Team Fortress 2 Source Code as on 22/4/2020
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.

787 lines
22 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include <locale.h>
  7. #include "vgui_surfacelib/BitmapFont.h"
  8. #include "vgui_surfacelib/FontManager.h"
  9. #include <vgui/ISurface.h>
  10. #include <tier0/dbg.h>
  11. // memdbgon must be the last include file in a .cpp file!!!
  12. #include <tier0/memdbgon.h>
  13. static CFontManager s_FontManager;
  14. #ifdef WIN32
  15. extern bool s_bSupportsUnicode;
  16. #endif
  17. #if !defined( _X360 )
  18. #define MAX_INITIAL_FONTS 100
  19. #else
  20. #define MAX_INITIAL_FONTS 1
  21. #endif
  22. //-----------------------------------------------------------------------------
  23. // Purpose: singleton accessor
  24. //-----------------------------------------------------------------------------
  25. CFontManager &FontManager()
  26. {
  27. return s_FontManager;
  28. }
  29. //-----------------------------------------------------------------------------
  30. // Purpose: Constructor
  31. //-----------------------------------------------------------------------------
  32. CFontManager::CFontManager()
  33. {
  34. // add a single empty font, to act as an invalid font handle 0
  35. m_FontAmalgams.EnsureCapacity( MAX_INITIAL_FONTS );
  36. m_FontAmalgams.AddToTail();
  37. m_Win32Fonts.EnsureCapacity( MAX_INITIAL_FONTS );
  38. #ifdef LINUX
  39. FT_Error error = FT_Init_FreeType( &library );
  40. if ( error )
  41. Error( "Unable to initalize freetype library, is it installed?" );
  42. m_pFontDataHelper = NULL;
  43. #endif
  44. // setup our text locale
  45. setlocale( LC_CTYPE, "" );
  46. setlocale( LC_TIME, "" );
  47. setlocale( LC_COLLATE, "" );
  48. setlocale( LC_MONETARY, "" );
  49. m_pFileSystem = NULL;
  50. m_pMaterialSystem = NULL;
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Purpose: language setting for font fallbacks
  54. //-----------------------------------------------------------------------------
  55. void CFontManager::SetLanguage(const char *language)
  56. {
  57. Q_strncpy(m_szLanguage, language, sizeof(m_szLanguage));
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose: Destructor
  61. //-----------------------------------------------------------------------------
  62. CFontManager::~CFontManager()
  63. {
  64. ClearAllFonts();
  65. m_FontAmalgams.RemoveAll();
  66. #ifdef LINUX
  67. FT_Done_FreeType( library );
  68. #endif
  69. }
  70. //-----------------------------------------------------------------------------
  71. // Purpose: frees the fonts
  72. //-----------------------------------------------------------------------------
  73. void CFontManager::ClearAllFonts()
  74. {
  75. // free the fonts
  76. for (int i = 0; i < m_Win32Fonts.Count(); i++)
  77. {
  78. delete m_Win32Fonts[i];
  79. }
  80. m_Win32Fonts.RemoveAll();
  81. for (int i = 0; i < m_FontAmalgams.Count(); i++)
  82. {
  83. m_FontAmalgams[i].RemoveAll();
  84. }
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose:
  88. //-----------------------------------------------------------------------------
  89. vgui::HFont CFontManager::CreateFont()
  90. {
  91. int i = m_FontAmalgams.AddToTail();
  92. return i;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose: Sets the valid glyph ranges for a font created by CreateFont()
  96. //-----------------------------------------------------------------------------
  97. bool CFontManager::SetFontGlyphSet(HFont font, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags)
  98. {
  99. return SetFontGlyphSet( font, windowsFontName, tall, weight, blur, scanlines, flags, 0, 0);
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose: Sets the valid glyph ranges for a font created by CreateFont()
  103. //-----------------------------------------------------------------------------
  104. bool CFontManager::SetFontGlyphSet(HFont font, const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags, int nRangeMin, int nRangeMax)
  105. {
  106. // ignore all but the first font added
  107. // need to rev vgui versions and change the name of this function
  108. if ( m_FontAmalgams[font].GetCount() > 0 )
  109. {
  110. // clear any existing fonts
  111. m_FontAmalgams[font].RemoveAll();
  112. }
  113. bool bForceSingleFontForXbox = false;
  114. if ( IsX360() )
  115. {
  116. // discovered xbox only allows glyphs from these languages from the foreign fallback font
  117. // prefer to have the entire range of chars from the font so UI doesn't suffer from glyph disparity
  118. if ( !V_stricmp( windowsFontName, "toolbox" ) )
  119. {
  120. // only the toolbox font is allowed to pass
  121. }
  122. else
  123. {
  124. if ( !V_stricmp( m_szLanguage, "polish" ) ||
  125. !V_stricmp( m_szLanguage, "russian" ) ||
  126. !V_stricmp( m_szLanguage, "japanese" ) ||
  127. !V_stricmp( m_szLanguage, "korean" ) ||
  128. !V_stricmp( m_szLanguage, "portuguese" ) ||
  129. !V_stricmp( m_szLanguage, "schinese" ) ||
  130. !V_stricmp( m_szLanguage, "tchinese" ) )
  131. {
  132. windowsFontName = GetForeignFallbackFontName();
  133. bForceSingleFontForXbox = true;
  134. }
  135. }
  136. }
  137. font_t *winFont = CreateOrFindWin32Font( windowsFontName, tall, weight, blur, scanlines, flags );
  138. // cycle until valid english/extended font support has been created
  139. do
  140. {
  141. // add to the amalgam
  142. if ( bForceSingleFontForXbox || IsFontForeignLanguageCapable( windowsFontName ) )
  143. {
  144. if ( winFont )
  145. {
  146. // font supports the full range of characters
  147. m_FontAmalgams[font].AddFont( winFont, 0x0000, 0xFFFF );
  148. return true;
  149. }
  150. }
  151. else
  152. {
  153. // font cannot provide glyphs and just supports the normal range
  154. // redirect to a font that can supply glyps
  155. const char *localizedFontName = GetForeignFallbackFontName();
  156. if ( winFont && !stricmp( localizedFontName, windowsFontName ) )
  157. {
  158. // it's the same font and can support the full range
  159. m_FontAmalgams[font].AddFont( winFont, 0x0000, 0xFFFF );
  160. return true;
  161. }
  162. // create the extended support font
  163. font_t *pExtendedFont = CreateOrFindWin32Font( localizedFontName, tall, weight, blur, scanlines, flags );
  164. if ( winFont && pExtendedFont )
  165. {
  166. // use the normal font for english characters, and the extended font for the rest
  167. int nMin = 0x0000, nMax = 0x00FF;
  168. // did we specify a range?
  169. if ( nRangeMin > 0 || nRangeMax > 0 )
  170. {
  171. nMin = nRangeMin;
  172. nMax = nRangeMax;
  173. // make sure they're in the correct order
  174. if ( nMin > nMax )
  175. {
  176. int nTemp = nMin;
  177. nMin = nMax;
  178. nMax = nTemp;
  179. }
  180. }
  181. if ( nMin > 0 )
  182. {
  183. m_FontAmalgams[font].AddFont( pExtendedFont, 0x0000, nMin - 1 );
  184. }
  185. m_FontAmalgams[font].AddFont( winFont, nMin, nMax );
  186. if ( nMax < 0xFFFF )
  187. {
  188. m_FontAmalgams[font].AddFont( pExtendedFont, nMax + 1, 0xFFFF );
  189. }
  190. return true;
  191. }
  192. else if ( pExtendedFont )
  193. {
  194. // the normal font failed to create
  195. // just use the extended font for the full range
  196. m_FontAmalgams[font].AddFont( pExtendedFont, 0x0000, 0xFFFF );
  197. return true;
  198. }
  199. }
  200. // no valid font has been created, so fallback to a different font and try again
  201. }
  202. while ( NULL != ( windowsFontName = GetFallbackFontName( windowsFontName ) ) );
  203. // nothing successfully created
  204. return false;
  205. }
  206. //-----------------------------------------------------------------------------
  207. // Purpose: adds glyphs to a font created by CreateFont()
  208. //-----------------------------------------------------------------------------
  209. bool CFontManager::SetBitmapFontGlyphSet(HFont font, const char *windowsFontName, float scalex, float scaley, int flags)
  210. {
  211. if ( m_FontAmalgams[font].GetCount() > 0 )
  212. {
  213. // clear any existing fonts
  214. m_FontAmalgams[font].RemoveAll();
  215. }
  216. CBitmapFont *winFont = CreateOrFindBitmapFont( windowsFontName, scalex, scaley, flags );
  217. if ( winFont )
  218. {
  219. // bitmap fonts are only 0-255
  220. m_FontAmalgams[font].AddFont( winFont, 0x0000, 0x00FF );
  221. return true;
  222. }
  223. // nothing successfully created
  224. return false;
  225. }
  226. //-----------------------------------------------------------------------------
  227. // Purpose: Creates a new win32 font, or reuses one if possible
  228. //-----------------------------------------------------------------------------
  229. font_t *CFontManager::CreateOrFindWin32Font(const char *windowsFontName, int tall, int weight, int blur, int scanlines, int flags)
  230. {
  231. // see if we already have the win32 font
  232. font_t *winFont = NULL;
  233. int i;
  234. for (i = 0; i < m_Win32Fonts.Count(); i++)
  235. {
  236. if (m_Win32Fonts[i]->IsEqualTo(windowsFontName, tall, weight, blur, scanlines, flags))
  237. {
  238. winFont = m_Win32Fonts[i];
  239. break;
  240. }
  241. }
  242. // create the new win32font if we didn't find it
  243. if (!winFont)
  244. {
  245. MEM_ALLOC_CREDIT();
  246. i = m_Win32Fonts.AddToTail();
  247. m_Win32Fonts[i] = NULL;
  248. #ifdef LINUX
  249. int memSize = 0;
  250. void *pchFontData = m_pFontDataHelper( windowsFontName, memSize, NULL );
  251. if( !pchFontData )
  252. {
  253. // If we didn't find the font data in the font cache, then get the font filename...
  254. char *filename = CLinuxFont::GetFontFileName( windowsFontName, flags );
  255. if( filename )
  256. {
  257. // ... and try to add it to the font cache.
  258. pchFontData = m_pFontDataHelper( windowsFontName, memSize, filename );
  259. free( filename );
  260. }
  261. }
  262. if ( pchFontData )
  263. {
  264. m_Win32Fonts[i] = new font_t();
  265. if (m_Win32Fonts[i]->CreateFromMemory( windowsFontName, pchFontData, memSize, tall, weight, blur, scanlines, flags))
  266. {
  267. // add to the list
  268. winFont = m_Win32Fonts[i];
  269. }
  270. }
  271. if( !winFont )
  272. {
  273. // failed to create, remove
  274. if ( m_Win32Fonts[i] )
  275. delete m_Win32Fonts[i];
  276. m_Win32Fonts.Remove(i);
  277. return NULL;
  278. }
  279. #else
  280. m_Win32Fonts[i] = new font_t();
  281. if (m_Win32Fonts[i]->Create(windowsFontName, tall, weight, blur, scanlines, flags))
  282. {
  283. // add to the list
  284. winFont = m_Win32Fonts[i];
  285. }
  286. else
  287. {
  288. // failed to create, remove
  289. delete m_Win32Fonts[i];
  290. m_Win32Fonts.Remove(i);
  291. return NULL;
  292. }
  293. #endif
  294. }
  295. return winFont;
  296. }
  297. //-----------------------------------------------------------------------------
  298. // Purpose: Creates a new win32 font, or reuses one if possible
  299. //-----------------------------------------------------------------------------
  300. CBitmapFont *CFontManager::CreateOrFindBitmapFont(const char *windowsFontName, float scalex, float scaley, int flags)
  301. {
  302. // see if we already have the font
  303. CBitmapFont *winFont = NULL;
  304. int i;
  305. for ( i = 0; i < m_Win32Fonts.Count(); i++ )
  306. {
  307. font_t *font = m_Win32Fonts[i];
  308. // Only looking for bitmap fonts
  309. int testflags = font->GetFlags();
  310. if ( !( testflags & vgui::ISurface::FONTFLAG_BITMAP ) )
  311. {
  312. continue;
  313. }
  314. CBitmapFont *bitmapFont = reinterpret_cast< CBitmapFont* >( font );
  315. if ( bitmapFont->IsEqualTo( windowsFontName, scalex, scaley, flags ) )
  316. {
  317. winFont = bitmapFont;
  318. break;
  319. }
  320. }
  321. // create the font if we didn't find it
  322. if ( !winFont )
  323. {
  324. MEM_ALLOC_CREDIT();
  325. i = m_Win32Fonts.AddToTail();
  326. CBitmapFont *bitmapFont = new CBitmapFont();
  327. if ( bitmapFont->Create( windowsFontName, scalex, scaley, flags ) )
  328. {
  329. // add to the list
  330. m_Win32Fonts[i] = bitmapFont;
  331. winFont = bitmapFont;
  332. }
  333. else
  334. {
  335. // failed to create, remove
  336. delete bitmapFont;
  337. m_Win32Fonts.Remove(i);
  338. return NULL;
  339. }
  340. }
  341. return winFont;
  342. }
  343. //-----------------------------------------------------------------------------
  344. // Purpose: sets the scale of a bitmap font
  345. //-----------------------------------------------------------------------------
  346. void CFontManager::SetFontScale(vgui::HFont font, float sx, float sy)
  347. {
  348. m_FontAmalgams[font].SetFontScale( sx, sy );
  349. }
  350. const char *CFontManager::GetFontName( HFont font )
  351. {
  352. // ignore the amalgam of disparate char ranges, assume the first font
  353. return m_FontAmalgams[font].GetFontName( 0 );
  354. }
  355. const char *CFontManager::GetFontFamilyName( HFont font )
  356. {
  357. return m_FontAmalgams[font].GetFontFamilyName( 0 );
  358. }
  359. //-----------------------------------------------------------------------------
  360. // Purpose: gets the windows font for the particular font in the amalgam
  361. //-----------------------------------------------------------------------------
  362. font_t *CFontManager::GetFontForChar(vgui::HFont font, wchar_t wch)
  363. {
  364. return m_FontAmalgams[font].GetFontForChar(wch);
  365. }
  366. //-----------------------------------------------------------------------------
  367. // Purpose: returns the abc widths of a single character
  368. //-----------------------------------------------------------------------------
  369. void CFontManager::GetCharABCwide(HFont font, int ch, int &a, int &b, int &c)
  370. {
  371. if ( !m_FontAmalgams.IsValidIndex( font ) )
  372. {
  373. a = b = c = 0;
  374. return;
  375. }
  376. font_t *winFont = m_FontAmalgams[font].GetFontForChar(ch);
  377. if (winFont)
  378. {
  379. winFont->GetCharABCWidths(ch, a, b, c);
  380. }
  381. else
  382. {
  383. // no font for this range, just use the default width
  384. a = c = 0;
  385. b = m_FontAmalgams[font].GetFontMaxWidth();
  386. }
  387. }
  388. //-----------------------------------------------------------------------------
  389. // Purpose: returns the max height of a font
  390. //-----------------------------------------------------------------------------
  391. int CFontManager::GetFontTall(HFont font)
  392. {
  393. return m_FontAmalgams[font].GetFontHeight();
  394. }
  395. //-----------------------------------------------------------------------------
  396. // Purpose: returns requested height of the font
  397. //-----------------------------------------------------------------------------
  398. int CFontManager::GetFontTallRequested(HFont font)
  399. {
  400. return m_FontAmalgams[font].GetFontHeightRequested();
  401. }
  402. //-----------------------------------------------------------------------------
  403. // Purpose: returns the ascent of a font
  404. //-----------------------------------------------------------------------------
  405. int CFontManager::GetFontAscent(HFont font, wchar_t wch)
  406. {
  407. font_t *winFont = m_FontAmalgams[font].GetFontForChar(wch);
  408. if ( winFont )
  409. {
  410. return winFont->GetAscent();
  411. }
  412. else
  413. {
  414. return 0;
  415. }
  416. }
  417. //-----------------------------------------------------------------------------
  418. // Purpose:
  419. //-----------------------------------------------------------------------------
  420. bool CFontManager::IsFontAdditive(HFont font)
  421. {
  422. return ( m_FontAmalgams[font].GetFlags( 0 ) & vgui::ISurface::FONTFLAG_ADDITIVE ) ? true : false;
  423. }
  424. //-----------------------------------------------------------------------------
  425. // Purpose:
  426. //-----------------------------------------------------------------------------
  427. bool CFontManager::IsBitmapFont(HFont font)
  428. {
  429. // A FontAmalgam is either some number of non-bitmap fonts, or a single bitmap font - so this check is valid
  430. return ( m_FontAmalgams[font].GetFlags( 0 ) & vgui::ISurface::FONTFLAG_BITMAP ) ? true : false;
  431. }
  432. //-----------------------------------------------------------------------------
  433. // Purpose: returns the pixel width of a single character
  434. //-----------------------------------------------------------------------------
  435. int CFontManager::GetCharacterWidth(HFont font, int ch)
  436. {
  437. if ( !iswcntrl( ch ) )
  438. {
  439. int a, b, c;
  440. GetCharABCwide(font, ch, a, b, c);
  441. return (a + b + c);
  442. }
  443. return 0;
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Purpose: returns the area of a text string, including newlines
  447. //-----------------------------------------------------------------------------
  448. void CFontManager::GetTextSize(HFont font, const wchar_t *text, int &wide, int &tall)
  449. {
  450. wide = 0;
  451. tall = 0;
  452. if (!text)
  453. return;
  454. tall = GetFontTall(font);
  455. float xx = 0;
  456. char chBefore = 0;
  457. char chAfter = 0;
  458. for (int i = 0; ; i++)
  459. {
  460. wchar_t ch = text[i];
  461. if (ch == 0)
  462. {
  463. break;
  464. }
  465. chAfter = text[i+1];
  466. if (ch == '\n')
  467. {
  468. tall += GetFontTall(font);
  469. xx=0;
  470. }
  471. else if (ch == '&')
  472. {
  473. // underscore character, so skip
  474. }
  475. else
  476. {
  477. float flWide, flabcA, flabcC;
  478. GetKernedCharWidth( font, ch, chBefore, chAfter, flWide, flabcA, flabcC );
  479. xx += flWide;
  480. if (xx > wide)
  481. {
  482. wide = ceil(xx);
  483. }
  484. }
  485. chBefore = ch;
  486. }
  487. }
  488. // font validation functions
  489. struct FallbackFont_t
  490. {
  491. const char *font;
  492. const char *fallbackFont;
  493. };
  494. #ifdef WIN32
  495. const char *g_szValidAsianFonts[] = { "Marlett", NULL };
  496. // list of how fonts fallback
  497. FallbackFont_t g_FallbackFonts[] =
  498. {
  499. { "Times New Roman", "Courier New" },
  500. { "Courier New", "Courier" },
  501. { "Verdana", "Arial" },
  502. { "Trebuchet MS", "Arial" },
  503. { "Tahoma", NULL },
  504. { NULL, "Tahoma" }, // every other font falls back to this
  505. };
  506. #elif defined(OSX)
  507. static const char *g_szValidAsianFonts[] = { "Apple Symbols", NULL };
  508. // list of how fonts fallback
  509. FallbackFont_t g_FallbackFonts[] =
  510. {
  511. { "Marlett", "Apple Symbols" },
  512. { "Lucida Console", "Lucida Grande" },
  513. { "Tahoma", "Helvetica" },
  514. { "Helvetica", "Monaco" },
  515. { "Monaco", NULL },
  516. { NULL, "Monaco" } // every other font falls back to this
  517. };
  518. #elif defined(LINUX)
  519. static const char *g_szValidAsianFonts[] = { "Marlett", "WenQuanYi Zen Hei", "unifont", NULL };
  520. // list of how fonts fallback
  521. FallbackFont_t g_FallbackFonts[] =
  522. {
  523. { "DejaVu Sans", NULL },
  524. { NULL, "DejaVu Sans" }, // every other font falls back to this
  525. };
  526. #elif defined(_PS3)
  527. // list of how fonts fallback
  528. FallbackFont_t g_FallbackFonts[] =
  529. {
  530. { NULL, "Tahoma" }, // every other font falls back to this
  531. };
  532. #else
  533. #error
  534. #endif
  535. //-----------------------------------------------------------------------------
  536. // Purpose: returns true if the font is in the list of OK asian fonts
  537. //-----------------------------------------------------------------------------
  538. bool CFontManager::IsFontForeignLanguageCapable(const char *windowsFontName)
  539. {
  540. if ( IsX360() )
  541. {
  542. return false;
  543. }
  544. for (int i = 0; g_szValidAsianFonts[i] != NULL; i++)
  545. {
  546. if (!stricmp(g_szValidAsianFonts[i], windowsFontName))
  547. return true;
  548. }
  549. // typeface isn't supported by asian languages
  550. return false;
  551. }
  552. //-----------------------------------------------------------------------------
  553. // Purpose: fallback fonts
  554. //-----------------------------------------------------------------------------
  555. const char *CFontManager::GetFallbackFontName(const char *windowsFontName)
  556. {
  557. int i;
  558. for ( i = 0; g_FallbackFonts[i].font != NULL; i++ )
  559. {
  560. if (!stricmp(g_FallbackFonts[i].font, windowsFontName))
  561. return g_FallbackFonts[i].fallbackFont;
  562. }
  563. // the ultimate fallback
  564. return g_FallbackFonts[i].fallbackFont;
  565. }
  566. //-----------------------------------------------------------------------------
  567. // Purpose: specialized fonts
  568. //-----------------------------------------------------------------------------
  569. const char *CFontManager::GetForeignFallbackFontName()
  570. {
  571. #ifdef WIN32
  572. // tahoma has all the necessary characters for asian/russian languages for winXP/2K+
  573. return "Tahoma";
  574. #elif defined(OSX)
  575. return "Helvetica";
  576. #elif defined(LINUX)
  577. return "WenQuanYi Zen Hei";
  578. #elif defined(_PS3)
  579. return "Tahoma";
  580. #else
  581. #error
  582. #endif
  583. }
  584. #if defined( _X360 )
  585. bool CFontManager::GetCachedXUIMetrics( const char *pFontName, int tall, int style, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] )
  586. {
  587. // linear lookup is good enough
  588. CUtlSymbol fontSymbol = pFontName;
  589. bool bFound = false;
  590. int i;
  591. for ( i = 0; i < m_XUIMetricCache.Count(); i++ )
  592. {
  593. if ( m_XUIMetricCache[i].fontSymbol == fontSymbol && m_XUIMetricCache[i].tall == tall && m_XUIMetricCache[i].style == style )
  594. {
  595. bFound = true;
  596. break;
  597. }
  598. }
  599. if ( !bFound )
  600. {
  601. return false;
  602. }
  603. // get from the cache
  604. *pFontMetrics = m_XUIMetricCache[i].fontMetrics;
  605. V_memcpy( charMetrics, m_XUIMetricCache[i].charMetrics, 256 * sizeof( XUICharMetrics ) );
  606. return true;
  607. }
  608. #endif
  609. #if defined( _X360 )
  610. void CFontManager::SetCachedXUIMetrics( const char *pFontName, int tall, int style, XUIFontMetrics *pFontMetrics, XUICharMetrics charMetrics[256] )
  611. {
  612. MEM_ALLOC_CREDIT();
  613. int i = m_XUIMetricCache.AddToTail();
  614. m_XUIMetricCache[i].fontSymbol = pFontName;
  615. m_XUIMetricCache[i].tall = tall;
  616. m_XUIMetricCache[i].style = style;
  617. m_XUIMetricCache[i].fontMetrics = *pFontMetrics;
  618. V_memcpy( m_XUIMetricCache[i].charMetrics, charMetrics, 256 * sizeof( XUICharMetrics ) );
  619. }
  620. #endif
  621. void CFontManager::ClearTemporaryFontCache()
  622. {
  623. #if defined( _X360 )
  624. COM_TimestampedLog( "ClearTemporaryFontCache(): Start" );
  625. m_XUIMetricCache.Purge();
  626. // many fonts are blindly precached by vgui and never used
  627. // font will re-open if glyph is actually requested
  628. for ( int i = 0; i < m_Win32Fonts.Count(); i++ )
  629. {
  630. m_Win32Fonts[i]->CloseResource();
  631. }
  632. COM_TimestampedLog( "ClearTemporaryFontCache(): Finish" );
  633. #endif
  634. }
  635. //-----------------------------------------------------------------------------
  636. // Purpose: returns the max height of a font
  637. //-----------------------------------------------------------------------------
  638. bool CFontManager::GetFontUnderlined( HFont font )
  639. {
  640. return m_FontAmalgams[font].GetUnderlined();
  641. }
  642. void CFontManager::GetKernedCharWidth( vgui::HFont font, wchar_t ch, wchar_t chBefore, wchar_t chAfter, float &wide, float &flabcA, float &flabcC )
  643. {
  644. wide = 0.0f;
  645. flabcA = 0.0f;
  646. Assert( font != vgui::INVALID_FONT );
  647. if ( font == vgui::INVALID_FONT )
  648. return;
  649. font_t *pFont = m_FontAmalgams[font].GetFontForChar(ch);
  650. if ( !pFont )
  651. {
  652. // no font for this range, just use the default width
  653. flabcA = 0.0f;
  654. wide = m_FontAmalgams[font].GetFontMaxWidth();
  655. return;
  656. }
  657. if ( m_FontAmalgams[font].GetFontForChar( chBefore ) != pFont )
  658. chBefore = 0;
  659. if ( m_FontAmalgams[font].GetFontForChar( chAfter ) != pFont )
  660. chAfter = 0;
  661. #if defined(LINUX)
  662. pFont->GetKernedCharWidth( ch, chBefore, chAfter, wide, flabcA, flabcC );
  663. #else
  664. pFont->GetKernedCharWidth( ch, chBefore, chAfter, wide, flabcA );
  665. #endif
  666. }
  667. #ifdef DBGFLAG_VALIDATE
  668. //-----------------------------------------------------------------------------
  669. // Purpose: Ensure that all of our internal structures are consistent, and
  670. // account for all memory that we've allocated.
  671. // Input: validator - Our global validator object
  672. // pchName - Our name (typically a member var in our container)
  673. //-----------------------------------------------------------------------------
  674. void CFontManager::Validate( CValidator &validator, char *pchName )
  675. {
  676. validator.Push( "CFontManager", this, pchName );
  677. ValidateObj( m_FontAmalgams );
  678. for ( int iFont = 0; iFont < m_FontAmalgams.Count(); iFont++ )
  679. {
  680. ValidateObj( m_FontAmalgams[iFont] );
  681. }
  682. ValidateObj( m_Win32Fonts );
  683. for ( int iWin32Font = 0; iWin32Font < m_Win32Fonts.Count(); iWin32Font++ )
  684. {
  685. ValidatePtr( m_Win32Fonts[ iWin32Font ] );
  686. }
  687. validator.Pop();
  688. }
  689. #endif // DBGFLAG_VALIDATE