You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
885 lines
25 KiB
885 lines
25 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#define SUPPORT_CUSTOM_FONT_FORMAT
|
|
|
|
#ifdef SUPPORT_CUSTOM_FONT_FORMAT
|
|
#define _WIN32_WINNT 0x0500
|
|
#endif
|
|
|
|
#include "gameuischeme.h"
|
|
#include "gameuisystemsurface.h"
|
|
#include "vgui/ISystem.h"
|
|
#include "tier1/utlbuffer.h"
|
|
#include "gameuisystemmgr.h"
|
|
#include "tier1/KeyValues.h"
|
|
#include "vgui_surfacelib/fontmanager.h"
|
|
#include "vgui/isurface.h"
|
|
#include "vgui_controls/controls.h" // has system()
|
|
|
|
#if defined( _X360 )
|
|
#include "xbox/xbox_win32stubs.h"
|
|
#endif
|
|
#include "xbox/xboxstubs.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
|
|
#define FONT_ALIAS_NAME_LENGTH 64
|
|
|
|
CGameUISchemeManager g_GameUISchemeManager;
|
|
CGameUISchemeManager *g_pGameUISchemeManager = &g_GameUISchemeManager;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Helper function for getting the language the game ui should use.
|
|
//-----------------------------------------------------------------------------
|
|
static void HelperGetLanguage( char *pLanguageBuf, int bufSize )
|
|
{
|
|
bool bValid = false;
|
|
if ( IsPC() )
|
|
{
|
|
bValid = vgui::system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Language", pLanguageBuf, bufSize - 1 );
|
|
}
|
|
else
|
|
{
|
|
Q_strncpy( pLanguageBuf, XBX_GetLanguageString(), bufSize );
|
|
bValid = true;
|
|
}
|
|
|
|
if ( !bValid )
|
|
{
|
|
Q_strncpy( pLanguageBuf, "english", bufSize );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CGameUISchemeManager::CGameUISchemeManager()
|
|
{
|
|
// 0th element is null, since that would be an invalid handle
|
|
CGameUIScheme *nullScheme = new CGameUIScheme();
|
|
m_Schemes.AddToTail(nullScheme);
|
|
Assert( g_pGameUISystemSurface );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Destructor
|
|
//-----------------------------------------------------------------------------
|
|
CGameUISchemeManager::~CGameUISchemeManager()
|
|
{
|
|
int i;
|
|
for ( i = 0; i < m_Schemes.Count(); i++ )
|
|
{
|
|
delete m_Schemes[i];
|
|
m_Schemes[i] = NULL;
|
|
}
|
|
m_Schemes.RemoveAll();
|
|
|
|
Shutdown( false );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Reloads the schemes from the files
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISchemeManager::ReloadSchemes()
|
|
{
|
|
int count = m_Schemes.Count();
|
|
Shutdown( false );
|
|
|
|
// reload the scheme
|
|
for (int i = 1; i < count; i++)
|
|
{
|
|
LoadSchemeFromFile( m_Schemes[i]->GetFileName(), m_Schemes[i]->GetName() );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Reload the fonts in all schemes
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISchemeManager::ReloadFonts( int inScreenTall )
|
|
{
|
|
for (int i = 1; i < m_Schemes.Count(); i++)
|
|
{
|
|
m_Schemes[i]->ReloadFontGlyphs( inScreenTall );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISchemeManager::Shutdown( bool full )
|
|
{
|
|
// Full shutdown kills the null scheme
|
|
for( int i = full ? 0 : 1; i < m_Schemes.Count(); i++ )
|
|
{
|
|
m_Schemes[i]->Shutdown( full );
|
|
}
|
|
|
|
if ( full )
|
|
{
|
|
m_Schemes.RemoveAll();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Find an already loaded scheme
|
|
//-----------------------------------------------------------------------------
|
|
IGameUIScheme * CGameUISchemeManager::FindLoadedScheme( const char *pFilename )
|
|
{
|
|
// Find the scheme in the list of already loaded schemes
|
|
for ( int i = 1; i < m_Schemes.Count(); i++ )
|
|
{
|
|
char const *schemeFileName = m_Schemes[i]->GetFileName();
|
|
if ( !stricmp( schemeFileName, pFilename ) )
|
|
return m_Schemes[i];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// First scheme loaded becomes the default scheme,
|
|
// and all subsequent loaded scheme are derivatives of that
|
|
//-----------------------------------------------------------------------------
|
|
IGameUIScheme * CGameUISchemeManager::LoadSchemeFromFileEx( const char *pFilename, const char *tag )
|
|
{
|
|
// Look to see if we've already got this scheme...
|
|
CGameUIScheme * hScheme = ( CGameUIScheme * ) FindLoadedScheme( pFilename );
|
|
if ( hScheme )
|
|
{
|
|
if ( hScheme->IsActive() )
|
|
{
|
|
if ( IsPC() )
|
|
{
|
|
hScheme->ReloadFontGlyphs();
|
|
}
|
|
return hScheme;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hScheme = new CGameUIScheme();
|
|
m_Schemes.AddToTail( hScheme );
|
|
}
|
|
|
|
KeyValues *data;
|
|
data = new KeyValues("Scheme");
|
|
|
|
data->UsesEscapeSequences( true ); // VGUI uses this
|
|
|
|
// look first in skins directory
|
|
bool result = data->LoadFromFile( g_pFullFileSystem, pFilename, "SKIN" );
|
|
if (!result)
|
|
{
|
|
result = data->LoadFromFile( g_pFullFileSystem, pFilename, "GAME" );
|
|
if ( !result )
|
|
{
|
|
// look in any directory
|
|
result = data->LoadFromFile( g_pFullFileSystem, pFilename, NULL );
|
|
}
|
|
}
|
|
|
|
if (!result)
|
|
{
|
|
data->deleteThis();
|
|
return 0;
|
|
}
|
|
|
|
if ( IsPC() )
|
|
{
|
|
ConVarRef cl_hud_minmode( "cl_hud_minmode", true );
|
|
if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() )
|
|
{
|
|
data->ProcessResolutionKeys( "_minmode" );
|
|
}
|
|
}
|
|
|
|
hScheme->SetActive( true );
|
|
hScheme->LoadFromFile( pFilename, tag, data );
|
|
|
|
return hScheme;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: loads a scheme from disk
|
|
//-----------------------------------------------------------------------------
|
|
IGameUIScheme * CGameUISchemeManager::LoadSchemeFromFile( const char *fileName, const char *tag )
|
|
{
|
|
return LoadSchemeFromFileEx( fileName, tag );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: returns a handle to the default (first loaded) scheme
|
|
//-----------------------------------------------------------------------------
|
|
IGameUIScheme * CGameUISchemeManager::GetDefaultScheme()
|
|
{
|
|
if ( m_Schemes.Count() >= 2 )
|
|
return m_Schemes[1];
|
|
else if ( m_Schemes.Count() > 0 )
|
|
return m_Schemes[0];
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: returns a handle to the scheme identified by "tag"
|
|
//-----------------------------------------------------------------------------
|
|
IGameUIScheme * CGameUISchemeManager::GetScheme( const char *tag )
|
|
{
|
|
for ( int i=1; i<m_Schemes.Count(); i++ )
|
|
{
|
|
if ( !stricmp( tag, m_Schemes[i]->GetName() ) )
|
|
{
|
|
return m_Schemes[i];
|
|
}
|
|
}
|
|
return GetDefaultScheme(); // default scheme
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// gets the proportional coordinates for doing screen-size independant panel layouts
|
|
// use these for font, image and panel size scaling (they all use the pixel height of the display for scaling)
|
|
//-----------------------------------------------------------------------------
|
|
int CGameUISchemeManager::GetProportionalScaledValueEx( CGameUIScheme *pScheme, int normalizedValue, int screenTall )
|
|
{
|
|
return GetProportionalScaledValue( normalizedValue, screenTall );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: converts a value into proportional mode
|
|
//-----------------------------------------------------------------------------
|
|
int CGameUISchemeManager::GetProportionalScaledValue( int normalizedValue, int screenTall )
|
|
{
|
|
int tall;
|
|
if ( screenTall == -1 )
|
|
{
|
|
g_pGameUISystemMgrImpl->GetScreenHeightForFontLoading( tall );
|
|
}
|
|
else
|
|
{
|
|
tall = screenTall;
|
|
}
|
|
return GetProportionalScaledValue_( tall, normalizedValue );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
int CGameUISchemeManager::GetProportionalScaledValue_( int screenTall, int normalizedValue )
|
|
{
|
|
int baseWide, baseTall;
|
|
g_pGameUISystemSurface->GetProportionalBase( baseWide, baseTall );
|
|
double scale = (double)screenTall / (double)baseTall;
|
|
|
|
return (int)( normalizedValue * scale );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISchemeManager::SpewFonts( void )
|
|
{
|
|
for ( int i = 1; i < m_Schemes.Count(); i++ )
|
|
{
|
|
m_Schemes[i]->SpewFonts();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUISchemeManager::SetLanguage( const char *pLanguage )
|
|
{
|
|
g_pGameUISystemSurface->SetLanguage( pLanguage );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
const char *CGameUISchemeManager::GetLanguage()
|
|
{
|
|
return g_pGameUISystemSurface->GetLanguage();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CGameUIScheme::CGameUIScheme()
|
|
{
|
|
m_pFileName = "";
|
|
m_pTag = "";
|
|
m_pData = NULL;
|
|
SetActive( false );
|
|
}
|
|
|
|
CGameUIScheme::~CGameUIScheme()
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: loads a scheme from from disk into memory
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::LoadFromFile( const char *pFilename, const char *inTag, KeyValues *inKeys )
|
|
{
|
|
COM_TimestampedLog( "CScheme::LoadFromFile( %s )", pFilename );
|
|
|
|
m_pFileName = pFilename;
|
|
m_pData = inKeys;
|
|
|
|
// override the scheme name with the tag name
|
|
KeyValues *name = m_pData->FindKey( "Name", true );
|
|
name->SetString("Name", inTag);
|
|
|
|
if ( inTag )
|
|
{
|
|
m_pTag = inTag;
|
|
}
|
|
else
|
|
{
|
|
Error( "You need to name the scheme (%s)!", m_pFileName.Get() );
|
|
m_pTag = "default";
|
|
}
|
|
|
|
LoadFonts();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Set the range of character values this font can be used on
|
|
//-----------------------------------------------------------------------------
|
|
bool CGameUIScheme::GetFontRange( const char *fontname, int &nMin, int &nMax )
|
|
{
|
|
for ( int i = 0 ; i < m_FontRanges.Count() ; i++ )
|
|
{
|
|
if ( Q_stricmp( m_FontRanges[i]._fontName.String(), fontname ) == 0 )
|
|
{
|
|
nMin = m_FontRanges[i]._min;
|
|
nMax = m_FontRanges[i]._max;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Get the range of character values this font can be used on
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::SetFontRange( const char *fontname, int nMin, int nMax )
|
|
{
|
|
for ( int i = 0 ; i < m_FontRanges.Count() ; i++ )
|
|
{
|
|
if ( Q_stricmp( m_FontRanges[i]._fontName.String(), fontname ) == 0 )
|
|
{
|
|
m_FontRanges[i]._min = nMin;
|
|
m_FontRanges[i]._max = nMax;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// not already in our list
|
|
int iIndex = m_FontRanges.AddToTail();
|
|
|
|
m_FontRanges[iIndex]._fontName = fontname;
|
|
m_FontRanges[iIndex]._min = nMin;
|
|
m_FontRanges[iIndex]._max = nMax;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: adds all the font specifications to the surface
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::LoadFonts()
|
|
{
|
|
// get our language
|
|
const char *pLanguage = g_GameUISchemeManager.GetLanguage();
|
|
|
|
|
|
// add our custom fonts
|
|
for ( KeyValues *kv = m_pData->FindKey("CustomFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey() )
|
|
{
|
|
const char *fontFile = kv->GetString();
|
|
if (fontFile && *fontFile)
|
|
{
|
|
g_pGameUISystemSurface->AddCustomFontFile( fontFile );
|
|
}
|
|
else
|
|
{
|
|
// we have a block to read
|
|
int nRangeMin = 0, nRangeMax = 0;
|
|
const char *pszName = NULL;
|
|
bool bUseRange = false;
|
|
|
|
for ( KeyValues *pData = kv->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
|
|
{
|
|
const char *pszKey = pData->GetName();
|
|
if ( !Q_stricmp( pszKey, "font" ) )
|
|
{
|
|
fontFile = pData->GetString();
|
|
}
|
|
else if ( !Q_stricmp( pszKey, "name" ) )
|
|
{
|
|
pszName = pData->GetString();
|
|
}
|
|
else
|
|
{
|
|
// we must have a language
|
|
if ( Q_stricmp( pLanguage, pszKey ) == 0 ) // matches the language we're running?
|
|
{
|
|
// get the range
|
|
KeyValues *pRange = pData->FindKey( "range" );
|
|
if ( pRange )
|
|
{
|
|
bUseRange = true;
|
|
sscanf( pRange->GetString(), "%x %x", &nRangeMin, &nRangeMax );
|
|
|
|
if ( nRangeMin > nRangeMax )
|
|
{
|
|
int nTemp = nRangeMin;
|
|
nRangeMin = nRangeMax;
|
|
nRangeMax = nTemp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( fontFile && *fontFile )
|
|
{
|
|
g_pGameUISystemSurface->AddCustomFontFile( fontFile );
|
|
|
|
if ( bUseRange )
|
|
{
|
|
SetFontRange( pszName, nRangeMin, nRangeMax );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// add bitmap fonts
|
|
for ( KeyValues *kv = m_pData->FindKey("BitmapFontFiles", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey() )
|
|
{
|
|
const char *fontFile = kv->GetString();
|
|
if (fontFile && *fontFile)
|
|
{
|
|
bool bSuccess = g_pGameUISystemSurface->AddBitmapFontFile( fontFile );
|
|
if ( bSuccess )
|
|
{
|
|
// refer to the font by a user specified symbol
|
|
g_pGameUISystemSurface->SetBitmapFontName( kv->GetName(), fontFile );
|
|
}
|
|
}
|
|
}
|
|
|
|
// create the fonts
|
|
for (KeyValues *kv = m_pData->FindKey("Fonts", true)->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey())
|
|
{
|
|
for ( int i = 0; i < 2; i++ )
|
|
{
|
|
// create the base font
|
|
bool proportionalFont = i ? true : false;
|
|
const char *fontName = GetMungedFontName( kv->GetName(), m_pTag.Get(), proportionalFont ); // first time it adds a normal font, and then a proportional one
|
|
FontHandle_t font = g_pGameUISystemSurface->CreateFont();
|
|
int j = m_FontAliases.AddToTail();
|
|
m_FontAliases[j]._fontName = fontName;
|
|
m_FontAliases[j]._trueFontName = kv->GetName();
|
|
m_FontAliases[j]._font = font;
|
|
m_FontAliases[j].m_bProportional = proportionalFont;
|
|
}
|
|
}
|
|
|
|
// load in the font glyphs
|
|
ReloadFontGlyphs();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Reloads all scheme fonts
|
|
// Supply a language if you don't want to use the one in the registry.
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::ReloadFontGlyphs( int inScreenTall )
|
|
{
|
|
int screenTall;
|
|
// get our current resolution
|
|
if ( inScreenTall == -1 )
|
|
{
|
|
//int screenWide;
|
|
g_pGameUISystemMgrImpl->GetScreenHeightForFontLoading( screenTall );
|
|
}
|
|
else // this will make fonts be the correct size in the editor, where the stage size is the screen size.
|
|
{
|
|
screenTall = inScreenTall;
|
|
}
|
|
|
|
// check our language; some have minimum sizes
|
|
int minimumFontHeight = GetMinimumFontHeightForCurrentLanguage( g_GameUISchemeManager.GetLanguage() );
|
|
|
|
// add the data to all the fonts
|
|
KeyValues *fonts = m_pData->FindKey( "Fonts", true );
|
|
for (int i = 0; i < m_FontAliases.Count(); i++)
|
|
{
|
|
KeyValues *kv = fonts->FindKey( m_FontAliases[i]._trueFontName.String(), true );
|
|
|
|
// walk through creating adding the first matching glyph set to the font
|
|
for ( KeyValues *fontdata = kv->GetFirstSubKey(); fontdata != NULL; fontdata = fontdata->GetNextKey() )
|
|
{
|
|
|
|
// skip over fonts not meant for this resolution
|
|
int fontYResMin = 0, fontYResMax = 0;
|
|
sscanf( fontdata->GetString( "yres", "" ), "%d %d", &fontYResMin, &fontYResMax );
|
|
if ( fontYResMin )
|
|
{
|
|
if ( !fontYResMax )
|
|
{
|
|
fontYResMax = fontYResMin;
|
|
}
|
|
// check the range
|
|
if ( screenTall < fontYResMin || screenTall > fontYResMax )
|
|
continue;
|
|
}
|
|
|
|
int flags = 0;
|
|
if (fontdata->GetInt( "italic" ))
|
|
{
|
|
flags |= FONTFLAG_ITALIC;
|
|
}
|
|
if (fontdata->GetInt( "underline" ))
|
|
{
|
|
flags |= FONTFLAG_UNDERLINE;
|
|
}
|
|
if (fontdata->GetInt( "strikeout" ))
|
|
{
|
|
flags |= FONTFLAG_STRIKEOUT;
|
|
}
|
|
if (fontdata->GetInt( "symbol" ))
|
|
{
|
|
flags |= FONTFLAG_SYMBOL;
|
|
}
|
|
if (fontdata->GetInt( "antialias" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_ANTIALIASED_FONTS ) )
|
|
{
|
|
flags |= FONTFLAG_ANTIALIAS;
|
|
}
|
|
if (fontdata->GetInt( "dropshadow" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_DROPSHADOW_FONTS ) )
|
|
{
|
|
flags |= FONTFLAG_DROPSHADOW;
|
|
}
|
|
if (fontdata->GetInt( "outline" ) && g_pGameUISystemSurface->SupportsFontFeature( FONT_FEATURE_OUTLINE_FONTS ) )
|
|
{
|
|
flags |= FONTFLAG_OUTLINE;
|
|
}
|
|
if (fontdata->GetInt( "custom" ))
|
|
{
|
|
flags |= FONTFLAG_CUSTOM;
|
|
}
|
|
if (fontdata->GetInt( "bitmap" ))
|
|
{
|
|
flags |= FONTFLAG_BITMAP;
|
|
}
|
|
if (fontdata->GetInt( "rotary" ))
|
|
{
|
|
flags |= FONTFLAG_ROTARY;
|
|
}
|
|
if (fontdata->GetInt( "additive" ))
|
|
{
|
|
flags |= FONTFLAG_ADDITIVE;
|
|
}
|
|
|
|
int fontTall = fontdata->GetInt( "tall" );
|
|
int blur = fontdata->GetInt( "blur" );
|
|
int scanlines = fontdata->GetInt( "scanlines" );
|
|
float scalex = fontdata->GetFloat( "scalex", 1.0f );
|
|
float scaley = fontdata->GetFloat( "scaley", 1.0f );
|
|
|
|
// only grow this font if it doesn't have a resolution filter specified
|
|
if ( ( !fontYResMin && !fontYResMax ) && m_FontAliases[i].m_bProportional )
|
|
{
|
|
fontTall = g_GameUISchemeManager.GetProportionalScaledValueEx( this, fontTall, screenTall );
|
|
blur = g_GameUISchemeManager.GetProportionalScaledValueEx( this, blur );
|
|
scanlines = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scanlines );
|
|
scalex = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scalex * 10000.0f ) * 0.0001f;
|
|
scaley = g_GameUISchemeManager.GetProportionalScaledValueEx( this, scaley * 10000.0f ) * 0.0001f;
|
|
}
|
|
|
|
// clip the font size so that fonts can't be too big
|
|
if ( fontTall > 127 )
|
|
{
|
|
fontTall = 127;
|
|
}
|
|
|
|
// check our minimum font height
|
|
if ( fontTall < minimumFontHeight )
|
|
{
|
|
fontTall = minimumFontHeight;
|
|
}
|
|
|
|
if ( flags & FONTFLAG_BITMAP )
|
|
{
|
|
// add the new set
|
|
g_pGameUISystemSurface->SetBitmapFontGlyphSet(
|
|
m_FontAliases[i]._font,
|
|
g_pGameUISystemSurface->GetBitmapFontName( fontdata->GetString( "name" ) ),
|
|
scalex,
|
|
scaley,
|
|
flags);
|
|
}
|
|
else
|
|
{
|
|
int nRangeMin, nRangeMax;
|
|
if ( GetFontRange( fontdata->GetString( "name" ), nRangeMin, nRangeMax ) )
|
|
{
|
|
// add the new set
|
|
g_pGameUISystemSurface->SetFontGlyphSet(
|
|
m_FontAliases[i]._font, fontdata->GetString( "name" ),
|
|
fontTall, fontdata->GetInt( "weight" ), blur, scanlines, flags, nRangeMin, nRangeMax);
|
|
}
|
|
else
|
|
{
|
|
// add the new set
|
|
g_pGameUISystemSurface->SetFontGlyphSet( m_FontAliases[i]._font, fontdata->GetString( "name" ),
|
|
fontTall, fontdata->GetInt( "weight" ), blur, scanlines, flags);
|
|
}
|
|
}
|
|
|
|
// don't add any more
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::SpewFonts( void )
|
|
{
|
|
Msg( "Game UI Scheme: %s (%s)\n", GetName(), GetFileName() );
|
|
for ( int i = 0; i < m_FontAliases.Count(); i++ )
|
|
{
|
|
Msg( " %2d: HFont:0x%8.8x, %s, %s, font:%s, tall:%d\n",
|
|
i,
|
|
m_FontAliases[i]._font,
|
|
m_FontAliases[i]._trueFontName.String(),
|
|
m_FontAliases[i]._fontName.String(),
|
|
g_pGameUISystemSurface->GetFontName( m_FontAliases[i]._font ),
|
|
g_pGameUISystemSurface->GetFontTall( m_FontAliases[i]._font ) );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Kills the scheme
|
|
//-----------------------------------------------------------------------------
|
|
void CGameUIScheme::Shutdown( bool full )
|
|
{
|
|
SetActive( false );
|
|
|
|
m_FontRanges.RemoveAll();
|
|
|
|
if (m_pData)
|
|
{
|
|
m_pData->deleteThis();
|
|
m_pData = NULL;
|
|
}
|
|
|
|
if ( full )
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Finds a font in the alias list
|
|
//-----------------------------------------------------------------------------
|
|
FontHandle_t CGameUIScheme::FindFontInAliasList( const char *fontName )
|
|
{
|
|
// FIXME: Slow!!!
|
|
for (int i = m_FontAliases.Count(); --i >= 0; )
|
|
{
|
|
if ( !strnicmp( fontName, m_FontAliases[i]._fontName.String(), FONT_ALIAS_NAME_LENGTH ) )
|
|
return m_FontAliases[i]._font;
|
|
}
|
|
|
|
// No dice
|
|
return 0;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input : font -
|
|
// Output : char const
|
|
//-----------------------------------------------------------------------------
|
|
char const *CGameUIScheme::GetFontName( const FontHandle_t &font )
|
|
{
|
|
for (int i = m_FontAliases.Count(); --i >= 0; )
|
|
{
|
|
FontHandle_t fnt = ( FontHandle_t )m_FontAliases[i]._font;
|
|
if ( fnt == font )
|
|
return m_FontAliases[i]._trueFontName.String();
|
|
}
|
|
|
|
return "<Unknown font>";
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// material Setting methods
|
|
//-----------------------------------------------------------------------------
|
|
FontHandle_t CGameUIScheme::GetFont( const char *fontName, bool proportional )
|
|
{
|
|
// First look in the list of aliases...
|
|
return FindFontInAliasList( GetMungedFontName( fontName, m_pTag.Get(), proportional ) );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Return the vgui name of the font that is the same truefont name and one size up.
|
|
// bUp is if true you want the next size up or the next size down.
|
|
//-----------------------------------------------------------------------------
|
|
FontHandle_t CGameUIScheme::GetFontNextSize( bool bUp, const char *fontName, bool proportional )
|
|
{
|
|
FontHandle_t currentFontHandle = GetFont( fontName, proportional );
|
|
// Current font name wasn't found.
|
|
if ( currentFontHandle == 0 )
|
|
{
|
|
return currentFontHandle;
|
|
}
|
|
|
|
int currentFontTall = g_pGameUISystemSurface->GetFontTall( currentFontHandle );
|
|
const char* pCurrentFontName = g_pGameUISystemSurface->GetFontName( currentFontHandle );
|
|
|
|
// Now find the closest font with this name that is the smallest size up
|
|
int sizeDifference = INT_MAX;
|
|
FontHandle_t closestFontHandle = 0;
|
|
for (int i = m_FontAliases.Count(); --i > 0; )
|
|
{
|
|
if ( proportional != m_FontAliases[i].m_bProportional )
|
|
continue;
|
|
|
|
FontHandle_t testFontHandle = m_FontAliases[i]._font;
|
|
const char* pTestFontName = g_pGameUISystemSurface->GetFontName( testFontHandle );
|
|
if ( currentFontHandle != testFontHandle )
|
|
{
|
|
if ( !Q_stricmp( pCurrentFontName, pTestFontName ) ) // font name is the same.
|
|
{
|
|
int thisFontTall = g_pGameUISystemSurface->GetFontTall( testFontHandle );
|
|
|
|
int diff;
|
|
if ( bUp ) // get next size up
|
|
{
|
|
diff = thisFontTall - currentFontTall;
|
|
}
|
|
else // get next size down.
|
|
{
|
|
diff = currentFontTall - thisFontTall;
|
|
}
|
|
|
|
if ( diff > 0 && diff < sizeDifference )
|
|
{
|
|
sizeDifference = diff;
|
|
closestFontHandle = testFontHandle;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( closestFontHandle != 0 )
|
|
{
|
|
return closestFontHandle;
|
|
}
|
|
else
|
|
{
|
|
return currentFontHandle;
|
|
}
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: returns a char string of the munged name this font is stored as in the font manager
|
|
//-----------------------------------------------------------------------------
|
|
const char *CGameUIScheme::GetMungedFontName( const char *fontName, const char *scheme, bool proportional )
|
|
{
|
|
static char mungeBuffer[ 64 ];
|
|
if ( scheme )
|
|
{
|
|
Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s%s-%s", fontName, scheme, proportional ? "p" : "no" );
|
|
}
|
|
else
|
|
{
|
|
Q_snprintf( mungeBuffer, sizeof( mungeBuffer ), "%s-%s", fontName, proportional ? "p" : "no" ); // we don't want the "(null)" snprintf appends
|
|
}
|
|
return mungeBuffer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: gets the minimum font height for the current language
|
|
//-----------------------------------------------------------------------------
|
|
int CGameUIScheme::GetMinimumFontHeightForCurrentLanguage( const char *pLanguage )
|
|
{
|
|
char language[64];
|
|
bool bValid;
|
|
if ( IsPC() )
|
|
{
|
|
if ( pLanguage )
|
|
{
|
|
Q_strncpy( language, pLanguage, sizeof(language)-1 );
|
|
bValid = true;
|
|
}
|
|
else
|
|
{
|
|
bValid = vgui::system()->GetRegistryString( "HKEY_CURRENT_USER\\Software\\Valve\\Steam\\Language", language, sizeof(language)-1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Q_strncpy( language, XBX_GetLanguageString(), sizeof( language ) );
|
|
bValid = true;
|
|
}
|
|
|
|
if ( bValid )
|
|
{
|
|
if (!stricmp(language, "korean")
|
|
|| !stricmp(language, "koreana")
|
|
|| !stricmp(language, "tchinese")
|
|
|| !stricmp(language, "schinese")
|
|
|| !stricmp(language, "japanese"))
|
|
{
|
|
// the bitmap-based fonts for these languages simply don't work with a pt. size of less than 9 (13 pixels)
|
|
return 13;
|
|
}
|
|
|
|
if ( !stricmp(language, "thai" ) )
|
|
{
|
|
// thai has problems below 18 pts
|
|
return 18;
|
|
}
|
|
}
|
|
|
|
// no special minimum height required
|
|
return 0;
|
|
}
|
|
|
|
void CGameUIScheme::SetActive( bool bActive )
|
|
{
|
|
m_bActive = bActive;
|
|
}
|
|
|
|
bool CGameUIScheme::IsActive() const
|
|
{
|
|
return m_bActive;
|
|
}
|