ReactOS  0.4.15-dev-4572-gde972e2
font.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Console Server DLL
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Console GDI Fonts Management.
5  * COPYRIGHT: Copyright 2017-2022 Hermès Bélusca-Maïto
6  * Copyright 2017 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "precomp.h"
12 #include <winuser.h>
13 
14 #include "settings.h"
15 #include "font.h"
16 // #include "concfg.h"
17 
18 #define NDEBUG
19 #include <debug.h>
20 
21 #define DBGFNT DPRINT
22 #define DBGFNT1 DPRINT1
23 
24 
25 /* GLOBALS ********************************************************************/
26 
27 #define TERMINAL_FACENAME L"Terminal"
28 #define DEFAULT_NON_DBCS_FONTFACE L"Lucida Console" // L"Consolas"
29 #define DEFAULT_TT_FONT_FACENAME L"__DefaultTTFont__"
30 
31 /* TrueType font list cache */
33 
34 // NOTE: Used to tag code that makes sense only with a font cache.
35 // #define FONT_CACHE_PRESENT
36 
37 
38 /* FUNCTIONS ******************************************************************/
39 
50 BYTE
52  _In_ UINT CodePage)
53 {
54  CHARSETINFO CharInfo;
55  if (TranslateCharsetInfo(UlongToPtr(CodePage), &CharInfo, TCI_SRCCODEPAGE))
56  return (BYTE)CharInfo.ciCharset;
57  else
58  return DEFAULT_CHARSET;
59 }
60 
61 /*****************************************************************************/
62 
64 {
65  /* Search criteria */
66  _In_reads_or_z_(LF_FACESIZE) PCWSTR AltFaceName;
67  FONT_DATA SearchFont;
68  UINT CodePage;
69  BOOL StrictSearch; // TRUE to do strict search; FALSE for relaxed criteria.
70 
71  /* Candidate font data */
72  BOOL FontFound; // TRUE/FALSE if we have/haven't found a suitable font.
73  FONT_DATA CandidateFont;
74  WCHAR CandidateFaceName[LF_FACESIZE];
76 
77 #define TM_IS_TT_FONT(x) (((x) & TMPF_TRUETYPE) == TMPF_TRUETYPE)
78 #define SIZE_EQUAL(s1, s2) (((s1).X == (s2).X) && ((s1).Y == (s2).Y))
79 
89 static BOOL CALLBACK
91  _In_ PLOGFONTW lplf,
92  _In_ PNEWTEXTMETRICW lpntm,
93  _In_ DWORD FontType,
95 {
97  PFONT_DATA SearchFont = &Param->SearchFont;
98 
99  if (!IsValidConsoleFont2(lplf, lpntm, FontType, Param->CodePage))
100  {
101  /* This font does not suit us; continue enumeration */
102  return TRUE;
103  }
104 
105 #ifndef FONT_CACHE_PRESENT
106  /*
107  * Since we don't cache all the possible font sizes for TrueType fonts,
108  * we cannot check our requested size (and weight) against the enumerated
109  * one; therefore reset the enumerated values to the requested ones.
110  * On the contrary, Raster fonts get their specific font sizes (and weights)
111  * enumerated separately, so for them we can keep the enumerated values.
112  */
113  if (FontType == TRUETYPE_FONTTYPE)
114  {
115  lplf->lfHeight = SearchFont->Size.Y;
116  lplf->lfWidth = 0; // SearchFont->Size.X;
117  lplf->lfWeight = FW_NORMAL;
118  }
119 #endif
120 
121  if (Param->StrictSearch)
122  {
123  /*
124  * Find whether this is an exact match.
125  */
126 
127  /* If looking for a particular family, skip non-matches */
128  if ((SearchFont->Family != 0) &&
129  ((BYTE)SearchFont->Family != (lplf->lfPitchAndFamily & 0xF0)))
130  {
131  /* Continue enumeration */
132  return TRUE;
133  }
134 
135  /* Skip non-matching sizes */
136 #if 0
137  if ((FontInfo[i].SizeWant.Y != Size.Y) &&
138  !SIZE_EQUAL(FontInfo[i].Size, Size))
139 #endif
140  if ((lplf->lfHeight != SearchFont->Size.Y) &&
141  !(lplf->lfWidth == SearchFont->Size.X &&
142  lplf->lfHeight == SearchFont->Size.Y))
143  {
144  /* Continue enumeration */
145  return TRUE;
146  }
147 
148  /* Skip non-matching weights */
149  if ((SearchFont->Weight != 0) &&
150  (SearchFont->Weight != lplf->lfWeight))
151  {
152  /* Continue enumeration */
153  return TRUE;
154  }
155 
156  /* NOTE: We are making the font enumeration at fixed CharSet,
157  * with the one specified in the parameter block. */
158  ASSERT(lplf->lfCharSet == SearchFont->CharSet);
159 
160  if ((FontType != TRUETYPE_FONTTYPE) && // !TM_IS_TT_FONT(lpntm->tmPitchAndFamily)
161  (lplf->lfCharSet != SearchFont->CharSet) &&
162  !(lplf->lfCharSet == OEM_CHARSET && IsCJKCodePage(Param->CodePage))) // g_fEastAsianSystem
163  {
164  /* Continue enumeration */
165  return TRUE;
166  }
167 
168  /*
169  * Size (and maybe family) match. If we don't care about the name or
170  * if it matches, use this font. Otherwise, if name doesn't match and
171  * it is a raster font, consider it.
172  *
173  * NOTE: The font face names are case-sensitive.
174  */
175  if (!SearchFont->FaceName || !*(SearchFont->FaceName) ||
176  (wcscmp(lplf->lfFaceName, SearchFont->FaceName) == 0) ||
177  (wcscmp(lplf->lfFaceName, Param->AltFaceName) == 0))
178  {
179  // FontIndex = i;
180 
181  PFONT_DATA CandidateFont = &Param->CandidateFont;
182 
183  CandidateFont->FaceName = Param->CandidateFaceName;
184  StringCchCopyNW(Param->CandidateFaceName,
185  ARRAYSIZE(Param->CandidateFaceName),
186  lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName));
187 
188  CandidateFont->Weight = lplf->lfWeight;
189  CandidateFont->Family = (lplf->lfPitchAndFamily & 0xF0);
190 
191  CandidateFont->Size.X = lplf->lfWidth;
192  CandidateFont->Size.Y = lplf->lfHeight;
193 
194  CandidateFont->CharSet = lplf->lfCharSet;
195 
196  /* The font is found, stop enumeration */
197  Param->FontFound = TRUE;
198  return FALSE;
199  }
200  else if (FontType != TRUETYPE_FONTTYPE) // !TM_IS_TT_FONT(lpntm->tmPitchAndFamily)
201  {
202  // FontIndex = i;
203 
204  PFONT_DATA CandidateFont = &Param->CandidateFont;
205 
206  CandidateFont->FaceName = Param->CandidateFaceName;
207  StringCchCopyNW(Param->CandidateFaceName,
208  ARRAYSIZE(Param->CandidateFaceName),
209  lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName));
210 
211  CandidateFont->Weight = lplf->lfWeight;
212  CandidateFont->Family = (lplf->lfPitchAndFamily & 0xF0);
213 
214  CandidateFont->Size.X = lplf->lfWidth;
215  CandidateFont->Size.Y = lplf->lfHeight;
216 
217  CandidateFont->CharSet = lplf->lfCharSet;
218 
219  /* A close Raster Font fit was found; only the name doesn't match.
220  * Continue enumeration to see whether we can find better. */
221  Param->FontFound = TRUE;
222  }
223  }
224  else // !Param->StrictSearch
225  {
226  /*
227  * Failed to find exact match, even after enumeration, so now
228  * try to find a font of same family and same size or bigger.
229  */
230 
231  if (IsCJKCodePage(Param->CodePage)) // g_fEastAsianSystem
232  {
233  if ((SearchFont->Family != 0) &&
234  ((BYTE)SearchFont->Family != (lplf->lfPitchAndFamily & 0xF0)))
235  {
236  /* Continue enumeration */
237  return TRUE;
238  }
239 
240  if ((FontType != TRUETYPE_FONTTYPE) && // !TM_IS_TT_FONT(lpntm->tmPitchAndFamily)
241  (lplf->lfCharSet != SearchFont->CharSet))
242  {
243  /* Continue enumeration */
244  return TRUE;
245  }
246  }
247  else
248  {
249  if (// (SearchFont->Family != 0) &&
250  ((BYTE)SearchFont->Family != (lplf->lfPitchAndFamily & 0xF0)))
251  {
252  /* Continue enumeration */
253  return TRUE;
254  }
255  }
256 
257  if ((lplf->lfHeight >= SearchFont->Size.Y) &&
258  (lplf->lfWidth >= SearchFont->Size.X))
259  {
260  /* Same family, size >= desired */
261  // FontIndex = i;
262 
263  PFONT_DATA CandidateFont = &Param->CandidateFont;
264 
265  CandidateFont->FaceName = Param->CandidateFaceName;
266  StringCchCopyNW(Param->CandidateFaceName,
267  ARRAYSIZE(Param->CandidateFaceName),
268  lplf->lfFaceName, ARRAYSIZE(lplf->lfFaceName));
269 
270  CandidateFont->Weight = lplf->lfWeight;
271  CandidateFont->Family = (lplf->lfPitchAndFamily & 0xF0);
272 
273  CandidateFont->Size.X = lplf->lfWidth;
274  CandidateFont->Size.Y = lplf->lfHeight;
275 
276  CandidateFont->CharSet = lplf->lfCharSet;
277 
278  /* The font is found, stop enumeration */
279  Param->FontFound = TRUE;
280  return FALSE;
281  }
282  }
283 
284  /* Continue enumeration */
285  return TRUE;
286 }
287 
306 static BOOL
308  _Inout_ PFONT_DATA FontData,
309  _In_ UINT CodePage)
310 {
313  HDC hDC;
314  LOGFONTW lf;
315  PTT_FONT_ENTRY FontEntry;
316 
317  /* Save the original FaceName pointer */
318  FaceName = FontData->FaceName;
319 
320  /* Save our current search criteria */
321  RtlZeroMemory(&Param, sizeof(Param));
322  Param.SearchFont = *FontData;
323 
324  Param.SearchFont.CharSet = CodePageToCharSet(CodePage);
325  Param.CodePage = CodePage;
326 
327  if (/* !FaceName || */ !*FaceName)
328  {
329  /* Find and use a default Raster font */
330 
331  /* Use "Terminal" as the fallback */
333 #if 0
334  // FIXME: CJK font choose workaround: Don't choose Asian
335  // charset font if there is no preferred font for CJK.
336  if (IsCJKCodePage(CodePage))
337  FontData->CharSet = ANSI_CHARSET;
338 #endif
339  FontData->Family &= ~TMPF_TRUETYPE;
340  }
341  else if (wcscmp(FaceName, DEFAULT_TT_FONT_FACENAME) == 0)
342  {
343  /* Find and use a default TrueType font */
344  FontEntry = FindCachedTTFont(NULL, CodePage);
345  if (FontEntry)
346  {
347  StringCchCopyW(FaceName, LF_FACESIZE, FontEntry->FaceName);
348  }
349  else
350  {
352  }
353  FontData->Family |= TMPF_TRUETYPE;
354  }
355 
356  /* Search for a TrueType alternative face name */
357  FontEntry = FindCachedTTFont(FaceName, CodePage);
358  if (FontEntry)
359  {
360  /* NOTE: The font face names are case-sensitive */
361  if (wcscmp(FontEntry->FaceName, FaceName) == 0)
362  Param.AltFaceName = FontEntry->FaceNameAlt;
363  else if (wcscmp(FontEntry->FaceNameAlt, FaceName) == 0)
364  Param.AltFaceName = FontEntry->FaceName;
365  }
366  else
367  {
368  Param.AltFaceName = FaceName;
369  }
370 
371  /* Initialize the search: start with a strict search, then a relaxed one */
372  Param.FontFound = FALSE;
373 
374  Param.StrictSearch = TRUE;
375 SearchAgain:
376  /*
377  * Enumerate all fonts with the given character set.
378  * We will match them with the search criteria.
379  */
380  RtlZeroMemory(&lf, sizeof(lf));
381  lf.lfCharSet = Param.SearchFont.CharSet;
382  // lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
383 
384  hDC = GetDC(NULL);
386  ReleaseDC(NULL, hDC);
387 
388  /* If we failed to find any font, search again with relaxed criteria */
389  if (Param.StrictSearch && !Param.FontFound)
390  {
391  Param.StrictSearch = FALSE;
392  goto SearchAgain;
393  }
394 
395  /* If no font was found again, return failure */
396  if (!Param.FontFound)
397  return FALSE;
398 
399  /* Return the font details */
400  *FontData = Param.CandidateFont;
401  FontData->FaceName = FaceName; // Restore the original FaceName pointer.
402  StringCchCopyNW(FaceName, LF_FACESIZE,
403  Param.CandidateFaceName,
404  ARRAYSIZE(Param.CandidateFaceName));
405 
406  return TRUE;
407 }
408 
423 static HFONT
425  _In_ PFONT_DATA FontData,
426  _In_ UINT CodePage)
427 {
428  LOGFONTW lf;
429 
430  RtlZeroMemory(&lf, sizeof(lf));
431 
432  lf.lfHeight = (LONG)(ULONG)FontData->Size.Y;
433  lf.lfWidth = (LONG)(ULONG)FontData->Size.X;
434 
435  lf.lfEscapement = 0;
436  lf.lfOrientation = 0; // TA_BASELINE; // TA_RTLREADING; when the console supports RTL?
437  // lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = FALSE;
438  lf.lfWeight = FontData->Weight;
439  lf.lfCharSet = CodePageToCharSet(CodePage);
443 
444  /* Set the mandatory flags and remove those that we do not support */
445  lf.lfPitchAndFamily = (BYTE)( (FIXED_PITCH | FF_MODERN | FontData->Family) &
447 
448  if (!IsValidConsoleFont(FontData->FaceName, CodePage))
449  return NULL;
450 
452  FontData->FaceName, LF_FACESIZE);
453 
454  return CreateFontIndirectW(&lf);
455 }
456 
457 /*****************************************************************************/
458 
504 HFONT
506  _In_ LONG Height,
509  PWSTR FaceName,
510  _In_ ULONG FontWeight,
512  _In_ UINT CodePage,
513  _In_ BOOL UseDefaultFallback,
514  _Out_ PFONT_DATA FontData)
515 {
516  HFONT hFont;
517 
518  FontData->FaceName = FaceName;
519  FontData->Weight = FontWeight;
520  FontData->Family = FontFamily;
521  /* NOTE: FontSize is always in cell height/width units (pixels) */
522  FontData->Size.X = Width;
523  FontData->Size.Y = Height;
524  FontData->CharSet = 0; // CodePageToCharSet(CodePage);
525 
526  if (/* !FaceName || */ !*FaceName || wcscmp(FaceName, DEFAULT_TT_FONT_FACENAME) == 0)
527  {
528  /* We do not have an actual font face name yet and should find one.
529  * Call FindSuitableFont() to determine the default font to use. */
530  }
531  else
532  {
533  hFont = CreateConsoleFontWorker(FontData, CodePage);
534  if (hFont)
535  return hFont;
536 
537  DBGFNT1("CreateConsoleFont('%S') failed - Try to find a suitable font...\n",
538  FaceName);
539  }
540 
541  /*
542  * We could not create a font with the default settings.
543  * Try to find a suitable font and retry.
544  */
545  if (!FindSuitableFont(FontData, CodePage))
546  {
547  /* We could not find any suitable font, fall back
548  * to some default one if required to do so. */
549  DBGFNT1("FindSuitableFont could not find anything - %s\n",
550  UseDefaultFallback ? "Falling back to 'Terminal'"
551  : "Bailing out");
552 
553  /* No fallback: no font! */
554  if (!UseDefaultFallback)
555  return NULL;
556 
557  //
558  // FIXME: See also !*FaceName case in FindSuitableFont().
559  //
560  /* Use "Terminal" as the fallback */
562 #if 0
563  // FIXME: CJK font choose workaround: Don't choose Asian
564  // charset font if there is no preferred font for CJK.
565  if (IsCJKCodePage(CodePage))
566  FontData->CharSet = ANSI_CHARSET;
567 #endif
568  FontData->Family &= ~TMPF_TRUETYPE;
569  }
570  else
571  {
572  DBGFNT1("FindSuitableFont found: '%S', size (%d x %d)\n",
573  FaceName, FontData->Size.X, FontData->Size.Y);
574  }
575 
576  /* Retry creating the font */
577  hFont = CreateConsoleFontWorker(FontData, CodePage);
578  if (!hFont)
579  DBGFNT1("CreateConsoleFont('%S') failed\n", FaceName);
580 
581  return hFont;
582 }
583 
608 HFONT
610  _In_ LONG Height,
613 {
614  FONT_DATA FontData;
615  HFONT hFont;
616 
618  Width,
619  ConsoleInfo->FaceName,
620  ConsoleInfo->FontWeight,
621  ConsoleInfo->FontFamily,
622  ConsoleInfo->CodePage,
623  TRUE, // UseDefaultFallback
624  &FontData);
625  if (hFont)
626  {
627  ConsoleInfo->FontWeight = FontData.Weight;
628  ConsoleInfo->FontFamily = FontData.Family;
629  }
630 
631  return hFont;
632 }
633 
652 HFONT
655 {
656  /*
657  * Format:
658  * Width = FontSize.X = LOWORD(FontSize);
659  * Height = FontSize.Y = HIWORD(FontSize);
660  */
661  /* NOTE: FontSize is always in cell height/width units (pixels) */
662  return CreateConsoleFont2((LONG)(ULONG)ConsoleInfo->FontSize.Y,
663  (LONG)(ULONG)ConsoleInfo->FontSize.X,
664  ConsoleInfo);
665 }
666 
686 _Success_(return)
687 BOOL
688 GetFontCellSize(
689  _In_opt_ HDC hDC,
690  _In_ HFONT hFont,
692  _Out_ PUINT Width)
693 {
694  BOOL Success = FALSE;
695  HDC hOrgDC = hDC;
696  HFONT hOldFont;
697  // LONG LogSize, PointSize;
699  TEXTMETRICW tm;
700  // SIZE CharSize;
701 
702  if (!hDC)
703  hDC = GetDC(NULL);
704 
705  hOldFont = SelectObject(hDC, hFont);
706  if (hOldFont == NULL)
707  {
708  DBGFNT1("GetFontCellSize: SelectObject failed\n");
709  goto Quit;
710  }
711 
712 /*
713  * See also: Display_SetTypeFace in applications/fontview/display.c
714  */
715 
716  /*
717  * Note that the method with GetObjectW just returns
718  * the original parameters with which the font was created.
719  */
720  if (!GetTextMetricsW(hDC, &tm))
721  {
722  DBGFNT1("GetFontCellSize: GetTextMetrics failed\n");
723  goto Cleanup;
724  }
725 
726  CharHeight = tm.tmHeight + tm.tmExternalLeading;
727 
728 #if 0
729  /* Measure real char width more precisely if possible */
730  if (GetTextExtentPoint32W(hDC, L"R", 1, &CharSize))
731  CharWidth = CharSize.cx;
732 #else
733  CharWidth = tm.tmAveCharWidth; // tm.tmMaxCharWidth;
734 #endif
735 
736 #if 0
737  /*** Logical to Point size ***/
738  LogSize = tm.tmHeight - tm.tmInternalLeading;
739  PointSize = MulDiv(LogSize, 72, GetDeviceCaps(hDC, LOGPIXELSY));
740  /*****************************/
741 #endif
742 
743  *Height = (UINT)CharHeight;
744  *Width = (UINT)CharWidth;
745  Success = TRUE;
746 
747 Cleanup:
748  SelectObject(hDC, hOldFont);
749 Quit:
750  if (!hOrgDC)
751  ReleaseDC(NULL, hDC);
752 
753  return Success;
754 }
755 
781 BOOL
783  _In_ PLOGFONTW lplf,
784  _In_ PNEWTEXTMETRICW lpntm,
785  _In_ DWORD FontType,
786  _In_ UINT CodePage)
787 {
788  LPCWSTR FaceName = lplf->lfFaceName;
789 
790  /*
791  * According to: https://web.archive.org/web/20140901124501/http://support.microsoft.com/kb/247815
792  * "Necessary criteria for fonts to be available in a command window",
793  * the criteria for console-eligible fonts are as follows:
794  * - The font must be a fixed-pitch font.
795  * - The font cannot be an italic font.
796  * - The font cannot have a negative A or C space.
797  * - If it is a TrueType font, it must be FF_MODERN.
798  * - If it is not a TrueType font, it must be OEM_CHARSET.
799  *
800  * Non documented: vertical fonts are forbidden (their name start with a '@').
801  *
802  * Additional criteria for Asian installations:
803  * - If it is not a TrueType font, the face name must be "Terminal".
804  * - If it is an Asian TrueType font, it must also be an Asian character set.
805  *
806  * See also Raymond Chen's blog: https://devblogs.microsoft.com/oldnewthing/?p=26843
807  * and MIT-licensed Microsoft Terminal source code: https://github.com/microsoft/terminal/blob/main/src/propsheet/misc.cpp
808  * for other details.
809  *
810  * To install additional TrueType fonts to be available for the console,
811  * add entries of type REG_SZ named "0", "00" etc... in:
812  * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont
813  * The names of the fonts listed there should match those in:
814  * HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts
815  */
816 
817  /*
818  * In ReactOS we relax some of the criteria:
819  * - We allow fixed-pitch FF_MODERN (Monospace) TrueType fonts
820  * that can be italic or have negative A or C space.
821  * - If it is not a TrueType font, it can be from another character set
822  * than OEM_CHARSET. When an Asian codepage is active however, we require
823  * that this non-TrueType font has an Asian character set.
824  */
825 
826  /* Reject variable-width fonts ... */
827  if ( ( ((lplf->lfPitchAndFamily & 0x03) != FIXED_PITCH)
828 #if 0 /* Reject italic and TrueType fonts with negative A or C space ... */
829  || (lplf->lfItalic)
830  || !(lpntm->ntmFlags & NTM_NONNEGATIVE_AC)
831 #endif
832  ) &&
833  /* ... if they are not in the list of additional TrueType fonts to include */
834  !IsAdditionalTTFont(FaceName) )
835  {
836  DBGFNT("Font '%S' rejected because it%s (lfPitchAndFamily = %d)\n",
837  FaceName,
838  !(lplf->lfPitchAndFamily & FIXED_PITCH) ? "'s not FIXED_PITCH"
839  : (!(lpntm->ntmFlags & NTM_NONNEGATIVE_AC) ? " has negative A or C space"
840  : " is broken"),
841  lplf->lfPitchAndFamily);
842  return FALSE;
843  }
844 
845  /* Reject TrueType fonts that are not FF_MODERN */
846  if ((FontType == TRUETYPE_FONTTYPE) && ((lplf->lfPitchAndFamily & 0xF0) != FF_MODERN))
847  {
848  DBGFNT("TrueType font '%S' rejected because it's not FF_MODERN (lfPitchAndFamily = %d)\n",
849  FaceName, lplf->lfPitchAndFamily);
850  return FALSE;
851  }
852 
853  /* Reject vertical fonts (tategaki) */
854  if (FaceName[0] == L'@')
855  {
856  DBGFNT("Font '%S' rejected because it's vertical\n", FaceName);
857  return FALSE;
858  }
859 
860  /* Is the current code page Chinese, Japanese or Korean? */
861  if (IsCJKCodePage(CodePage))
862  {
863  /* It's CJK */
864 
865  if (FontType == TRUETYPE_FONTTYPE)
866  {
867  /*
868  * Here we are inclusive and check for any CJK character set,
869  * instead of looking just at the current one via CodePageToCharSet().
870  */
871  if (!IsCJKCharSet(lplf->lfCharSet))
872  {
873  DBGFNT("TrueType font '%S' rejected because it's not Asian charset (lfCharSet = %d)\n",
874  FaceName, lplf->lfCharSet);
875  return FALSE;
876  }
877 
878  /*
879  * If this is a cached TrueType font that is used only for certain
880  * code pages, verify that the charset it claims is the correct one.
881  *
882  * Since there may be multiple entries for a cached TrueType font,
883  * a general one (code page == 0) and one or more for explicit
884  * code pages, we need to perform two search queries instead of
885  * just one and retrieving the code page for this entry.
886  */
887  if (IsAdditionalTTFont(FaceName) && !IsAdditionalTTFontCP(FaceName, 0) &&
888  !IsCJKCharSet(lplf->lfCharSet))
889  {
890  DBGFNT("Cached TrueType font '%S' rejected because it claims a code page that is not Asian charset (lfCharSet = %d)\n",
891  FaceName, lplf->lfCharSet);
892  return FALSE;
893  }
894  }
895  else
896  {
897  /* Reject non-TrueType fonts that do not have an Asian character set */
898  if (!IsCJKCharSet(lplf->lfCharSet) && (lplf->lfCharSet != OEM_CHARSET))
899  {
900  DBGFNT("Non-TrueType font '%S' rejected because it's not Asian charset or OEM_CHARSET (lfCharSet = %d)\n",
901  FaceName, lplf->lfCharSet);
902  return FALSE;
903  }
904 
905  /* Reject non-TrueType fonts that are not Terminal */
906  if (wcscmp(FaceName, TERMINAL_FACENAME) != 0)
907  {
908  DBGFNT("Non-TrueType font '%S' rejected because it's not 'Terminal'\n", FaceName);
909  return FALSE;
910  }
911  }
912  }
913  else
914  {
915  /* Not CJK */
916 
917  /* Reject non-TrueType fonts that are not OEM or similar */
918  if ((FontType != TRUETYPE_FONTTYPE) &&
919  (lplf->lfCharSet != ANSI_CHARSET) &&
920  (lplf->lfCharSet != DEFAULT_CHARSET) &&
921  (lplf->lfCharSet != OEM_CHARSET))
922  {
923  DBGFNT("Non-TrueType font '%S' rejected because it's not ANSI_CHARSET or DEFAULT_CHARSET or OEM_CHARSET (lfCharSet = %d)\n",
924  FaceName, lplf->lfCharSet);
925  return FALSE;
926  }
927  }
928 
929  /* All good */
930  return TRUE;
931 }
932 
934 {
938 
942 static BOOL CALLBACK
944  _In_ PLOGFONTW lplf,
945  _In_ PNEWTEXTMETRICW lpntm,
946  _In_ DWORD FontType,
948 {
950  Param->IsValidFont = IsValidConsoleFont2(lplf, lpntm, FontType, Param->CodePage);
951 
952  /* Stop the enumeration now */
953  return FALSE;
954 }
955 
973 BOOL
975  // _In_reads_or_z_(LF_FACESIZE)
976  _In_ PCWSTR FaceName,
977  _In_ UINT CodePage)
978 {
980  HDC hDC;
981  LOGFONTW lf;
982 
983  Param.IsValidFont = FALSE;
984  Param.CodePage = CodePage;
985 
986  RtlZeroMemory(&lf, sizeof(lf));
987  lf.lfCharSet = CodePageToCharSet(CodePage);
988  // lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
989  StringCchCopyW(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FaceName);
990 
991  hDC = GetDC(NULL);
993  ReleaseDC(NULL, hDC);
994 
995  return Param.IsValidFont;
996 }
997 
998 
1012 VOID
1014 {
1015  LRESULT lResult;
1016  HKEY hKey;
1017  DWORD dwIndex, dwType;
1018  WCHAR szValueName[MAX_PATH];
1019  DWORD cchValueName;
1020  WCHAR szValue[LF_FACESIZE] = L"";
1021  DWORD cbValue;
1022  UINT CodePage;
1023  PTT_FONT_ENTRY FontEntry;
1024  PWCHAR pszNext;
1025 
1026  if (TTFontCache.Next != NULL)
1027  return;
1028  // TTFontCache.Next = NULL;
1029 
1030  /* Open the Console\TrueTypeFont key */
1031  // "\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont"
1033  L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont",
1034  0,
1036  &hKey) != ERROR_SUCCESS)
1037  {
1038  return;
1039  }
1040 
1041  /* Enumerate all the available TrueType console fonts */
1042  for (dwIndex = 0, cchValueName = ARRAYSIZE(szValueName),
1043  cbValue = sizeof(szValue);
1044  (lResult = RegEnumValueW(hKey, dwIndex,
1045  szValueName, &cchValueName,
1046  NULL, &dwType,
1047  (PBYTE)szValue, &cbValue)) != ERROR_NO_MORE_ITEMS;
1048  ++dwIndex, cchValueName = ARRAYSIZE(szValueName),
1049  cbValue = sizeof(szValue))
1050  {
1051  /* Ignore if we failed for another reason, e.g. because
1052  * the value name is too long (and thus, invalid). */
1053  if (lResult != ERROR_SUCCESS)
1054  continue;
1055 
1056  /* Validate the value name (exclude the unnamed value) */
1057  if (!cchValueName || (*szValueName == UNICODE_NULL))
1058  continue;
1059  /* Too large value names have already been handled with ERROR_MORE_DATA */
1060  ASSERT((cchValueName < ARRAYSIZE(szValueName)) &&
1061  (szValueName[cchValueName] == UNICODE_NULL));
1062 
1063  /* Only (multi-)string values are supported */
1064  if ((dwType != REG_SZ) && (dwType != REG_MULTI_SZ))
1065  continue;
1066 
1067  /* The value name is a code page (in decimal), validate it */
1068  CodePage = wcstoul(szValueName, &pszNext, 10);
1069  if (*pszNext)
1070  continue; // Non-numerical garbage followed...
1071  // IsValidCodePage(CodePage);
1072 
1073  FontEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*FontEntry));
1074  if (!FontEntry)
1075  {
1076  DBGFNT1("InitTTFontCache: Failed to allocate memory, continuing...\n");
1077  continue;
1078  }
1079 
1080  FontEntry->CodePage = CodePage;
1081 
1082  pszNext = szValue;
1083 
1084  /* Check whether bold is disabled for this font */
1085  if (*pszNext == BOLD_MARK)
1086  {
1087  FontEntry->DisableBold = TRUE;
1088  ++pszNext;
1089  }
1090  else
1091  {
1092  FontEntry->DisableBold = FALSE;
1093  }
1094 
1095  /* Copy the font name */
1096  StringCchCopyNW(FontEntry->FaceName, ARRAYSIZE(FontEntry->FaceName),
1097  pszNext, wcslen(pszNext));
1098 
1099  if (dwType == REG_MULTI_SZ)
1100  {
1101  /* There may be an alternate face name as the second string */
1102  pszNext += wcslen(pszNext) + 1;
1103 
1104  /* Check whether bold is disabled for this font */
1105  if (*pszNext == BOLD_MARK)
1106  {
1107  FontEntry->DisableBold = TRUE;
1108  ++pszNext;
1109  }
1110  // else, keep the original setting.
1111 
1112  /* Copy the alternate font name */
1113  StringCchCopyNW(FontEntry->FaceNameAlt, ARRAYSIZE(FontEntry->FaceNameAlt),
1114  pszNext, wcslen(pszNext));
1115  }
1116 
1117  PushEntryList(&TTFontCache, &FontEntry->Entry);
1118  }
1119 
1120  /* Close the key and quit */
1121  RegCloseKey(hKey);
1122 }
1123 
1130 VOID
1132 {
1134  PTT_FONT_ENTRY FontEntry;
1135 
1136  while (TTFontCache.Next != NULL)
1137  {
1139  FontEntry = CONTAINING_RECORD(Entry, TT_FONT_ENTRY, Entry);
1140  RtlFreeHeap(RtlGetProcessHeap(), 0, FontEntry);
1141  }
1142  TTFontCache.Next = NULL;
1143 }
1144 
1152 VOID
1154 {
1155  ClearTTFontCache();
1156  InitTTFontCache();
1157 }
1158 
1185  PCWSTR FaceName,
1186  _In_ UINT CodePage)
1187 {
1189  PTT_FONT_ENTRY FontEntry;
1190 
1191  if (FaceName)
1192  {
1193  /* Search for the named font */
1194  for (Entry = TTFontCache.Next;
1195  Entry != NULL;
1196  Entry = Entry->Next)
1197  {
1198  FontEntry = CONTAINING_RECORD(Entry, TT_FONT_ENTRY, Entry);
1199 
1200  /* NOTE: The font face names are case-sensitive */
1201  if ((wcscmp(FontEntry->FaceName , FaceName) == 0) ||
1202  (wcscmp(FontEntry->FaceNameAlt, FaceName) == 0))
1203  {
1204  /* Return the font if we don't search by code page, or when they match */
1205  if ((CodePage == INVALID_CP) || (CodePage == FontEntry->CodePage))
1206  {
1207  return FontEntry;
1208  }
1209  }
1210  }
1211  }
1212  else if (CodePage != INVALID_CP)
1213  {
1214  /* Search for a font with the specified code page */
1215  for (Entry = TTFontCache.Next;
1216  Entry != NULL;
1217  Entry = Entry->Next)
1218  {
1219  FontEntry = CONTAINING_RECORD(Entry, TT_FONT_ENTRY, Entry);
1220 
1221  /* Return the font if the code pages match */
1222  if (CodePage == FontEntry->CodePage)
1223  return FontEntry;
1224  }
1225  }
1226 
1227  return NULL;
1228 }
1229 
1230 /* EOF */
HFONT WINAPI CreateFontIndirectW(CONST LOGFONTW *lplf)
Definition: font.c:1803
const uint16_t * PCWSTR
Definition: typedefs.h:57
int WINAPI EnumFontFamiliesExW(HDC hdc, LPLOGFONTW lpLogfont, FONTENUMPROCW lpEnumFontFamExProc, LPARAM lParam, DWORD dwFlags)
Definition: font.c:400
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
#define LF_FACESIZE
Definition: dimm.idl:39
BYTE lfPitchAndFamily
Definition: dimm.idl:71
#define VARIABLE_PITCH
Definition: wingdi.h:445
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
#define IsCJKCharSet(CharSet)
Definition: font.h:54
#define _In_opt_
Definition: ms_sal.h:309
#define _Inout_
Definition: ms_sal.h:378
#define ERROR_SUCCESS
Definition: deptool.c:10
#define DEFAULT_QUALITY
Definition: wingdi.h:436
#define NTM_NONNEGATIVE_AC
Definition: wingdi.h:25
struct _Entry Entry
Definition: kefuncs.h:629
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
Definition: ntbasedef.h:628
#define _Out_
Definition: ms_sal.h:345
static LONG(WINAPI *pGdiGetCharDimensions)(HDC hdc
HDC WINAPI GetDC(_In_opt_ HWND)
HFONT CreateConsoleFont(_Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
A wrapper for CreateConsoleFontEx().
Definition: font.c:653
#define TRUE
Definition: types.h:120
static BOOL CALLBACK IsValidConsoleFontProc(_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ LPARAM lParam)
EnumFontFamiliesEx() callback helper for IsValidConsoleFont().
Definition: font.c:943
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:124
static BOOL CALLBACK FindSuitableFontProc(_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ LPARAM lParam)
EnumFontFamiliesEx() callback helper for FindSuitableFont().
Definition: font.c:90
#define FF_DECORATIVE
Definition: wingdi.h:447
BOOL IsValidConsoleFont(_In_ PCWSTR FaceName, _In_ UINT CodePage)
Validates whether a given font can be supported in the console, under the specified code page.
Definition: font.c:974
LONG lfHeight
Definition: dimm.idl:59
struct _FIND_SUITABLE_FONT_PROC_PARAM FIND_SUITABLE_FONT_PROC_PARAM
BYTE lfCharSet
Definition: dimm.idl:67
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BYTE lfClipPrecision
Definition: dimm.idl:69
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
LONG lfEscapement
Definition: dimm.idl:61
#define DBGFNT
Definition: font.c:21
UINT CodePage
Definition: font.h:75
_In_ HFONT _Out_ PUINT Height
Definition: font.h:124
uint16_t * PWCHAR
Definition: typedefs.h:56
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define BOLD_MARK
Definition: font.h:70
#define DEFAULT_CHARSET
Definition: wingdi.h:384
HFONT hFont
Definition: main.c:53
VOID InitTTFontCache(VOID)
Initializes the console TrueType font cache.
Definition: font.c:1013
#define IsAdditionalTTFont(FaceName)
Verifies whether the given font is an additional console TrueType font. Wrapper macros around FindCac...
Definition: font.h:168
VOID ClearTTFontCache(VOID)
Clears the console TrueType font cache.
Definition: font.c:1131
static HFONT CreateConsoleFontWorker(_In_ PFONT_DATA FontData, _In_ UINT CodePage)
Validates and creates a suitable console font based on the font characteristics given in input.
Definition: font.c:424
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define SIZE_EQUAL(s1, s2)
Definition: font.c:78
unsigned int BOOL
Definition: ntddk_ex.h:94
HFONT CreateConsoleFontEx(_In_ LONG Height, _In_opt_ LONG Width, _Inout_updates_z_(LF_FACESIZE) PWSTR FaceName, _In_ ULONG FontWeight, _In_ ULONG FontFamily, _In_ UINT CodePage, _In_ BOOL UseDefaultFallback, _Out_ PFONT_DATA FontData)
Validates and creates a suitable console font based on the font characteristics given in input.
Definition: font.c:505
long LONG
Definition: pedump.c:60
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
#define FIXED_PITCH
Definition: wingdi.h:444
LONG lfOrientation
Definition: dimm.idl:62
#define REG_MULTI_SZ
Definition: nt_native.h:1501
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
ULONG Family
Definition: font.h:93
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
UINT ciCharset
Definition: wingdi.h:1546
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
LONG lfWidth
Definition: dimm.idl:60
COORD Size
Definition: font.h:94
#define _In_
Definition: ms_sal.h:308
LONG_PTR LPARAM
Definition: windef.h:208
static BOOL FindSuitableFont(_Inout_ PFONT_DATA FontData, _In_ UINT CodePage)
Finds a font suitable for the given code page, based on the current font and its characteristics prov...
Definition: font.c:307
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240
BYTE lfOutPrecision
Definition: dimm.idl:68
static int CharHeight
Definition: carets.c:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
ULONG X
Definition: bl.h:1339
BYTE CodePageToCharSet(_In_ UINT CodePage)
Retrieves the character set associated with a given code page.
Definition: font.c:51
HFONT CreateConsoleFont2(_In_ LONG Height, _In_opt_ LONG Width, _Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
A wrapper for CreateConsoleFontEx().
Definition: font.c:609
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:415
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _In_reads_or_z_opt_(size)
Definition: ms_sal.h:326
static int CharWidth
Definition: carets.c:7
#define INVALID_CP
Definition: stream.h:53
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
#define OEM_CHARSET
Definition: wingdi.h:400
BYTE lfQuality
Definition: dimm.idl:70
WCHAR FaceName[LF_FACESIZE]
Definition: font.h:77
ULONG Weight
Definition: font.h:92
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
Definition: time.h:68
#define FF_ROMAN
Definition: wingdi.h:450
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned char BYTE
Definition: xxhash.c:193
BOOL DisableBold
Definition: font.h:76
BOOL WINAPI TranslateCharsetInfo(LPDWORD lpSrc, LPCHARSETINFO lpCs, DWORD flags)
Definition: font.c:2186
SINGLE_LIST_ENTRY Entry
Definition: font.h:74
static HDC hDC
Definition: 3dtext.c:33
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define FF_SWISS
Definition: wingdi.h:452
VOID RefreshTTFontCache(VOID)
Refreshes the console TrueType font cache, by clearing and re-initializing it.
Definition: font.c:1153
Definition: font.h:72
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxAutoRegKey hKey
FARPROC FONTENUMPROCW
Definition: wingdi.h:2897
#define IsCJKCodePage(CodePage)
Definition: pager.c:42
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define TERMINAL_FACENAME
Definition: font.c:27
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
#define _Inout_updates_z_(size)
Definition: ms_sal.h:389
#define FF_MODERN
Definition: wingdi.h:449
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define DEFAULT_TT_FONT_FACENAME
Definition: font.c:29
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
struct _IS_VALID_CONSOLE_FONT_PARAM * PIS_VALID_CONSOLE_FONT_PARAM
#define FF_SCRIPT
Definition: wingdi.h:451
#define FW_NORMAL
Definition: wingdi.h:373
#define _In_reads_or_z_(size)
Definition: ms_sal.h:325
struct _FIND_SUITABLE_FONT_PROC_PARAM * PFIND_SUITABLE_FONT_PROC_PARAM
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define TCI_SRCCODEPAGE
Definition: wingdi.h:962
WCHAR FaceNameAlt[LF_FACESIZE]
Definition: font.h:78
SINGLE_LIST_ENTRY TTFontCache
Definition: font.c:32
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
BOOL IsValidConsoleFont2(_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ UINT CodePage)
Validates whether a given font can be supported in the console, under the specified code page.
Definition: font.c:782
#define DEFAULT_NON_DBCS_FONTFACE
Definition: font.c:28
unsigned int ULONG
Definition: retypes.h:1
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define LOGPIXELSY
Definition: wingdi.h:719
BYTE CharSet
Definition: font.h:95
PTT_FONT_ENTRY FindCachedTTFont(_In_reads_or_z_opt_(LF_FACESIZE) PCWSTR FaceName, _In_ UINT CodePage)
Searches for a font in the console TrueType font cache, with the specified code page.
Definition: font.c:1183
struct _IS_VALID_CONSOLE_FONT_PARAM IS_VALID_CONSOLE_FONT_PARAM
LONG lfWeight
Definition: dimm.idl:63
#define ANSI_CHARSET
Definition: wingdi.h:383
LONG_PTR LRESULT
Definition: windef.h:209
ULONG Y
Definition: bl.h:1340
BYTE * PBYTE
Definition: pedump.c:66
LPARAM lParam
Definition: combotst.c:139
#define RegCloseKey(hKey)
Definition: registry.h:47
base of all file and directory entries
Definition: entries.h:82
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
unsigned int * PUINT
Definition: ndis.h:50
#define TRUETYPE_FONTTYPE
Definition: wingdi.h:1109
#define DBGFNT1
Definition: font.c:22
#define IsAdditionalTTFontCP(FaceName, CodePage)
Definition: font.h:171
_Success_(return)
Retrieves the cell size for a console font.
Definition: font.c:686
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22