22#define DBGFNT1 DPRINT1
27#define TERMINAL_FACENAME L"Terminal"
28#define DEFAULT_NON_DBCS_FONTFACE L"Lucida Console"
29#define DEFAULT_TT_FONT_FACENAME L"__DefaultTTFont__"
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))
105#ifndef FONT_CACHE_PRESENT
115 lplf->lfHeight = SearchFont->
Size.
Y;
121 if (Param->StrictSearch)
128 if ((SearchFont->
Family != 0) &&
129 ((
BYTE)SearchFont->
Family != (lplf->lfPitchAndFamily & 0xF0)))
137 if ((FontInfo[
i].SizeWant.Y !=
Size.Y) &&
140 if ((lplf->lfHeight != SearchFont->
Size.
Y) &&
141 !(lplf->lfWidth == SearchFont->
Size.
X &&
142 lplf->lfHeight == SearchFont->
Size.
Y))
149 if ((SearchFont->
Weight != 0) &&
150 (SearchFont->
Weight != lplf->lfWeight))
161 (lplf->lfCharSet != SearchFont->
CharSet) &&
175 if (!SearchFont->FaceName || !*(SearchFont->FaceName) ||
176 (
wcscmp(lplf->lfFaceName, SearchFont->FaceName) == 0) ||
177 (
wcscmp(lplf->lfFaceName, Param->AltFaceName) == 0))
181 PFONT_DATA CandidateFont = &Param->CandidateFont;
183 CandidateFont->FaceName = Param->CandidateFaceName;
186 lplf->lfFaceName,
ARRAYSIZE(lplf->lfFaceName));
188 CandidateFont->
Weight = lplf->lfWeight;
189 CandidateFont->
Family = (lplf->lfPitchAndFamily & 0xF0);
191 CandidateFont->
Size.
X = lplf->lfWidth;
192 CandidateFont->
Size.
Y = lplf->lfHeight;
194 CandidateFont->
CharSet = lplf->lfCharSet;
197 Param->FontFound =
TRUE;
204 PFONT_DATA CandidateFont = &Param->CandidateFont;
206 CandidateFont->FaceName = Param->CandidateFaceName;
209 lplf->lfFaceName,
ARRAYSIZE(lplf->lfFaceName));
211 CandidateFont->
Weight = lplf->lfWeight;
212 CandidateFont->
Family = (lplf->lfPitchAndFamily & 0xF0);
214 CandidateFont->
Size.
X = lplf->lfWidth;
215 CandidateFont->
Size.
Y = lplf->lfHeight;
217 CandidateFont->
CharSet = lplf->lfCharSet;
221 Param->FontFound =
TRUE;
233 if ((SearchFont->
Family != 0) &&
234 ((
BYTE)SearchFont->
Family != (lplf->lfPitchAndFamily & 0xF0)))
241 (lplf->lfCharSet != SearchFont->
CharSet))
250 ((
BYTE)SearchFont->
Family != (lplf->lfPitchAndFamily & 0xF0)))
257 if ((lplf->lfHeight >= SearchFont->
Size.
Y) &&
258 (lplf->lfWidth >= SearchFont->
Size.
X))
263 PFONT_DATA CandidateFont = &Param->CandidateFont;
265 CandidateFont->FaceName = Param->CandidateFaceName;
268 lplf->lfFaceName,
ARRAYSIZE(lplf->lfFaceName));
270 CandidateFont->
Weight = lplf->lfWeight;
271 CandidateFont->
Family = (lplf->lfPitchAndFamily & 0xF0);
273 CandidateFont->
Size.
X = lplf->lfWidth;
274 CandidateFont->
Size.
Y = lplf->lfHeight;
276 CandidateFont->
CharSet = lplf->lfCharSet;
279 Param->FontFound =
TRUE;
322 Param.SearchFont = *FontData;
325 Param.CodePage = CodePage;
339 FontData->Family &= ~TMPF_TRUETYPE;
364 Param.AltFaceName = FontEntry->
FaceName;
368 Param.AltFaceName = FaceName;
372 Param.FontFound =
FALSE;
374 Param.StrictSearch =
TRUE;
389 if (Param.StrictSearch && !Param.FontFound)
391 Param.StrictSearch =
FALSE;
396 if (!Param.FontFound)
400 *FontData = Param.CandidateFont;
401 FontData->FaceName = FaceName;
403 Param.CandidateFaceName,
518 FontData->FaceName = FaceName;
519 FontData->Weight = FontWeight;
522 FontData->Size.X =
Width;
523 FontData->Size.Y =
Height;
524 FontData->CharSet = 0;
537 DBGFNT1(
"CreateConsoleFont('%S') failed - Try to find a suitable font...\n",
549 DBGFNT1(
"FindSuitableFont could not find anything - %s\n",
550 UseDefaultFallback ?
"Falling back to 'Terminal'"
554 if (!UseDefaultFallback)
568 FontData->Family &= ~TMPF_TRUETYPE;
572 DBGFNT1(
"FindSuitableFont found: '%S', size (%d x %d)\n",
573 FaceName, FontData->Size.X, FontData->Size.Y);
579 DBGFNT1(
"CreateConsoleFont('%S') failed\n", FaceName);
706 if (hOldFont ==
NULL)
708 DBGFNT1(
"GetFontCellSize: SelectObject failed\n");
722 DBGFNT1(
"GetFontCellSize: GetTextMetrics failed\n");
738 LogSize =
tm.tmHeight -
tm.tmInternalLeading;
788 LPCWSTR FaceName = lplf->lfFaceName;
827 if ( ( ((lplf->lfPitchAndFamily & 0x03) !=
FIXED_PITCH)
836 DBGFNT(
"Font '%S' rejected because it%s (lfPitchAndFamily = %d)\n",
838 !(lplf->lfPitchAndFamily &
FIXED_PITCH) ?
"'s not FIXED_PITCH"
841 lplf->lfPitchAndFamily);
848 DBGFNT(
"TrueType font '%S' rejected because it's not FF_MODERN (lfPitchAndFamily = %d)\n",
849 FaceName, lplf->lfPitchAndFamily);
854 if (FaceName[0] ==
L'@')
856 DBGFNT(
"Font '%S' rejected because it's vertical\n", FaceName);
873 DBGFNT(
"TrueType font '%S' rejected because it's not Asian charset (lfCharSet = %d)\n",
874 FaceName, lplf->lfCharSet);
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);
900 DBGFNT(
"Non-TrueType font '%S' rejected because it's not Asian charset or OEM_CHARSET (lfCharSet = %d)\n",
901 FaceName, lplf->lfCharSet);
908 DBGFNT(
"Non-TrueType font '%S' rejected because it's not 'Terminal'\n", FaceName);
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);
1017 DWORD dwIndex, dwType;
1033 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont",
1042 for (dwIndex = 0, cchValueName =
ARRAYSIZE(szValueName),
1043 cbValue =
sizeof(szValue);
1045 szValueName, &cchValueName,
1048 ++dwIndex, cchValueName =
ARRAYSIZE(szValueName),
1049 cbValue =
sizeof(szValue))
1068 CodePage =
wcstoul(szValueName, &pszNext, 10);
1076 DBGFNT1(
"InitTTFontCache: Failed to allocate memory, continuing...\n");
1097 pszNext,
wcslen(pszNext));
1102 pszNext +=
wcslen(pszNext) + 1;
1114 pszNext,
wcslen(pszNext));
1222 if (CodePage == FontEntry->
CodePage)
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
#define RegCloseKey(hKey)
#define IsCJKCharSet(CharSet)
#define IsCJKCodePage(CodePage)
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
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)
#define ERROR_NO_MORE_ITEMS
static const WCHAR Cleanup[]
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
_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)
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define _In_reads_or_z_(size)
#define _In_reads_or_z_opt_(size)
#define _Inout_updates_z_(size)
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
_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)
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
base of all file and directory entries
WCHAR lfFaceName[LF_FACESIZE]
struct _SINGLE_LIST_ENTRY * Next
WCHAR FaceName[LF_FACESIZE]
WCHAR FaceNameAlt[LF_FACESIZE]
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
#define IsAdditionalTTFontCP(FaceName, CodePage)
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
_In_ HFONT _Out_ PUINT Height
#define IsAdditionalTTFont(FaceName)
Verifies whether the given font is an additional console TrueType font. Wrapper macros around FindCac...
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
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.
#define SIZE_EQUAL(s1, s2)
HFONT CreateConsoleFont(_Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
A wrapper for CreateConsoleFontEx().
VOID InitTTFontCache(VOID)
Initializes the console TrueType font cache.
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().
struct _FIND_SUITABLE_FONT_PROC_PARAM FIND_SUITABLE_FONT_PROC_PARAM
#define TERMINAL_FACENAME
SINGLE_LIST_ENTRY TTFontCache
struct _IS_VALID_CONSOLE_FONT_PARAM IS_VALID_CONSOLE_FONT_PARAM
struct _FIND_SUITABLE_FONT_PROC_PARAM * PFIND_SUITABLE_FONT_PROC_PARAM
#define DEFAULT_NON_DBCS_FONTFACE
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.
BOOL IsValidConsoleFont(_In_ PCWSTR FaceName, _In_ UINT CodePage)
Validates whether a given font can be supported in the console, under the specified code page.
HFONT CreateConsoleFont2(_In_ LONG Height, _In_opt_ LONG Width, _Inout_ PCONSOLE_STATE_INFO ConsoleInfo)
A wrapper for CreateConsoleFontEx().
#define DEFAULT_TT_FONT_FACENAME
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...
BYTE CodePageToCharSet(_In_ UINT CodePage)
Retrieves the character set associated with a given code page.
VOID ClearTTFontCache(VOID)
Clears the console TrueType font cache.
struct _IS_VALID_CONSOLE_FONT_PARAM * PIS_VALID_CONSOLE_FONT_PARAM
VOID RefreshTTFontCache(VOID)
Refreshes the console TrueType font cache, by clearing and re-initializing it.
static BOOL CALLBACK FindSuitableFontProc(_In_ PLOGFONTW lplf, _In_ PNEWTEXTMETRICW lpntm, _In_ DWORD FontType, _In_ LPARAM lParam)
EnumFontFamiliesEx() callback helper for FindSuitableFont().
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI EnumFontFamiliesExW(_In_ HDC, _In_ PLOGFONTW, _In_ FONTENUMPROCW, _In_ LPARAM, _In_ DWORD)
#define TRUETYPE_FONTTYPE
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
#define OUT_DEFAULT_PRECIS
#define CLIP_DEFAULT_PRECIS
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
BOOL WINAPI TranslateCharsetInfo(_Inout_ PDWORD, _Out_ LPCHARSETINFO, _In_ DWORD)
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define NTM_NONNEGATIVE_AC
#define HKEY_LOCAL_MACHINE
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)