mirror of
https://github.com/reactos/reactos.git
synced 2025-02-20 15:35:04 +00:00
[CONSOLE][CONCFG][CONSRV] Provide support for specified additional TrueType fonts + bugfixes.
CORE-12451 CORE-13182 CORE-13196 - CONSOLE: Initialize the additional TrueType fonts cache. * Fix the font preview when a TrueType font has been selected. * Refresh the available fonts and the font preview when the selected code page is changed (Work In Progress), or when the OS pool of font resources has changed (WM_FONTCHANGE message). - CONCFG: Implement support for the additional TrueType fonts cache: the contents of the cache is enumerated under the registry key HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont * Add helper functions and macros. * In CreateConsoleFontEx(), set the mandatory font pitch&family flags and remove those that we do not support. * In IsValidConsoleFont2(), update the validity checks and the documentation links. - CONSRV: Load/refresh the additional TrueType fonts cache when needed.
This commit is contained in:
parent
73d7fd1415
commit
c4e2826c73
11 changed files with 497 additions and 108 deletions
|
@ -227,11 +227,9 @@ InitApplet(HANDLE hSectionOrWnd)
|
|||
InitDefaultConsoleInfo(ConInfo);
|
||||
}
|
||||
|
||||
/* Initialize the font support */
|
||||
FontPreview.hFont = CreateConsoleFont(ConInfo);
|
||||
if (FontPreview.hFont == NULL)
|
||||
DPRINT1("InitApplet: CreateConsoleFont() failed\n");
|
||||
GetFontCellSize(NULL, FontPreview.hFont, &FontPreview.CharHeight, &FontPreview.CharWidth);
|
||||
/* Initialize the font support -- additional TrueType fonts cache and current preview font */
|
||||
InitTTFontCache();
|
||||
RefreshFontPreview(&FontPreview, ConInfo);
|
||||
|
||||
/* Initialize the property sheet structure */
|
||||
ZeroMemory(&psh, sizeof(psh));
|
||||
|
@ -274,8 +272,8 @@ InitApplet(HANDLE hSectionOrWnd)
|
|||
UnRegisterWinPrevClass(hApplet);
|
||||
|
||||
/* Clear the font support */
|
||||
if (FontPreview.hFont) DeleteObject(FontPreview.hFont);
|
||||
FontPreview.hFont = NULL;
|
||||
ResetFontPreview(&FontPreview);
|
||||
ClearTTFontCache();
|
||||
|
||||
/* Save the console settings */
|
||||
if (SetConsoleInfo)
|
||||
|
|
|
@ -49,6 +49,23 @@ extern FONT_PREVIEW FontPreview;
|
|||
|
||||
VOID ApplyConsoleInfo(HWND hwndDlg);
|
||||
|
||||
|
||||
VOID
|
||||
RefreshFontPreview(
|
||||
IN FONT_PREVIEW* Preview,
|
||||
IN PCONSOLE_STATE_INFO pConInfo);
|
||||
|
||||
VOID
|
||||
UpdateFontPreview(
|
||||
IN FONT_PREVIEW* Preview,
|
||||
IN HFONT hFont,
|
||||
IN UINT CharWidth,
|
||||
IN UINT CharHeight);
|
||||
|
||||
#define ResetFontPreview(Preview) \
|
||||
UpdateFontPreview((Preview), NULL, 0, 0)
|
||||
|
||||
|
||||
/* Preview Windows */
|
||||
BOOL
|
||||
RegisterWinPrevClass(
|
||||
|
|
|
@ -45,6 +45,31 @@ static INT CurrentSelFont = LB_ERR;
|
|||
static DWORD CurrentFontType = (DWORD)-1; // Invalid font type
|
||||
|
||||
|
||||
VOID
|
||||
RefreshFontPreview(
|
||||
IN FONT_PREVIEW* Preview,
|
||||
IN PCONSOLE_STATE_INFO pConInfo)
|
||||
{
|
||||
if (Preview->hFont) DeleteObject(Preview->hFont);
|
||||
Preview->hFont = CreateConsoleFont(pConInfo);
|
||||
if (Preview->hFont == NULL)
|
||||
DPRINT1("RefreshFontPreview: CreateConsoleFont() failed\n");
|
||||
GetFontCellSize(NULL, Preview->hFont, &Preview->CharHeight, &Preview->CharWidth);
|
||||
}
|
||||
|
||||
VOID
|
||||
UpdateFontPreview(
|
||||
IN FONT_PREVIEW* Preview,
|
||||
IN HFONT hFont,
|
||||
IN UINT CharWidth,
|
||||
IN UINT CharHeight)
|
||||
{
|
||||
if (Preview->hFont) DeleteObject(Preview->hFont);
|
||||
Preview->hFont = hFont;
|
||||
Preview->CharWidth = CharWidth;
|
||||
Preview->CharHeight = CharHeight;
|
||||
}
|
||||
|
||||
// PLIST_GETCOUNT
|
||||
static INT
|
||||
RasterSizeList_GetCount(
|
||||
|
@ -284,13 +309,6 @@ EnumFaceNamesProc(
|
|||
{
|
||||
PFACE_NAMES_PROC_PARAM Param = (PFACE_NAMES_PROC_PARAM)lParam;
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
if (IsValidConsoleFont2(lplf, lpntm, FontType, Param->CodePage))
|
||||
{
|
||||
/* Add the font to the list */
|
||||
|
@ -374,7 +392,7 @@ FaceNameList_Initialize(
|
|||
|
||||
ZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(CodePage);
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
|
||||
|
||||
hDC = GetDC(NULL);
|
||||
EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFaceNamesProc, (LPARAM)&Param, 0);
|
||||
|
@ -397,9 +415,14 @@ FaceNameList_Initialize(
|
|||
}
|
||||
|
||||
static VOID
|
||||
FaceNameList_SelectFaceName(
|
||||
FaceNameList_SelectFont(
|
||||
IN HWND hDlg,
|
||||
IN HWND hWndList,
|
||||
IN LPCWSTR FaceName)
|
||||
IN PFONTSIZE_LIST_CTL SizeList,
|
||||
IN LPCWSTR FaceName,
|
||||
IN ULONG FontFamily,
|
||||
IN ULONG FontWeight,
|
||||
IN COORD FontSize)
|
||||
{
|
||||
INT iItem;
|
||||
|
||||
|
@ -410,6 +433,21 @@ FaceNameList_SelectFaceName(
|
|||
iItem = 0;
|
||||
SendMessageW(hWndList, LB_SETCURSEL, (WPARAM)iItem, 0);
|
||||
|
||||
if (FontWeight >= FW_BOLD)
|
||||
CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_CHECKED);
|
||||
else
|
||||
CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_UNCHECKED);
|
||||
|
||||
/* Select the current font size */
|
||||
/*
|
||||
* Format:
|
||||
* Width = FontSize.X = LOWORD(FontSize);
|
||||
* Height = FontSize.Y = HIWORD(FontSize);
|
||||
*/
|
||||
SizeList->CurrentRasterSize = MAKELONG(FontSize.X, FontSize.Y);
|
||||
SizeList->CurrentTTSize = FontSize.Y;
|
||||
// FontSizeList_SelectFontSize(SizeList, SizeList->CurrentRasterSize);
|
||||
|
||||
// return iItem;
|
||||
}
|
||||
|
||||
|
@ -486,7 +524,6 @@ FontTypeChange(
|
|||
{
|
||||
HWND hListBox = GetDlgItem(hDlg, IDC_LBOX_FONTTYPE);
|
||||
INT Length, nSel;
|
||||
LOGFONTW lf;
|
||||
LPWSTR FaceName;
|
||||
DWORD FontType;
|
||||
LPCWSTR FontGrpBoxLabelTpl = NULL;
|
||||
|
@ -518,12 +555,7 @@ FontTypeChange(
|
|||
FaceName[Length] = L'\0';
|
||||
|
||||
StringCchCopyW(pConInfo->FaceName, ARRAYSIZE(pConInfo->FaceName), FaceName);
|
||||
DPRINT1("pConInfo->FaceName = '%S'\n", pConInfo->FaceName);
|
||||
|
||||
ZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(pConInfo->CodePage);
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
|
||||
StringCchCopyW(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FaceName);
|
||||
DPRINT("pConInfo->FaceName = '%S'\n", pConInfo->FaceName);
|
||||
|
||||
/*
|
||||
* Retrieve the read-only font group box label string template,
|
||||
|
@ -560,6 +592,7 @@ FontTypeChange(
|
|||
if ((CurrentFontType != FontType) ||
|
||||
(FontType == RASTER_FONTTYPE && CurrentSelFont != nSel))
|
||||
{
|
||||
LOGFONTW lf;
|
||||
HDC hDC;
|
||||
|
||||
if (SizeList->UseRasterOrTTList)
|
||||
|
@ -567,6 +600,11 @@ FontTypeChange(
|
|||
else
|
||||
SendMessageW(SizeList->hWndTTSizeList, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
ZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(pConInfo->CodePage);
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
|
||||
StringCchCopyW(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), pConInfo->FaceName);
|
||||
|
||||
hDC = GetDC(NULL);
|
||||
EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFontSizesProc, (LPARAM)SizeList, 0);
|
||||
ReleaseDC(NULL, hDC);
|
||||
|
@ -597,7 +635,9 @@ FontSizeChange(
|
|||
IN PFONTSIZE_LIST_CTL SizeList,
|
||||
IN OUT PCONSOLE_STATE_INFO pConInfo)
|
||||
{
|
||||
LONG FontSize, CharWidth, CharHeight;
|
||||
LONG FontSize;
|
||||
UINT CharWidth, CharHeight;
|
||||
HFONT hFont;
|
||||
WCHAR szFontSize[100];
|
||||
|
||||
/*
|
||||
|
@ -610,35 +650,44 @@ FontSizeChange(
|
|||
if (FontSize == 0)
|
||||
return FALSE; // We have got an invalid font size...
|
||||
|
||||
CharHeight = (SizeList->UseRasterOrTTList ? (LONG)HIWORD(FontSize) : FontSize);
|
||||
CharWidth = (SizeList->UseRasterOrTTList ? (LONG)LOWORD(FontSize) : 0);
|
||||
/*
|
||||
* For TrueType fonts we set the requested width to zero
|
||||
* so as to obtain a default aspect-ratio width.
|
||||
*/
|
||||
CharHeight = (UINT)(SizeList->UseRasterOrTTList ? HIWORD(FontSize) : FontSize);
|
||||
CharWidth = (UINT)(SizeList->UseRasterOrTTList ? LOWORD(FontSize) : 0);
|
||||
|
||||
if (FontPreview.hFont) DeleteObject(FontPreview.hFont);
|
||||
FontPreview.hFont = CreateConsoleFont2(CharHeight, CharWidth, pConInfo);
|
||||
if (FontPreview.hFont == NULL)
|
||||
hFont = CreateConsoleFont2((LONG)CharHeight, (LONG)CharWidth, pConInfo);
|
||||
if (hFont == NULL)
|
||||
DPRINT1("FontSizeChange: CreateConsoleFont2() failed\n");
|
||||
|
||||
/* Retrieve the real character size in pixels */
|
||||
GetFontCellSize(NULL, FontPreview.hFont, &FontPreview.CharHeight, &FontPreview.CharWidth);
|
||||
GetFontCellSize(NULL, hFont, &CharHeight, &CharWidth);
|
||||
|
||||
/*
|
||||
* Update the font preview as well, and store the font handle. It will be
|
||||
* freed at later update or when the font preview is refreshed or reset.
|
||||
* For TrueType fonts, the preview will show the actual character width.
|
||||
*/
|
||||
UpdateFontPreview(&FontPreview, hFont, CharWidth, CharHeight);
|
||||
|
||||
/*
|
||||
* Format:
|
||||
* Width = FontSize.X = LOWORD(FontSize);
|
||||
* Height = FontSize.Y = HIWORD(FontSize);
|
||||
*/
|
||||
pConInfo->FontSize.X = (SHORT)(SizeList->UseRasterOrTTList ? FontPreview.CharWidth : 0);
|
||||
pConInfo->FontSize.Y = (SHORT)FontPreview.CharHeight;
|
||||
pConInfo->FontSize.X = (SHORT)(SizeList->UseRasterOrTTList ? CharWidth : 0);
|
||||
pConInfo->FontSize.Y = (SHORT)CharHeight;
|
||||
|
||||
DPRINT1("pConInfo->FontSize = (%d x %d) ; (CharWidth x CharHeight) = (%d x %d)\n",
|
||||
pConInfo->FontSize.X, pConInfo->FontSize.Y,
|
||||
FontPreview.CharWidth, FontPreview.CharHeight);
|
||||
DPRINT("pConInfo->FontSize = (%d x %d) ; (CharWidth x CharHeight) = (%d x %d)\n",
|
||||
pConInfo->FontSize.X, pConInfo->FontSize.Y, CharWidth, CharHeight);
|
||||
|
||||
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_FONT_WINDOW_PREVIEW), NULL, TRUE);
|
||||
InvalidateRect(GetDlgItem(hDlg, IDC_STATIC_SELECT_FONT_PREVIEW), NULL, TRUE);
|
||||
|
||||
StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", FontPreview.CharWidth);
|
||||
StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", CharWidth);
|
||||
SetDlgItemText(hDlg, IDC_FONT_SIZE_X, szFontSize);
|
||||
StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", FontPreview.CharHeight);
|
||||
StringCchPrintfW(szFontSize, ARRAYSIZE(szFontSize), L"%d", CharHeight);
|
||||
SetDlgItemText(hDlg, IDC_FONT_SIZE_Y, szFontSize);
|
||||
|
||||
return TRUE;
|
||||
|
@ -689,22 +738,12 @@ FontProc(HWND hDlg,
|
|||
|
||||
/* Select the current font */
|
||||
DPRINT1("ConInfo->FaceName = '%S'\n", ConInfo->FaceName);
|
||||
FaceNameList_SelectFaceName(hFontList, ConInfo->FaceName);
|
||||
|
||||
if (ConInfo->FontWeight >= FW_BOLD)
|
||||
CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_CHECKED);
|
||||
else
|
||||
CheckDlgButton(hDlg, IDC_CHECK_BOLD_FONTS, BST_UNCHECKED);
|
||||
|
||||
/* Select the current font size */
|
||||
/*
|
||||
* Format:
|
||||
* Width = FontSize.X = LOWORD(FontSize);
|
||||
* Height = FontSize.Y = HIWORD(FontSize);
|
||||
*/
|
||||
SizeList->CurrentRasterSize = MAKELONG(ConInfo->FontSize.X, ConInfo->FontSize.Y);
|
||||
SizeList->CurrentTTSize = ConInfo->FontSize.Y;
|
||||
// FontSizeList_SelectFontSize(SizeList, SizeList->CurrentRasterSize);
|
||||
FaceNameList_SelectFont(hDlg, hFontList,
|
||||
SizeList,
|
||||
ConInfo->FaceName,
|
||||
ConInfo->FontFamily,
|
||||
ConInfo->FontWeight,
|
||||
ConInfo->FontSize);
|
||||
|
||||
/* Refresh everything */
|
||||
FontTypeChange(hDlg, SizeList, ConInfo);
|
||||
|
@ -737,6 +776,42 @@ FontProc(HWND hDlg,
|
|||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
case PSM_QUERYSIBLINGS:
|
||||
{
|
||||
/*
|
||||
* If this is a notification from the "Options" dialog because we
|
||||
* changed the code page, treat it using the WM_FONTCHANGE case,
|
||||
* otherwise ignore it.
|
||||
*/
|
||||
if (wParam != IDL_CODEPAGE)
|
||||
return FALSE;
|
||||
|
||||
/* Fall through */
|
||||
}
|
||||
#endif
|
||||
|
||||
case WM_FONTCHANGE:
|
||||
{
|
||||
/* The pool of font resources has changed, re-enumerate the fonts */
|
||||
HWND hFontList = GetDlgItem(hDlg, IDC_LBOX_FONTTYPE);
|
||||
|
||||
/* Initialize the font list */
|
||||
FaceNameList_Initialize(hFontList, ConInfo->CodePage);
|
||||
|
||||
/* Select the current font */
|
||||
FaceNameList_SelectFont(hDlg, hFontList,
|
||||
SizeList,
|
||||
ConInfo->FaceName,
|
||||
ConInfo->FontFamily,
|
||||
ConInfo->FontWeight,
|
||||
ConInfo->FontSize);
|
||||
|
||||
/* Refresh everything */
|
||||
FontTypeChange(hDlg, SizeList, ConInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
switch (((LPNMHDR)lParam)->code)
|
||||
|
|
|
@ -203,6 +203,9 @@ WinPrev_OnDraw(
|
|||
* Compute the console window layout
|
||||
*/
|
||||
|
||||
if (FontPreview.hFont == NULL)
|
||||
RefreshFontPreview(&FontPreview, pConInfo);
|
||||
|
||||
/* We start with the console client area, rescaled for the preview */
|
||||
SetRect(&rcWin, 0, 0,
|
||||
pConInfo->WindowSize.X * FontPreview.CharWidth,
|
||||
|
@ -489,6 +492,9 @@ PaintText(
|
|||
hBrush = CreateSolidBrush(nbkColor);
|
||||
if (!hBrush) return;
|
||||
|
||||
if (FontPreview.hFont == NULL)
|
||||
RefreshFontPreview(&FontPreview, pConInfo);
|
||||
|
||||
hOldFont = SelectObject(drawItem->hDC, FontPreview.hFont);
|
||||
//if (hOldFont == NULL)
|
||||
//{
|
||||
|
|
|
@ -72,7 +72,8 @@ AddCodePage(
|
|||
|
||||
static VOID
|
||||
BuildCodePageList(
|
||||
IN HWND hDlg)
|
||||
IN HWND hDlg,
|
||||
IN UINT CurrentCodePage)
|
||||
{
|
||||
LIST_CTL ListCtl;
|
||||
HKEY hKey;
|
||||
|
@ -126,7 +127,7 @@ BuildCodePageList(
|
|||
AddCodePage(&ListCtl, CP_UTF8);
|
||||
|
||||
/* Find and select the current code page in the sorted list */
|
||||
if (BisectListSortedByValue(&ListCtl, ConInfo->CodePage, &CodePage, FALSE) == CB_ERR ||
|
||||
if (BisectListSortedByValue(&ListCtl, CurrentCodePage, &CodePage, FALSE) == CB_ERR ||
|
||||
CodePage == CB_ERR)
|
||||
{
|
||||
/* Not found, select the first element */
|
||||
|
@ -212,7 +213,7 @@ OptionsProc(HWND hDlg,
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
BuildCodePageList(hDlg);
|
||||
BuildCodePageList(hDlg, ConInfo->CodePage);
|
||||
UpdateDialogElements(hDlg, ConInfo);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -332,6 +333,7 @@ OptionsProc(HWND hDlg,
|
|||
}
|
||||
}
|
||||
else
|
||||
// (HIWORD(wParam) == CBN_KILLFOCUS)
|
||||
if ((HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_SELENDOK) &&
|
||||
(LOWORD(wParam) == IDL_CODEPAGE))
|
||||
{
|
||||
|
@ -347,11 +349,15 @@ OptionsProc(HWND hDlg,
|
|||
if (CodePage == CB_ERR)
|
||||
break;
|
||||
|
||||
ConInfo->CodePage = CodePage;
|
||||
|
||||
/* Change the property sheet state only if the user validated */
|
||||
if (HIWORD(wParam) == CBN_SELENDOK)
|
||||
/* If the user validated a different code page... */
|
||||
if ((HIWORD(wParam) == CBN_SELENDOK) && (CodePage != ConInfo->CodePage))
|
||||
{
|
||||
/* ... update the code page, notify the siblings and change the property sheet state */
|
||||
ConInfo->CodePage = CodePage;
|
||||
// PropSheet_QuerySiblings(GetParent(hDlg), IDL_CODEPAGE, 0);
|
||||
ResetFontPreview(&FontPreview);
|
||||
PropSheet_Changed(GetParent(hDlg), hDlg);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#include <debug.h>
|
||||
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
// RTL_STATIC_LIST_HEAD(TTFontCache);
|
||||
LIST_ENTRY TTFontCache = {&TTFontCache, &TTFontCache};
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/* Retrieves the character set associated with a given code page */
|
||||
|
@ -58,7 +63,10 @@ CreateConsoleFontEx(
|
|||
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
||||
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
lf.lfQuality = DEFAULT_QUALITY;
|
||||
lf.lfPitchAndFamily = (BYTE)(FIXED_PITCH | FontFamily);
|
||||
|
||||
/* Set the mandatory flags and remove those that we do not support */
|
||||
lf.lfPitchAndFamily = (BYTE)( (FIXED_PITCH | FF_MODERN | FontFamily) &
|
||||
~(VARIABLE_PITCH | FF_DECORATIVE | FF_ROMAN | FF_SCRIPT | FF_SWISS));
|
||||
|
||||
if (!IsValidConsoleFont(FaceName, CodePage))
|
||||
StringCchCopyW(FaceName, LF_FACESIZE, L"Terminal");
|
||||
|
@ -179,13 +187,10 @@ IsValidConsoleFont2(
|
|||
{
|
||||
LPCWSTR FaceName = lplf->lfFaceName;
|
||||
|
||||
/* Record the font's attributes (Fixedwidth and Truetype) */
|
||||
// BOOL fFixed = ((lplf->lfPitchAndFamily & 0x03) == FIXED_PITCH);
|
||||
// BOOL fTrueType = (lplf->lfOutPrecision == OUT_STROKE_PRECIS);
|
||||
|
||||
/*
|
||||
* According to: http://support.microsoft.com/kb/247815
|
||||
* the criteria for console-eligible fonts are:
|
||||
* According to: https://web.archive.org/web/20140901124501/http://support.microsoft.com/kb/247815
|
||||
* "Necessary criteria for fonts to be available in a command window",
|
||||
* the criteria for console-eligible fonts are as follows:
|
||||
* - The font must be a fixed-pitch font.
|
||||
* - The font cannot be an italic font.
|
||||
* - The font cannot have a negative A or C space.
|
||||
|
@ -198,6 +203,10 @@ IsValidConsoleFont2(
|
|||
* - If it is not a TrueType font, the face name must be "Terminal".
|
||||
* - If it is an Asian TrueType font, it must also be an Asian character set.
|
||||
*
|
||||
* See also Raymond Chen's blog: https://devblogs.microsoft.com/oldnewthing/?p=26843
|
||||
* and MIT-licensed Microsoft Terminal source code: https://github.com/microsoft/Terminal/blob/master/src/propsheet/misc.cpp
|
||||
* for other details.
|
||||
*
|
||||
* 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
|
||||
|
@ -205,27 +214,30 @@ IsValidConsoleFont2(
|
|||
* HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts
|
||||
*/
|
||||
|
||||
/*
|
||||
* In ReactOS we relax some of the criteria:
|
||||
* - We allow fixed-pitch FF_MODERN (Monospace) TrueType fonts
|
||||
* that can be italic or have negative A or C space.
|
||||
* - If it is not a TrueType font, it can be from another character set
|
||||
* than OEM_CHARSET.
|
||||
* - We do not look into the magic registry key mentioned above.
|
||||
*/
|
||||
/*
|
||||
* In ReactOS we relax some of the criteria:
|
||||
* - We allow fixed-pitch FF_MODERN (Monospace) TrueType fonts
|
||||
* that can be italic or have negative A or C space.
|
||||
* - If it is not a TrueType font, it can be from another character set
|
||||
* than OEM_CHARSET. When an Asian codepage is active however, we require
|
||||
* that this non-TrueType font has an Asian character set.
|
||||
*/
|
||||
|
||||
/* Reject variable width fonts */
|
||||
if (((lplf->lfPitchAndFamily & 0x03) != FIXED_PITCH)
|
||||
#if 0 /* Reject italic and TrueType fonts with negative A or C space */
|
||||
|| (lplf->lfItalic)
|
||||
|| !(lpntm->ntmFlags & NTM_NONNEGATIVE_AC)
|
||||
/* Reject variable-width fonts ... */
|
||||
if ( ( ((lplf->lfPitchAndFamily & 0x03) != FIXED_PITCH)
|
||||
#if 0 /* Reject italic and TrueType fonts with negative A or C space ... */
|
||||
|| (lplf->lfItalic)
|
||||
|| !(lpntm->ntmFlags & NTM_NONNEGATIVE_AC)
|
||||
#endif
|
||||
)
|
||||
) &&
|
||||
/* ... if they are not in the list of additional TrueType fonts to include */
|
||||
!IsAdditionalTTFont(FaceName) )
|
||||
{
|
||||
DPRINT1("Font '%S' rejected because it%s (lfPitchAndFamily = %d).\n",
|
||||
FaceName, !(lplf->lfPitchAndFamily & FIXED_PITCH) ? "'s not FIXED_PITCH"
|
||||
: (!(lpntm->ntmFlags & NTM_NONNEGATIVE_AC) ? " has negative A or C space"
|
||||
: " is broken"),
|
||||
DPRINT1("Font '%S' rejected because it%s (lfPitchAndFamily = %d)\n",
|
||||
FaceName,
|
||||
!(lplf->lfPitchAndFamily & FIXED_PITCH) ? "'s not FIXED_PITCH"
|
||||
: (!(lpntm->ntmFlags & NTM_NONNEGATIVE_AC) ? " has negative A or C space"
|
||||
: " is broken"),
|
||||
lplf->lfPitchAndFamily);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -238,25 +250,66 @@ IsValidConsoleFont2(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Reject vertical fonts (tategaki) */
|
||||
if (FaceName[0] == L'@')
|
||||
{
|
||||
DPRINT1("Font '%S' rejected because it's vertical\n", FaceName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Is the current code page Chinese, Japanese or Korean? */
|
||||
if (IsCJKCodePage(CodePage))
|
||||
{
|
||||
/* It's Asian */
|
||||
/* It's CJK */
|
||||
|
||||
if (FontType == TRUETYPE_FONTTYPE)
|
||||
{
|
||||
if (lplf->lfCharSet != CodePageToCharSet(CodePage))
|
||||
/*
|
||||
* Here we are inclusive and check for any CJK character set,
|
||||
* instead of looking just at the current one via CodePageToCharSet().
|
||||
*/
|
||||
if (!IsCJKCharSet(lplf->lfCharSet)
|
||||
#if 1 // FIXME: Temporary HACK!
|
||||
&& wcscmp(FaceName, L"Terminal") != 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
DPRINT1("TrueType font '%S' rejected because it's not user Asian charset (lfCharSet = %d)\n",
|
||||
DPRINT1("TrueType font '%S' rejected because it's not Asian charset (lfCharSet = %d)\n",
|
||||
FaceName, lplf->lfCharSet);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a cached TrueType font that is used only for certain
|
||||
* code pages, verify that the charset it claims is the correct one.
|
||||
*
|
||||
* Since there may be multiple entries for a cached TrueType font,
|
||||
* a general one (code page == 0) and one or more for explicit
|
||||
* code pages, we need to perform two search queries instead of
|
||||
* just one and retrieving the code page for this entry.
|
||||
*/
|
||||
if (IsAdditionalTTFont(FaceName) && !IsAdditionalTTFontCP(FaceName, 0) &&
|
||||
!IsCJKCharSet(lplf->lfCharSet))
|
||||
{
|
||||
DPRINT1("Cached TrueType font '%S' rejected because it claims a code page that is not Asian charset (lfCharSet = %d)\n",
|
||||
FaceName, lplf->lfCharSet);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reject non-TrueType fonts that do not have an Asian character set */
|
||||
if (!IsCJKCharSet(lplf->lfCharSet) && (lplf->lfCharSet != OEM_CHARSET))
|
||||
{
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not Asian charset or OEM_CHARSET (lfCharSet = %d)\n",
|
||||
FaceName, lplf->lfCharSet);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Reject non-TrueType fonts that are not Terminal */
|
||||
if (wcscmp(FaceName, L"Terminal") != 0)
|
||||
{
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not Terminal\n", FaceName);
|
||||
DPRINT1("Non-TrueType font '%S' rejected because it's not 'Terminal'\n", FaceName);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -264,6 +317,8 @@ IsValidConsoleFont2(
|
|||
else
|
||||
{
|
||||
/* Not CJK */
|
||||
|
||||
/* Reject non-TrueType fonts that are not OEM or similar */
|
||||
if ((FontType != TRUETYPE_FONTTYPE) &&
|
||||
(lplf->lfCharSet != ANSI_CHARSET) &&
|
||||
(lplf->lfCharSet != DEFAULT_CHARSET) &&
|
||||
|
@ -275,13 +330,6 @@ IsValidConsoleFont2(
|
|||
}
|
||||
}
|
||||
|
||||
/* Reject fonts that are vertical (tategaki) */
|
||||
if (FaceName[0] == L'@')
|
||||
{
|
||||
DPRINT1("Font '%S' rejected because it's vertical\n", FaceName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* All good */
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -320,7 +368,7 @@ IsValidConsoleFont(
|
|||
|
||||
RtlZeroMemory(&lf, sizeof(lf));
|
||||
lf.lfCharSet = DEFAULT_CHARSET; // CodePageToCharSet(CodePage);
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
|
||||
// lf.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
|
||||
StringCchCopyW(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FaceName);
|
||||
|
||||
hDC = GetDC(NULL);
|
||||
|
@ -330,4 +378,173 @@ IsValidConsoleFont(
|
|||
return Param.IsValidFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* This function initializes the cache of the fonts listed there.
|
||||
*/
|
||||
VOID
|
||||
InitTTFontCache(VOID)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
HKEY hKeyTTFonts; // hKey;
|
||||
DWORD dwNumValues = 0;
|
||||
DWORD dwIndex;
|
||||
DWORD dwType;
|
||||
WCHAR szValueName[MAX_PATH];
|
||||
DWORD dwValueName;
|
||||
WCHAR szValue[LF_FACESIZE] = L"";
|
||||
DWORD dwValue;
|
||||
PTT_FONT_ENTRY FontEntry;
|
||||
PWCHAR pszNext = NULL;
|
||||
UINT CodePage;
|
||||
|
||||
if (!IsListEmpty(&TTFontCache))
|
||||
return;
|
||||
// InitializeListHead(&TTFontCache);
|
||||
|
||||
/* Open the key */
|
||||
// "\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont"
|
||||
Success = (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
|
||||
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Console\\TrueTypeFont",
|
||||
0,
|
||||
KEY_READ,
|
||||
&hKeyTTFonts) == ERROR_SUCCESS);
|
||||
if (!Success)
|
||||
return;
|
||||
|
||||
/* Enumerate each value */
|
||||
if (RegQueryInfoKeyW(hKeyTTFonts, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
&dwNumValues, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("ConCfgReadUserSettings: RegQueryInfoKeyW failed\n");
|
||||
RegCloseKey(hKeyTTFonts);
|
||||
return;
|
||||
}
|
||||
|
||||
for (dwIndex = 0; dwIndex < dwNumValues; dwIndex++)
|
||||
{
|
||||
dwValue = sizeof(szValue);
|
||||
dwValueName = ARRAYSIZE(szValueName);
|
||||
if (RegEnumValueW(hKeyTTFonts, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("InitTTFontCache: RegEnumValueW failed, continuing...\n");
|
||||
continue;
|
||||
}
|
||||
/* Only (multi-)string values are supported */
|
||||
if ((dwType != REG_SZ) && (dwType != REG_MULTI_SZ))
|
||||
continue;
|
||||
|
||||
/* The value name is a code page (in decimal), validate it */
|
||||
CodePage = wcstoul(szValueName, &pszNext, 10);
|
||||
if (*pszNext)
|
||||
continue; // Non-numerical garbage followed...
|
||||
// IsValidCodePage(CodePage);
|
||||
|
||||
FontEntry = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*FontEntry));
|
||||
if (!FontEntry)
|
||||
{
|
||||
DPRINT1("InitTTFontCache: Failed to allocate memory, continuing...\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
FontEntry->CodePage = CodePage;
|
||||
|
||||
pszNext = szValue;
|
||||
|
||||
/* Check whether bold is disabled for this font */
|
||||
if (*pszNext == L'*')
|
||||
{
|
||||
FontEntry->DisableBold = TRUE;
|
||||
++pszNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
FontEntry->DisableBold = FALSE;
|
||||
}
|
||||
|
||||
/* Copy the font name */
|
||||
StringCchCopyNW(FontEntry->FaceName, ARRAYSIZE(FontEntry->FaceName),
|
||||
pszNext, wcslen(pszNext));
|
||||
|
||||
if (dwType == REG_MULTI_SZ)
|
||||
{
|
||||
/* There may be an alternate face name as the second string */
|
||||
pszNext += wcslen(pszNext) + 1;
|
||||
|
||||
/* Check whether bold is disabled for this font */
|
||||
if (*pszNext == L'*')
|
||||
{
|
||||
FontEntry->DisableBold = TRUE;
|
||||
++pszNext;
|
||||
}
|
||||
// else, keep the original setting.
|
||||
|
||||
/* Copy the alternate font name */
|
||||
StringCchCopyNW(FontEntry->FaceNameAlt, ARRAYSIZE(FontEntry->FaceNameAlt),
|
||||
pszNext, wcslen(pszNext));
|
||||
}
|
||||
|
||||
InsertTailList(&TTFontCache, &FontEntry->Entry);
|
||||
}
|
||||
|
||||
/* Close the key and quit */
|
||||
RegCloseKey(hKeyTTFonts);
|
||||
}
|
||||
|
||||
VOID
|
||||
ClearTTFontCache(VOID)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PTT_FONT_ENTRY FontEntry;
|
||||
|
||||
while (!IsListEmpty(&TTFontCache))
|
||||
{
|
||||
Entry = RemoveHeadList(&TTFontCache);
|
||||
FontEntry = CONTAINING_RECORD(Entry, TT_FONT_ENTRY, Entry);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, FontEntry);
|
||||
}
|
||||
InitializeListHead(&TTFontCache);
|
||||
}
|
||||
|
||||
VOID
|
||||
RefreshTTFontCache(VOID)
|
||||
{
|
||||
ClearTTFontCache();
|
||||
InitTTFontCache();
|
||||
}
|
||||
|
||||
PTT_FONT_ENTRY
|
||||
FindCachedTTFont(
|
||||
IN LPCWSTR FaceName,
|
||||
IN UINT CodePage)
|
||||
{
|
||||
PLIST_ENTRY Entry;
|
||||
PTT_FONT_ENTRY FontEntry;
|
||||
|
||||
/* Search for the font in the cache */
|
||||
for (Entry = TTFontCache.Flink;
|
||||
Entry != &TTFontCache;
|
||||
Entry = Entry->Flink)
|
||||
{
|
||||
FontEntry = CONTAINING_RECORD(Entry, TT_FONT_ENTRY, Entry);
|
||||
|
||||
/* NOTE: The font face names are case-sensitive */
|
||||
if ((wcscmp(FontEntry->FaceName , FaceName) == 0) ||
|
||||
(wcscmp(FontEntry->FaceNameAlt, FaceName) == 0))
|
||||
{
|
||||
/* Return a match if we don't look at the code pages, or when they match */
|
||||
if ((CodePage == INVALID_CP) || (CodePage == FontEntry->CodePage))
|
||||
{
|
||||
return FontEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -11,16 +11,50 @@
|
|||
|
||||
/* DEFINES ********************************************************************/
|
||||
|
||||
#define CP_SHIFTJIS 932 // Japanese Shift-JIS
|
||||
#define CP_HANGUL 949 // Korean Hangul
|
||||
#define CP_GB2312 936 // Chinese Simplified (GB2312)
|
||||
#define CP_BIG5 950 // Chinese Traditional (Big5)
|
||||
#define INVALID_CP ((UINT)-1)
|
||||
|
||||
#define CP_SHIFTJIS 932 // Japanese Shift-JIS
|
||||
#define CP_HANGUL 949 // Korean Hangul/Wansung
|
||||
#define CP_JOHAB 1361 // Korean Johab
|
||||
#define CP_GB2312 936 // Chinese Simplified (GB2312)
|
||||
#define CP_BIG5 950 // Chinese Traditional (Big5)
|
||||
|
||||
/* IsFarEastCP(CodePage) */
|
||||
#define IsCJKCodePage(CodePage) \
|
||||
((CodePage) == CP_SHIFTJIS || (CodePage) == CP_HANGUL || \
|
||||
/* (CodePage) == CP_JOHAB || */ \
|
||||
(CodePage) == CP_BIG5 || (CodePage) == CP_GB2312)
|
||||
|
||||
#if !defined(_WINGDI_) || defined(NOGDI)
|
||||
#define SHIFTJIS_CHARSET 128
|
||||
#define HANGEUL_CHARSET 129
|
||||
#define HANGUL_CHARSET 129 // HANGEUL_CHARSET
|
||||
#if(WINVER >= 0x0400)
|
||||
#define JOHAB_CHARSET 130
|
||||
#endif /* WINVER */
|
||||
#define GB2312_CHARSET 134
|
||||
#define CHINESEBIG5_CHARSET 136
|
||||
#endif /* !defined(_WINGDI_) || defined(NOGDI) */
|
||||
|
||||
/* IsAnyDBCSCharSet(CharSet) */
|
||||
#define IsCJKCharSet(CharSet) \
|
||||
((CharSet) == SHIFTJIS_CHARSET || (CharSet) == HANGUL_CHARSET || \
|
||||
/* (CharSet) == JOHAB_CHARSET || */ \
|
||||
(CharSet) == GB2312_CHARSET || (CharSet) == CHINESEBIG5_CHARSET)
|
||||
|
||||
#define IsBoldFont(Weight) \
|
||||
((Weight) >= FW_SEMIBOLD) /* Sometimes, just > FW_MEDIUM */
|
||||
|
||||
typedef struct _TT_FONT_ENTRY
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
UINT CodePage;
|
||||
BOOL DisableBold;
|
||||
WCHAR FaceName[LF_FACESIZE];
|
||||
WCHAR FaceNameAlt[LF_FACESIZE];
|
||||
} TT_FONT_ENTRY, *PTT_FONT_ENTRY;
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BYTE
|
||||
|
@ -65,4 +99,33 @@ IsValidConsoleFont(
|
|||
IN LPCWSTR FaceName,
|
||||
IN UINT CodePage);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* This function initializes the cache of the fonts listed there.
|
||||
*/
|
||||
VOID
|
||||
InitTTFontCache(VOID);
|
||||
|
||||
VOID
|
||||
ClearTTFontCache(VOID);
|
||||
|
||||
VOID
|
||||
RefreshTTFontCache(VOID);
|
||||
|
||||
PTT_FONT_ENTRY
|
||||
FindCachedTTFont(
|
||||
IN LPCWSTR FaceName,
|
||||
IN UINT CodePage);
|
||||
|
||||
#define IsAdditionalTTFont(FaceName) \
|
||||
(FindCachedTTFont((FaceName), INVALID_CP) != NULL)
|
||||
|
||||
#define IsAdditionalTTFontCP(FaceName, CodePage) \
|
||||
(FindCachedTTFont((FaceName), (CodePage)) != NULL)
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
#include <ndk/obfuncs.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
|
||||
#include <stdio.h> // for swprintf
|
||||
#include <stdio.h> // For swprintf()
|
||||
#include <stdlib.h> // For wcstoul()
|
||||
#include <strsafe.h>
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "font.h"
|
||||
#include "concfg/font.h"
|
||||
#include "guiterm.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "concfg/font.h"
|
||||
#include "guiterm.h"
|
||||
#include "guisettings.h"
|
||||
|
||||
|
@ -331,7 +332,8 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
|||
|
||||
/* Set the terminal informations */
|
||||
|
||||
/* Change the font */
|
||||
/* Refresh the additional TrueType fonts cache and change the font */
|
||||
RefreshTTFontCache();
|
||||
InitFonts(GuiData,
|
||||
pConInfo->FaceName,
|
||||
pConInfo->FontFamily,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "concfg/font.h"
|
||||
#include "guiterm.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
@ -294,12 +295,15 @@ GuiInit(IN PCONSOLE_INIT_INFO ConsoleInitInfo,
|
|||
HANDLE hInputThread;
|
||||
CLIENT_ID ClientId;
|
||||
|
||||
/*
|
||||
* Initialize and register the console window class, if needed.
|
||||
*/
|
||||
/* Perform one-time initialization */
|
||||
if (!ConsInitialized)
|
||||
{
|
||||
/* Initialize and register the console window class */
|
||||
if (!RegisterConWndClass(ConSrvDllInstance)) return FALSE;
|
||||
|
||||
/* Initialize the font support -- additional TrueType fonts cache */
|
||||
InitTTFontCache();
|
||||
|
||||
ConsInitialized = TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue