ReactOS 0.4.15-dev-7958-gcd0bb1a
font.c File Reference
#include "precomp.h"
#include <winuser.h>
#include "settings.h"
#include "font.h"
#include <debug.h>
Include dependency graph for font.c:

Go to the source code of this file.

Classes

struct  _FIND_SUITABLE_FONT_PROC_PARAM
 
struct  _IS_VALID_CONSOLE_FONT_PARAM
 

Macros

#define NDEBUG
 
#define DBGFNT   DPRINT
 
#define DBGFNT1   DPRINT1
 
#define TERMINAL_FACENAME   L"Terminal"
 
#define DEFAULT_NON_DBCS_FONTFACE   L"Lucida Console"
 
#define DEFAULT_TT_FONT_FACENAME   L"__DefaultTTFont__"
 
#define TM_IS_TT_FONT(x)   (((x) & TMPF_TRUETYPE) == TMPF_TRUETYPE)
 
#define SIZE_EQUAL(s1, s2)   (((s1).X == (s2).X) && ((s1).Y == (s2).Y))
 

Typedefs

typedef struct _FIND_SUITABLE_FONT_PROC_PARAM FIND_SUITABLE_FONT_PROC_PARAM
 
typedef struct _FIND_SUITABLE_FONT_PROC_PARAMPFIND_SUITABLE_FONT_PROC_PARAM
 
typedef struct _IS_VALID_CONSOLE_FONT_PARAM IS_VALID_CONSOLE_FONT_PARAM
 
typedef struct _IS_VALID_CONSOLE_FONT_PARAMPIS_VALID_CONSOLE_FONT_PARAM
 

Functions

BYTE CodePageToCharSet (_In_ UINT CodePage)
 Retrieves the character set associated with a given code page.
 
static BOOL CALLBACK FindSuitableFontProc (_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ LPARAM lParam)
 EnumFontFamiliesEx() callback helper for FindSuitableFont().
 
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 provided in input.
 
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.
 
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.
 
HFONT CreateConsoleFont2 (_In_ LONG Height, _In_opt_ LONG Width, _Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
 A wrapper for CreateConsoleFontEx().
 
HFONT CreateConsoleFont (_Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
 A wrapper for CreateConsoleFontEx().
 
 _Success_ (return)
 Retrieves the cell size for a console font.
 
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.
 
static BOOL CALLBACK IsValidConsoleFontProc (_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ LPARAM lParam)
 EnumFontFamiliesEx() callback helper for IsValidConsoleFont().
 
BOOL IsValidConsoleFont (_In_ PCWSTR FaceName, _In_ UINT CodePage)
 Validates whether a given font can be supported in the console, under the specified code page.
 
VOID InitTTFontCache (VOID)
 Initializes the console TrueType font cache.
 
VOID ClearTTFontCache (VOID)
 Clears the console TrueType font cache.
 
VOID RefreshTTFontCache (VOID)
 Refreshes the console TrueType font cache, by clearing and re-initializing it.
 
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.
 

Variables

SINGLE_LIST_ENTRY TTFontCache = { NULL }
 

Macro Definition Documentation

◆ DBGFNT

#define DBGFNT   DPRINT

Definition at line 21 of file font.c.

◆ DBGFNT1

#define DBGFNT1   DPRINT1

Definition at line 22 of file font.c.

◆ DEFAULT_NON_DBCS_FONTFACE

#define DEFAULT_NON_DBCS_FONTFACE   L"Lucida Console"

Definition at line 28 of file font.c.

◆ DEFAULT_TT_FONT_FACENAME

#define DEFAULT_TT_FONT_FACENAME   L"__DefaultTTFont__"

Definition at line 29 of file font.c.

◆ NDEBUG

#define NDEBUG

Definition at line 18 of file font.c.

◆ SIZE_EQUAL

#define SIZE_EQUAL (   s1,
  s2 
)    (((s1).X == (s2).X) && ((s1).Y == (s2).Y))

Definition at line 78 of file font.c.

◆ TERMINAL_FACENAME

#define TERMINAL_FACENAME   L"Terminal"

Definition at line 27 of file font.c.

◆ TM_IS_TT_FONT

#define TM_IS_TT_FONT (   x)    (((x) & TMPF_TRUETYPE) == TMPF_TRUETYPE)

Definition at line 77 of file font.c.

Typedef Documentation

◆ FIND_SUITABLE_FONT_PROC_PARAM

◆ IS_VALID_CONSOLE_FONT_PARAM

◆ PFIND_SUITABLE_FONT_PROC_PARAM

◆ PIS_VALID_CONSOLE_FONT_PARAM

Function Documentation

◆ _Success_()

_Success_ ( return  )

Retrieves the cell size for a console font.

Parameters
[in,opt]hDC An optional GDI device context handle.
[in]hFontThe GDI handle to the font.
[out]HeightIn case of success, receives the cell height size (in pixels).
[out]WidthIn case of success, receives the cell height size (in pixels).
Returns
TRUE if success, FALSE in case of failure.

Definition at line 686 of file font.c.

693{
695 HDC hOrgDC = hDC;
696 HFONT hOldFont;
697 // LONG LogSize, PointSize;
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
744 *Width = (UINT)CharWidth;
745 Success = TRUE;
746
747Cleanup:
748 SelectObject(hDC, hOldFont);
749Quit:
750 if (!hOrgDC)
752
753 return Success;
754}
static HDC hDC
Definition: 3dtext.c:33
HFONT hFont
Definition: main.c:53
static int CharWidth
Definition: carets.c:7
static int CharHeight
Definition: carets.c:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
static HDC
Definition: imagelist.c:92
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
Definition: time.h:68
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
#define DBGFNT1
Definition: font.c:22
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define LOGPIXELSY
Definition: wingdi.h:719
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)

◆ ClearTTFontCache()

VOID ClearTTFontCache ( VOID  )

Clears the console TrueType font cache.

Returns
None.

Definition at line 1131 of file font.c.

1132{
1134 PTT_FONT_ENTRY FontEntry;
1135
1136 while (TTFontCache.Next != NULL)
1137 {
1140 RtlFreeHeap(RtlGetProcessHeap(), 0, FontEntry);
1141 }
1143}
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
base of all file and directory entries
Definition: entries.h:83
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: font.h:36
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
SINGLE_LIST_ENTRY TTFontCache
Definition: font.c:32
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:240

Referenced by InitApplet(), and RefreshTTFontCache().

◆ CodePageToCharSet()

BYTE CodePageToCharSet ( _In_ UINT  CodePage)

Retrieves the character set associated with a given code page.

Parameters
[in]CodePageThe code page to convert.
Returns
The character set corresponding to the code page, or DEFAULT_CHARSET.

Definition at line 51 of file font.c.

53{
54 CHARSETINFO CharInfo;
55 if (TranslateCharsetInfo(UlongToPtr(CodePage), &CharInfo, TCI_SRCCODEPAGE))
56 return (BYTE)CharInfo.ciCharset;
57 else
58 return DEFAULT_CHARSET;
59}
#define UlongToPtr(u)
Definition: config.h:106
UINT ciCharset
Definition: wingdi.h:1546
#define DEFAULT_CHARSET
Definition: wingdi.h:384
BOOL WINAPI TranslateCharsetInfo(_Inout_ PDWORD, _Out_ LPCHARSETINFO, _In_ DWORD)
#define TCI_SRCCODEPAGE
Definition: wingdi.h:962
unsigned char BYTE
Definition: xxhash.c:193

Referenced by CON_API(), CreateConsoleFontWorker(), FindSuitableFont(), and IsValidConsoleFont().

◆ CreateConsoleFont()

HFONT CreateConsoleFont ( _Inout_ PCONSOLE_STATE_INFO  ConsoleInfo)

A wrapper for CreateConsoleFontEx().

Parameters
[in,out]ConsoleInfoA pointer to console settings information, containing in particular (in input) the face name and characteristics of the font to create with the current console code page. In output, the font information gets updated. Note that a default fallback font is always being used in case neither the specified font nor any substitute font could be found and created for the specified code page.
Returns
A GDI handle to the created font, or NULL in case of failure.
See also
CreateConsoleFontEx(), CreateConsoleFont2()

Definition at line 653 of file font.c.

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,
665}
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
uint32_t ULONG
Definition: typedefs.h:59
HFONT CreateConsoleFont2(_In_ LONG Height, _In_opt_ LONG Width, _Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
A wrapper for CreateConsoleFontEx().
Definition: font.c:609

Referenced by RefreshFontPreview().

◆ CreateConsoleFont2()

HFONT CreateConsoleFont2 ( _In_ LONG  Height,
_In_opt_ LONG  Width,
_Inout_ PCONSOLE_STATE_INFO  ConsoleInfo 
)

A wrapper for CreateConsoleFontEx().

Parameters
[in]HeightThe font height in cell units (pixels).
[in,opt]Width The font width in cell units (pixels).
[in,out]ConsoleInfoA pointer to console settings information, containing in particular (in input) the face name and characteristics of the font to create with the current console code page. In output, the font information gets updated. Note that a default fallback font is always being used in case neither the specified font nor any substitute font could be found and created for the specified code page.
Returns
A GDI handle to the created font, or NULL in case of failure.
See also
CreateConsoleFontEx(), CreateConsoleFont()

Definition at line 609 of file font.c.

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}
ULONG Family
Definition: font.h:56
ULONG Weight
Definition: font.h:55
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

Referenced by CreateConsoleFont(), and FontSizeChange().

◆ CreateConsoleFontEx()

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.

Parameters
[in]HeightThe font height in cell units (pixels).
[in,opt]Width The font width in cell units (pixels).
[in,out]FaceNameA pointer to a maximally LF_FACESIZE-sized buffer. In input: The buffer contains the face name of the font to try to create. In output: The buffer receives the face name of the font that has been created, in case of success. It may, or may not be, identical to the face name provided in input, in case a substitute font has been chosen.
[in]FontWeightThe font weight.
[in]FontFamilyThe font family.
[in]CodePageThe code page the font has to support.
[in]UseDefaultFallbackWhether (TRUE) or not (FALSE) to use a default fallback font in case neither the specified font nor any substitute font could be found and created for the specified code page.
[out]FontDataThe face name and characteristics of the created font.
Returns
A GDI handle to the created font, or NULL in case of failure.
Remarks
Similar to FindCreateFont() https://github.com/microsoft/terminal/blob/main/src/propsheet/fontdlg.cpp#L1113 but:
  • does not support an internal font cache for now;
  • returns a font handle (and not a font index to the cache).

Definition at line 505 of file font.c.

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}
#define IsCJKCodePage(CodePage)
Definition: cjkcode.h:27
#define LF_FACESIZE
Definition: dimm.idl:39
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define TERMINAL_FACENAME
Definition: font.c:27
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
#define DEFAULT_TT_FONT_FACENAME
Definition: font.c:29
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
#define ANSI_CHARSET
Definition: wingdi.h:383

Referenced by CreateConsoleFont2(), and InitFonts().

◆ CreateConsoleFontWorker()

static HFONT CreateConsoleFontWorker ( _In_ PFONT_DATA  FontData,
_In_ UINT  CodePage 
)
static

Validates and creates a suitable console font based on the font characteristics given in input.

Parameters
[in]FontDataThe face name and characteristics of the font to create.
[in]CodePageThe code page the font has to support.
Returns
A GDI handle to the created font, or NULL in case of failure.

Definition at line 424 of file font.c.

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}
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
BYTE lfOutPrecision
Definition: dimm.idl:68
LONG lfHeight
Definition: dimm.idl:59
LONG lfWeight
Definition: dimm.idl:63
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
LONG lfOrientation
Definition: dimm.idl:62
LONG lfWidth
Definition: dimm.idl:60
BYTE lfClipPrecision
Definition: dimm.idl:69
LONG lfEscapement
Definition: dimm.idl:61
BYTE lfCharSet
Definition: dimm.idl:67
BYTE lfQuality
Definition: dimm.idl:70
BYTE lfPitchAndFamily
Definition: dimm.idl:71
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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
BYTE CodePageToCharSet(_In_ UINT CodePage)
Retrieves the character set associated with a given code page.
Definition: font.c:51
#define FIXED_PITCH
Definition: wingdi.h:444
#define VARIABLE_PITCH
Definition: wingdi.h:445
#define FF_MODERN
Definition: wingdi.h:449
#define FF_DECORATIVE
Definition: wingdi.h:447
#define FF_SCRIPT
Definition: wingdi.h:451
#define FF_ROMAN
Definition: wingdi.h:450
#define DEFAULT_QUALITY
Definition: wingdi.h:436
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:415
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
#define FF_SWISS
Definition: wingdi.h:452

Referenced by CreateConsoleFontEx().

◆ FindCachedTTFont()

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.

Parameters
[in,opt]FaceName An optional pointer to a maximally LF_FACESIZE-sized buffer. The buffer contains the face name of the font to search for.
  • If FaceName != NULL, search for the named font that should match the provided code page (when CodePage != INVALID_CP).
  • If FaceName == NULL, search for a font with the provided code page. In this case, CodePage cannot be == INVALID_CP, otherwise the search fails.
Parameters
[in]CodePageThe code page the font has to support, or INVALID_CP when searching a font by face name only.
Returns
A pointer to the cache entry for the font, or NULL if not found.

Definition at line 1183 of file font.c.

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 {
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 {
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}
#define INVALID_CP
Definition: stream.h:53
WCHAR FaceName[LF_FACESIZE]
Definition: font.h:40
UINT CodePage
Definition: font.h:38
WCHAR FaceNameAlt[LF_FACESIZE]
Definition: font.h:41

Referenced by FindSuitableFont().

◆ FindSuitableFont()

static BOOL FindSuitableFont ( _Inout_ PFONT_DATA  FontData,
_In_ UINT  CodePage 
)
static

Finds a font suitable for the given code page, based on the current font and its characteristics provided in input.

Parameters
[in,out]FontDataIn input: The face name and characteristics of the font to search for, possibly getting a best match. In output: The face name and characteristics of the suitable font, in case of success.
[in]CodePageThe code page the font has to support.
Returns
TRUE in case a suitable font has been found. Its name and characteristics are returned in FontData. FALSE if no suitable font has been found.

Definition at line 307 of file font.c.

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;
375SearchAgain:
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);
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.
403 Param.CandidateFaceName,
404 ARRAYSIZE(Param.CandidateFaceName));
405
406 return TRUE;
407}
#define _Inout_updates_z_(size)
Definition: ms_sal.h:389
uint16_t * PWSTR
Definition: typedefs.h:56
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
#define DEFAULT_NON_DBCS_FONTFACE
Definition: font.c:28
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
LONG_PTR LPARAM
Definition: windef.h:208
int WINAPI EnumFontFamiliesExW(_In_ HDC, _In_ PLOGFONTW, _In_ FONTENUMPROCW, _In_ LPARAM, _In_ DWORD)
FARPROC FONTENUMPROCW
Definition: wingdi.h:2897
#define TMPF_TRUETYPE
Definition: wingdi.h:1313

Referenced by CreateConsoleFontEx().

◆ FindSuitableFontProc()

static BOOL CALLBACK FindSuitableFontProc ( _In_ PLOGFONTW  lplf,
_In_ PNEWTEXTMETRICW  lpntm,
_In_ DWORD  FontType,
_In_ LPARAM  lParam 
)
static

EnumFontFamiliesEx() callback helper for FindSuitableFont().

Remarks
It implements a nearly-identical console-suitable font search algorithm based on the one from FindCreateFont() https://github.com/microsoft/terminal/blob/main/src/propsheet/fontdlg.cpp#L1113 excepting that for now, it does not support an internal font cache.

Definition at line 90 of file font.c.

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}
LPARAM lParam
Definition: combotst.c:139
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
#define ASSERT(a)
Definition: mode.c:44
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
BYTE CharSet
Definition: font.h:58
COORD Size
Definition: font.h:57
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define SIZE_EQUAL(s1, s2)
Definition: font.c:78
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
struct _FIND_SUITABLE_FONT_PROC_PARAM * PFIND_SUITABLE_FONT_PROC_PARAM
#define TRUETYPE_FONTTYPE
Definition: wingdi.h:1109
#define OEM_CHARSET
Definition: wingdi.h:400
#define FW_NORMAL
Definition: wingdi.h:373

Referenced by FindSuitableFont().

◆ InitTTFontCache()

VOID InitTTFontCache ( VOID  )

Initializes the console TrueType font cache.

Remarks
To install additional TrueType fonts to be available for the console, add entries of type REG_SZ named "0", "00" etc... in: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont The names of the fonts listed there should match those in: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts
Returns
None.

Definition at line 1013 of file font.c.

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 */
1122}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
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:2830
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define UNICODE_NULL
BYTE * PBYTE
Definition: pedump.c:66
BOOL DisableBold
Definition: font.h:39
SINGLE_LIST_ENTRY Entry
Definition: font.h:37
uint16_t * PWCHAR
Definition: typedefs.h:56
#define BOLD_MARK
Definition: font.h:33
LONG_PTR LRESULT
Definition: windef.h:209
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:253
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by GuiInit(), InitApplet(), and RefreshTTFontCache().

◆ IsValidConsoleFont()

BOOL IsValidConsoleFont ( _In_ PCWSTR  FaceName,
_In_ UINT  CodePage 
)

Validates whether a given font can be supported in the console, under the specified code page.

Parameters
[in]FaceNameThe face name of the font to validate.
[in]CodePageThe code page the font has to support.
Returns
TRUE if the font is valid and supported in the console, FALSE if not.
See also
IsValidConsoleFont2()

Definition at line 974 of file font.c.

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;
990
991 hDC = GetDC(NULL);
994
995 return Param.IsValidFont;
996}
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

Referenced by CreateConsoleFontWorker().

◆ IsValidConsoleFont2()

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.

Parameters
[in]lplf
[in]lpntm
[in]FontTypeThe GDI font characteristics of the font to validate.
[in]CodePageThe code page the font has to support.
Returns
TRUE if the font is valid and supported in the console, FALSE if not.
Remarks
Equivalent of the font validation tests in FontEnumForV2Console() (or the more restrictive ones in FontEnum()) https://github.com/microsoft/terminal/blob/main/src/propsheet/misc.cpp#L465 https://github.com/microsoft/terminal/blob/main/src/propsheet/misc.cpp#L607
See also
IsValidConsoleFont()

Definition at line 782 of file font.c.

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}
#define IsCJKCharSet(CharSet)
Definition: cjkcode.h:44
#define IsAdditionalTTFontCP(FaceName, CodePage)
Definition: font.h:134
#define IsAdditionalTTFont(FaceName)
Verifies whether the given font is an additional console TrueType font. Wrapper macros around FindCac...
Definition: font.h:131
#define DBGFNT
Definition: font.c:21
#define NTM_NONNEGATIVE_AC
Definition: wingdi.h:25
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by EnumFaceNamesProc(), FindSuitableFontProc(), and IsValidConsoleFontProc().

◆ IsValidConsoleFontProc()

static BOOL CALLBACK IsValidConsoleFontProc ( _In_ PLOGFONTW  lplf,
_In_ PNEWTEXTMETRICW  lpntm,
_In_ DWORD  FontType,
_In_ LPARAM  lParam 
)
static

EnumFontFamiliesEx() callback helper for IsValidConsoleFont().

Definition at line 943 of file font.c.

948{
950 Param->IsValidFont = IsValidConsoleFont2(lplf, lpntm, FontType, Param->CodePage);
951
952 /* Stop the enumeration now */
953 return FALSE;
954}
struct _IS_VALID_CONSOLE_FONT_PARAM * PIS_VALID_CONSOLE_FONT_PARAM

Referenced by IsValidConsoleFont().

◆ RefreshTTFontCache()

VOID RefreshTTFontCache ( VOID  )

Refreshes the console TrueType font cache, by clearing and re-initializing it.

Returns
None.

Definition at line 1153 of file font.c.

1154{
1157}
VOID InitTTFontCache(VOID)
Initializes the console TrueType font cache.
Definition: font.c:1013
VOID ClearTTFontCache(VOID)
Clears the console TrueType font cache.
Definition: font.c:1131

Referenced by GuiApplyUserSettings().

Variable Documentation

◆ TTFontCache

SINGLE_LIST_ENTRY TTFontCache = { NULL }

Definition at line 32 of file font.c.

Referenced by ClearTTFontCache(), FindCachedTTFont(), and InitTTFontCache().