etqw-sdk/source/game/gamesys/DeviceContextHelper.h

156 lines
3.7 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __DEVICECONTEXTHELPER_H__
#define __DEVICECONTEXTHELPER_H__
class sdTextDimensionHelper {
public:
sdTextDimensionHelper( void );
~sdTextDimensionHelper( void );
void Init( const wchar_t* text, const int textLength, const sdBounds2D& rect, unsigned int flags, const qhandle_t font, const int pointSize, idList< int >* lineBreaks = NULL );
int GetAdvance( const int index ) const;
float GetWidth( const int startIndex, const int endIndex ) const;
int GetTextWidth() const { return width; }
int GetTextHeight() const { return height; }
int GetLineHeight() const { return lineHeight; }
int ToVirtualScreenSize( const int size ) const;
float ToVirtualScreenSizeFloat( const int size ) const;
private:
static const int BASE_BUFFER = 256;
float scale;
int width;
int height;
int lineHeight;
int* advances;
int advancesBase[ BASE_BUFFER ];
int textLength;
};
/*
============
sdTextDimensionHelper::sdTextDimensionHelper
============
*/
ID_INLINE sdTextDimensionHelper::sdTextDimensionHelper( void ) :
scale( 1.0f ),
width( 0 ),
height( 0 ),
lineHeight( 0 ),
advances( &advancesBase[ 0 ] ),
textLength( 0 ) {
}
/*
============
sdTextDimensionHelper::~sdTextDimensionHelper
============
*/
ID_INLINE sdTextDimensionHelper::~sdTextDimensionHelper( void ) {
if( advances != &advancesBase[ 0 ] ) {
Mem_Free( advances );
}
}
/*
============
sdTextDimensionHelper::Init
============
*/
ID_INLINE void sdTextDimensionHelper::Init( const wchar_t* text, const int textLength, const sdBounds2D& rect, unsigned int flags, const qhandle_t font, const int pointSize, idList< int >* lineBreaks ) {
if( lineBreaks != NULL ) {
lineBreaks->SetNum( 0, false );
}
if ( textLength == 0 ) {
memset( advances, 0, this->textLength * sizeof( int ) );
this->textLength = 0;
return;
}
if( advances != NULL && textLength > this->textLength && advances != &advancesBase[ 0 ] ) {
Mem_Free( advances );
advances = &advancesBase[ 0 ];
}
if( textLength > BASE_BUFFER ) {
advances = static_cast< int* >( Mem_Alloc( textLength * sizeof( int ) ) );
}
deviceContext->GetTextDimensions( text, rect, flags, font, pointSize, width, height, &scale, &advances, lineBreaks );
int numLines = ( lineBreaks != NULL ) ? lineBreaks->Num() : 0;
// a trailing empty line isn't included in the total drawn height
if( text[ textLength - 1 ] == L'\n' ) {
numLines--;
}
lineHeight = idMath::Ftoi( idMath::Ceil( static_cast< float >( height ) / ( numLines + 1 ) ) );
this->textLength = textLength;
}
/*
============
sdTextDimensionHelper::GetAdvance
============
*/
ID_INLINE int sdTextDimensionHelper::GetAdvance( const int index ) const {
if ( advances == NULL ) {
return 0;
}
return advances[index];
}
/*
============
sdTextDimensionHelper::GetWidth
============
*/
ID_INLINE float sdTextDimensionHelper::GetWidth( const int startIndex, const int endIndex ) const {
if ( advances == NULL || textLength == 0 ) {
return 0.0f;
}
int width = 0;
for ( int i = startIndex; i <= endIndex && i < textLength ; i++ ) {
width += advances[i];
}
return ToVirtualScreenSize( width );
}
/*
============
sdTextDimensionHelper::ToVirtualScreenSize
============
*/
ID_INLINE int sdTextDimensionHelper::ToVirtualScreenSize( const int size ) const {
return idMath::Ftoi( idMath::Ceil( ( size >> 6 ) / scale ) );
}
/*
============
sdTextDimensionHelper::ToVirtualScreenSizeFloat
============
*/
ID_INLINE float sdTextDimensionHelper::ToVirtualScreenSizeFloat( const int size ) const {
return ( size >> 6 ) / scale;
}
#endif /* !__DEVICECONTEXTHELPER_H__ */