summaryrefslogtreecommitdiff
path: root/vgui2/vgui_surfacelib/BitmapFont.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /vgui2/vgui_surfacelib/BitmapFont.cpp
downloadarchived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz
archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip
Diffstat (limited to 'vgui2/vgui_surfacelib/BitmapFont.cpp')
-rw-r--r--vgui2/vgui_surfacelib/BitmapFont.cpp324
1 files changed, 324 insertions, 0 deletions
diff --git a/vgui2/vgui_surfacelib/BitmapFont.cpp b/vgui2/vgui_surfacelib/BitmapFont.cpp
new file mode 100644
index 0000000..36d6be9
--- /dev/null
+++ b/vgui2/vgui_surfacelib/BitmapFont.cpp
@@ -0,0 +1,324 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: XBox Compiled Bitmap Fonts
+//
+//=============================================================================//
+
+// conversion from 'double' to 'float', possible loss of data
+#pragma warning( disable : 4244 )
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <malloc.h>
+#include "vgui_surfacelib/BitmapFont.h"
+#include "vgui_surfacelib/FontManager.h"
+#include <tier0/dbg.h>
+#include <vgui/ISurface.h>
+#include <tier0/mem.h>
+#include <utlbuffer.h>
+#include "filesystem.h"
+#include "materialsystem/itexture.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+struct BitmapFontTable_t
+{
+ BitmapFontTable_t()
+ {
+ m_szName = UTL_INVAL_SYMBOL;
+ m_pBitmapFont = NULL;
+ m_pBitmapGlyphs = NULL;
+ m_pTexture = NULL;
+ }
+
+ CUtlSymbol m_szName;
+ BitmapFont_t *m_pBitmapFont;
+ BitmapGlyph_t *m_pBitmapGlyphs;
+ ITexture *m_pTexture;
+};
+
+static CUtlVector< BitmapFontTable_t > g_BitmapFontTable( 1, 4 );
+
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+//-----------------------------------------------------------------------------
+CBitmapFont::CBitmapFont()
+{
+ m_scalex = 1.0f;
+ m_scaley = 1.0f;
+
+ m_bitmapFontHandle = g_BitmapFontTable.InvalidIndex();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Destructor
+//-----------------------------------------------------------------------------
+CBitmapFont::~CBitmapFont()
+{
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: creates the font. returns false if the font cannot be mounted.
+//-----------------------------------------------------------------------------
+bool CBitmapFont::Create( const char *pFontFilename, float scalex, float scaley, int flags )
+{
+ MEM_ALLOC_CREDIT();
+
+ if ( !pFontFilename || !pFontFilename[0] )
+ {
+ return false;
+ }
+
+ CUtlSymbol symbol;
+ char fontName[MAX_PATH];
+ Q_FileBase( pFontFilename, fontName, MAX_PATH );
+ Q_strlower( fontName );
+ symbol = fontName;
+
+ // find a match that can use same entries
+ BitmapFontTable_t *pFontTable = NULL;
+ for ( int i=0; i<g_BitmapFontTable.Count(); i++ )
+ {
+ if ( symbol == g_BitmapFontTable[i].m_szName )
+ {
+ m_bitmapFontHandle = i;
+ pFontTable = &g_BitmapFontTable[m_bitmapFontHandle];
+ break;
+ }
+ }
+
+ if ( !pFontTable )
+ {
+ void *pBuf = NULL;
+ int nLength;
+
+ nLength = FontManager().FileSystem()->ReadFileEx( pFontFilename, "GAME", &pBuf );
+ if ( nLength <= 0 || !pBuf )
+ {
+ // not found
+ return false;
+ }
+
+ if ( ((BitmapFont_t*)pBuf)->m_id != LittleLong( BITMAPFONT_ID ) || ((BitmapFont_t*)pBuf)->m_Version != LittleLong( BITMAPFONT_VERSION ) )
+ {
+ // bad version
+ return false;
+ }
+
+ if ( IsX360() )
+ {
+ CByteswap swap;
+ swap.ActivateByteSwapping( true );
+ swap.SwapFieldsToTargetEndian( (BitmapFont_t*)pBuf );
+ swap.SwapFieldsToTargetEndian( (BitmapGlyph_t*)((char*)pBuf + sizeof( BitmapFont_t )), ((BitmapFont_t*)pBuf)->m_NumGlyphs );
+ }
+
+ // create it
+ m_bitmapFontHandle = g_BitmapFontTable.AddToTail();
+ pFontTable = &g_BitmapFontTable[m_bitmapFontHandle];
+
+ pFontTable->m_szName = fontName;
+
+ pFontTable->m_pBitmapFont = new BitmapFont_t;
+ memcpy( pFontTable->m_pBitmapFont, pBuf, sizeof( BitmapFont_t ) );
+
+ pFontTable->m_pBitmapGlyphs = new BitmapGlyph_t[pFontTable->m_pBitmapFont->m_NumGlyphs];
+ memcpy( pFontTable->m_pBitmapGlyphs, (unsigned char*)pBuf + sizeof(BitmapFont_t), pFontTable->m_pBitmapFont->m_NumGlyphs*sizeof(BitmapGlyph_t) );
+
+ FontManager().FileSystem()->FreeOptimalReadBuffer( pBuf );
+
+ // load the art resources
+ char textureName[MAX_PATH];
+ Q_snprintf( textureName, MAX_PATH, "vgui/fonts/%s", fontName );
+ pFontTable->m_pTexture = FontManager().MaterialSystem()->FindTexture( textureName, TEXTURE_GROUP_VGUI );
+
+#if defined( _DEBUG ) && !defined( DX_TO_GL_ABSTRACTION )
+ if ( pFontTable->m_pBitmapFont->m_PageWidth != pFontTable->m_pTexture->GetActualWidth() ||
+ pFontTable->m_pBitmapFont->m_PageHeight != pFontTable->m_pTexture->GetActualHeight() )
+ {
+ // font is out of sync with its art
+ Assert( 0 );
+ return false;
+ }
+#endif
+ // the font texture lives forever, ensure it doesn't get purged
+ pFontTable->m_pTexture->IncrementReferenceCount();
+ }
+
+ // setup font properties
+ m_scalex = scalex;
+ m_scaley = scaley;
+
+ // flags are derived from the baked font
+ m_iFlags = vgui::ISurface::FONTFLAG_BITMAP;
+ int bitmapFlags = pFontTable->m_pBitmapFont->m_Flags;
+
+ if ( bitmapFlags & BF_ANTIALIASED )
+ {
+ m_iFlags |= vgui::ISurface::FONTFLAG_ANTIALIAS;
+ }
+
+ if ( bitmapFlags & BF_ITALIC )
+ {
+ m_iFlags |= vgui::ISurface::FONTFLAG_ITALIC;
+ }
+
+ if ( bitmapFlags & BF_BLURRED )
+ {
+ m_iFlags |= vgui::ISurface::FONTFLAG_GAUSSIANBLUR;
+ m_iBlur = 1;
+ }
+
+ if ( bitmapFlags & BF_SCANLINES )
+ {
+ m_iScanLines = 1;
+ }
+
+ if ( bitmapFlags & BF_OUTLINED )
+ {
+ m_iFlags |= vgui::ISurface::FONTFLAG_OUTLINE;
+ m_iOutlineSize = 1;
+ }
+
+ if ( bitmapFlags & BF_DROPSHADOW )
+ {
+ m_iFlags |= vgui::ISurface::FONTFLAG_DROPSHADOW;
+ m_iDropShadowOffset = 1;
+ }
+
+ if ( flags & vgui::ISurface::FONTFLAG_ADDITIVE )
+ {
+ m_bAdditive = true;
+ m_iFlags |= vgui::ISurface::FONTFLAG_ADDITIVE;
+ }
+
+ m_iMaxCharWidth = (float)pFontTable->m_pBitmapFont->m_MaxCharWidth * m_scalex;
+ m_iHeight = (float)pFontTable->m_pBitmapFont->m_MaxCharHeight * m_scaley;
+ m_iAscent = (float)pFontTable->m_pBitmapFont->m_Ascent * m_scaley;
+
+ // mark as valid
+ m_szName = fontName;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: returns true if the font is equivalent to that specified
+//-----------------------------------------------------------------------------
+bool CBitmapFont::IsEqualTo( const char *windowsFontName, float scalex, float scaley, int flags )
+{
+ char fontname[MAX_PATH];
+ Q_FileBase( windowsFontName, fontname, MAX_PATH );
+
+ if ( !Q_stricmp( fontname, m_szName.String() ) &&
+ m_scalex == scalex &&
+ m_scaley == scaley )
+ {
+ int commonFlags = m_iFlags & flags;
+ if ( commonFlags & vgui::ISurface::FONTFLAG_ADDITIVE )
+ {
+ // an exact match
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: sets the scale for a font
+//-----------------------------------------------------------------------------
+void CBitmapFont::SetScale( float sx, float sy )
+{
+ m_scalex = sx;
+ m_scaley = sy;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: gets the abc widths for a character
+//-----------------------------------------------------------------------------
+void CBitmapFont::GetCharABCWidths( int ch, int &a, int &b, int &c )
+{
+ Assert( IsValid() && ch >= 0 && ch <= 255 );
+
+ BitmapFontTable_t *pFont = &g_BitmapFontTable[m_bitmapFontHandle];
+
+ ch = pFont->m_pBitmapFont->m_TranslateTable[ch];
+ a = (float)pFont->m_pBitmapGlyphs[ch].a * m_scalex;
+ b = (float)pFont->m_pBitmapGlyphs[ch].b * m_scalex;
+ c = (float)pFont->m_pBitmapGlyphs[ch].c * m_scalex;
+}
+
+void CBitmapFont::GetCharRGBA( wchar_t ch, int rgbaWide, int rgbaTall, unsigned char *prgba )
+{
+ // CBitmapFont derives off CLinuxFont, etc. But you should never call GetCharRGBA on a bitmap font.
+ // If we let this fall into the CLinuxFont code, we'd have a difficult to track down bug - so crash
+ // hard here...
+ Error( "GetCharRGBA called on CBitmapFont." );
+}
+
+void CBitmapFont::GetKernedCharWidth( wchar_t ch, wchar_t chBefore, wchar_t chAfter, float &wide, float &abcA, float &abcC )
+{
+ Assert( IsValid() && ch >= 0 && ch <= 255 );
+
+ float abcB;
+ BitmapFontTable_t *pFont = &g_BitmapFontTable[m_bitmapFontHandle];
+
+ ch = pFont->m_pBitmapFont->m_TranslateTable[ch];
+ abcA = (float)pFont->m_pBitmapGlyphs[ch].a * m_scalex;
+ abcB = (float)pFont->m_pBitmapGlyphs[ch].b * m_scalex;
+ abcC = (float)pFont->m_pBitmapGlyphs[ch].c * m_scalex;
+
+ wide = ( abcA + abcB + abcC );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: gets the texcoords for a character
+//-----------------------------------------------------------------------------
+void CBitmapFont::GetCharCoords( int ch, float *left, float *top, float *right, float *bottom )
+{
+ Assert( IsValid() && ch >= 0 && ch <= 255 );
+
+ BitmapFontTable_t *pFont = &g_BitmapFontTable[m_bitmapFontHandle];
+
+ ch = pFont->m_pBitmapFont->m_TranslateTable[ch];
+ *left = (float)pFont->m_pBitmapGlyphs[ch].x/(float)pFont->m_pBitmapFont->m_PageWidth;
+ *top = (float)pFont->m_pBitmapGlyphs[ch].y/(float)pFont->m_pBitmapFont->m_PageHeight;
+ *right = (float)(pFont->m_pBitmapGlyphs[ch].x+pFont->m_pBitmapGlyphs[ch].w)/(float)pFont->m_pBitmapFont->m_PageWidth;
+ *bottom = (float)(pFont->m_pBitmapGlyphs[ch].y+pFont->m_pBitmapGlyphs[ch].h)/(float)pFont->m_pBitmapFont->m_PageHeight;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: gets the texture page
+//-----------------------------------------------------------------------------
+ITexture *CBitmapFont::GetTexturePage()
+{
+ Assert( IsValid() );
+
+ return g_BitmapFontTable[m_bitmapFontHandle].m_pTexture;
+}
+
+BEGIN_BYTESWAP_DATADESC( BitmapGlyph_t )
+ DEFINE_FIELD( x, FIELD_SHORT ),
+ DEFINE_FIELD( y, FIELD_SHORT ),
+ DEFINE_FIELD( w, FIELD_SHORT ),
+ DEFINE_FIELD( h, FIELD_SHORT ),
+ DEFINE_FIELD( a, FIELD_SHORT ),
+ DEFINE_FIELD( b, FIELD_SHORT ),
+ DEFINE_FIELD( c, FIELD_SHORT ),
+END_BYTESWAP_DATADESC()
+
+BEGIN_BYTESWAP_DATADESC( BitmapFont_t )
+ DEFINE_FIELD( m_id, FIELD_INTEGER ),
+ DEFINE_FIELD( m_Version, FIELD_INTEGER ),
+ DEFINE_FIELD( m_PageWidth, FIELD_SHORT ),
+ DEFINE_FIELD( m_PageHeight, FIELD_SHORT ),
+ DEFINE_FIELD( m_MaxCharWidth, FIELD_SHORT ),
+ DEFINE_FIELD( m_MaxCharHeight, FIELD_SHORT ),
+ DEFINE_FIELD( m_Flags, FIELD_SHORT ),
+ DEFINE_FIELD( m_Ascent, FIELD_SHORT ),
+ DEFINE_FIELD( m_NumGlyphs, FIELD_SHORT ),
+ DEFINE_ARRAY( m_TranslateTable, FIELD_CHARACTER, 256 ),
+END_BYTESWAP_DATADESC()