Compare commits

...

1 Commits

Author SHA1 Message Date
Leonard Hecker
b229afbe8c wip 2023-11-22 16:24:10 +01:00
7 changed files with 87 additions and 728 deletions

View File

@@ -28,8 +28,6 @@ UINT gnCurrentPage;
#define SYSTEM_ROOT (L"%SystemRoot%")
#define SYSTEM_ROOT_LENGTH (sizeof(SYSTEM_ROOT) - sizeof(WCHAR))
void RecreateFontHandles(const HWND hWnd);
void UpdateItem(HWND hDlg, UINT item, UINT nNum)
{
SetDlgItemInt(hDlg, item, nNum, TRUE);
@@ -622,9 +620,6 @@ INT_PTR ConsolePropertySheet(__in HWND hWnd, __in PCONSOLE_STATE_INFO pStateInfo
gpStateInfo->FontWeight,
gpStateInfo->CodePage);
// since we just triggered font enumeration, recreate our font handles to adapt for DPI
RecreateFontHandles(hWnd);
//
// Find the available default console/terminal packages
//
@@ -758,7 +753,8 @@ void UnregisterClasses(HINSTANCE hModule)
gpStateInfo->CodePage);
gpStateInfo->FontFamily = FontInfo[g_currentFontIndex].Family;
gpStateInfo->FontSize = FontInfo[g_currentFontIndex].Size;
gpStateInfo->FontSize.X = (SHORT)FontInfo[g_currentFontIndex].Size.cx;
gpStateInfo->FontSize.Y = (SHORT)FontInfo[g_currentFontIndex].Size.cy;
gpStateInfo->FontWeight = FontInfo[g_currentFontIndex].Weight;
return StringCchCopyW(gpStateInfo->FaceName, ARRAYSIZE(gpStateInfo->FaceName), FontInfo[g_currentFontIndex].FaceName);
}

View File

@@ -44,8 +44,8 @@ void MakeAltRasterFont(
if (!TM_IS_TT_FONT(FontInfo[i].Family) &&
IS_ANY_DBCS_CHARSET(FontInfo[i].tmCharSet) == fDbcsCharSet)
{
FontDelta.X = (SHORT)abs(FontSize.X - FontInfo[i].Size.X);
FontDelta.Y = (SHORT)abs(FontSize.Y - FontInfo[i].Size.Y);
FontDelta.X = (SHORT)abs(FontSize.cx - FontInfo[i].Size.cx);
FontDelta.Y = (SHORT)abs(FontSize.cy - FontInfo[i].Size.cy);
if (Find > (DWORD)(FontDelta.X + FontDelta.Y))
{
Find = (DWORD)(FontDelta.X + FontDelta.Y);
@@ -56,7 +56,8 @@ void MakeAltRasterFont(
*AltFontIndex = FontIndex;
StringCchCopy(AltFaceName, LF_FACESIZE, FontInfo[*AltFontIndex].FaceName);
*AltFontSize = FontInfo[*AltFontIndex].Size;
AltFontSize->X = (SHORT)FontInfo[*AltFontIndex].Size.cx;
AltFontSize->Y = (SHORT)FontInfo[*AltFontIndex].Size.cy;
*AltFontFamily = FontInfo[*AltFontIndex].Family;
DBGFONTS(("MakeAltRasterFont : AltFontIndex = %ld\n", *AltFontIndex));

View File

@@ -52,8 +52,6 @@ Revision History:
typedef struct _FONT_INFO
{
HFONT hFont;
COORD Size; // font size obtained
COORD SizeWant; // 0;0 if Raster font
LONG Weight;
LPTSTR FaceName;
BYTE Family;
@@ -74,7 +72,6 @@ typedef struct tagFACENODE
#define TM_IS_TT_FONT(x) (((x)&TMPF_TRUETYPE) == TMPF_TRUETYPE)
#define IS_BOLD(w) ((w) >= FW_SEMIBOLD)
#define SIZE_EQUAL(s1, s2) (((s1).X == (s2).X) && ((s1).Y == (s2).Y))
#define POINTS_PER_INCH 72
#define MIN_PIXEL_HEIGHT 5
#define MAX_PIXEL_HEIGHT 72
@@ -99,17 +96,10 @@ int FindCreateFont(
__in LONG Weight,
__in UINT CodePage);
BOOL DoFontEnum(
__in_opt HDC hDC,
__in_ecount_opt(LF_FACESIZE) LPTSTR ptszFace,
__in_ecount_opt(nTTPoints) PSHORT pTTPoints,
__in UINT nTTPoints);
BOOL DoFontEnum(__in_opt HDC hDC, __in_ecount_opt(LF_FACESIZE) LPTSTR ptszFace);
[[nodiscard]] NTSTATUS GetTTFontFaceForCodePage(const UINT uiCodePage,
_Out_writes_(cchFaceName) PWSTR pszFaceName,
const size_t cchFaceName);
bool IsFontSizeCustom(__in PCWSTR pwszFaceName, const __in SHORT sSize);
void CreateSizeForAllTTFonts(const __in SHORT sSize);
#endif /* !FONT_H */

View File

@@ -46,8 +46,6 @@ BOOL PreviewInit(
VOID DrawItemFontList(const HWND hDlg, const LPDRAWITEMSTRUCT lpdis);
void RecreateFontHandles(const HWND hWnd);
/* ----- Globals ----- */
HBITMAP hbmTT = nullptr; // handle of TT logo bitmap
@@ -151,63 +149,6 @@ BOOL IsBoldOnlyTTFont(_In_ PCWSTR pwszTTFace, _In_opt_ PCWSTR pwszAltTTFace)
return !fFoundNormalWeightFont;
}
// Given a handle to our dialog:
// 1. Get currently entered font size
// 2. Check to see if the size is a valid custom size
// 3. If the size is custom, add it to the points size list
static void AddCustomFontSizeToListIfNeeded(const __in HWND hDlg)
{
WCHAR wszBuf[3]; // only need space for point sizes. the max we allow is "72"
// check to see if we have text
if (GetDlgItemText(hDlg, IDD_POINTSLIST, wszBuf, ARRAYSIZE(wszBuf)) > 0)
{
// we have text, now retrieve it as an actual size
BOOL fTranslated;
const auto nPointSize = (SHORT)GetDlgItemInt(hDlg, IDD_POINTSLIST, &fTranslated, TRUE);
if (fTranslated &&
nPointSize >= MIN_PIXEL_HEIGHT &&
nPointSize <= MAX_PIXEL_HEIGHT &&
IsFontSizeCustom(gpStateInfo->FaceName, nPointSize))
{
// we got a proper custom size. let's see if it's in our point size list
auto iSize = (LONG)SendDlgItemMessage(hDlg, IDD_POINTSLIST, CB_FINDSTRINGEXACT, (WPARAM)-1, (LPARAM)wszBuf);
if (iSize == CB_ERR)
{
// the size isn't in our list, so we haven't created them yet. do so now.
CreateSizeForAllTTFonts(nPointSize);
// add the size to the dialog list and select it
iSize = (LONG)SendDlgItemMessage(hDlg, IDD_POINTSLIST, CB_ADDSTRING, 0, (LPARAM)wszBuf);
SendDlgItemMessage(hDlg, IDD_POINTSLIST, CB_SETCURSEL, iSize, 0);
// get the current font selection
auto lCurrentFont = (LONG)SendDlgItemMessage(hDlg, IDD_FACENAME, LB_GETCURSEL, 0, 0);
// now get the current font's face name
WCHAR wszFontFace[LF_FACESIZE];
SendDlgItemMessage(hDlg,
IDD_FACENAME,
LB_GETTEXT,
(WPARAM)lCurrentFont,
(LPARAM)wszFontFace);
// now cause the hFont for this face/size combination to get loaded -- we need to do this so that the
// font preview has an hFont with which to render
COORD coordFontSize;
coordFontSize.X = 0;
coordFontSize.Y = nPointSize;
const auto iFont = FindCreateFont(FF_MODERN | TMPF_VECTOR | TMPF_TRUETYPE,
wszFontFace,
coordFontSize,
0,
gpStateInfo->CodePage);
SendDlgItemMessage(hDlg, IDD_POINTSLIST, CB_SETITEMDATA, (WPARAM)iSize, (LPARAM)iFont);
}
}
}
}
INT_PTR
APIENTRY
FontDlgProc(
@@ -245,11 +186,11 @@ FontDlgProc(
if (g_fEastAsianSystem)
{
SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[g_currentFontIndex].tmCharSet, FontInfo[g_currentFontIndex].Size.Y));
SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[g_currentFontIndex].tmCharSet, FontInfo[g_currentFontIndex].Size.cy));
}
else
{
SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[g_currentFontIndex].Size.X, FontInfo[g_currentFontIndex].Size.Y));
SetWindowLongPtr(hDlg, GWLP_USERDATA, MAKELONG(FontInfo[g_currentFontIndex].Size.cx, FontInfo[g_currentFontIndex].Size.cy));
}
if (g_fHostedInFileProperties || gpStateInfo->Defaults)
@@ -403,7 +344,6 @@ FontDlgProc(
if (hWndFocus != nullptr && IsChild(hDlg, hWndFocus) &&
hWndFocus != GetDlgItem(hDlg, IDCANCEL))
{
AddCustomFontSizeToListIfNeeded(hDlg);
PreviewUpdate(hDlg, FALSE);
}
}
@@ -439,42 +379,6 @@ FontDlgProc(
const PSHNOTIFY* const pshn = (LPPSHNOTIFY)lParam;
switch (pshn->hdr.code)
{
case PSN_KILLACTIVE:
//
// If the TT combo box is visible, update selection
//
hWndList = GetDlgItem(hDlg, IDD_POINTSLIST);
if (hWndList != nullptr && IsWindowVisible(hWndList))
{
if (!PreviewUpdate(hDlg, FALSE))
{
SetDlgMsgResult(hDlg, PSN_KILLACTIVE, TRUE);
return TRUE;
}
SetDlgMsgResult(hDlg, PSN_KILLACTIVE, FALSE);
}
FontIndex = g_currentFontIndex;
if (FontInfo[FontIndex].SizeWant.Y == 0)
{
// Raster Font, so save actual size
gpStateInfo->FontSize = FontInfo[FontIndex].Size;
}
else
{
// TT Font, so save desired size
gpStateInfo->FontSize = FontInfo[FontIndex].SizeWant;
}
gpStateInfo->FontWeight = FontInfo[FontIndex].Weight;
gpStateInfo->FontFamily = FontInfo[FontIndex].Family;
StringCchCopy(gpStateInfo->FaceName,
ARRAYSIZE(gpStateInfo->FaceName),
FontInfo[FontIndex].FaceName);
return TRUE;
case PSN_APPLY:
/*
* Write out the state values and exit.
@@ -510,9 +414,6 @@ FontDlgProc(
return TRUE;
case WM_DPICHANGED_BEFOREPARENT:
// DPI has changed -- recreate our font handles to get appropriately scaled fonts
RecreateFontHandles(hDlg);
// Now reset our item height. This is to work around a limitation of automatic dialog DPI scaling where
// WM_MEASUREITEM doesn't get sent when the DPI has changed.
SendDlgItemMessage(hDlg, IDD_FACENAME, LB_SETITEMHEIGHT, 0, GetItemHeight(hDlg));
@@ -525,158 +426,6 @@ FontDlgProc(
return FALSE;
}
// Iterate through all of our fonts to find the font entries that match the desired family, charset, name (TT), and
// boldness (TT). Each entry in FontInfo represents a specific combination of font states. We expect to encounter
// numerous entries for each size/boldness/charset of TT fonts. If fAddBoldFonts is true, we'll add a font even if it's
// bold, regardless of whether the user has chosen bold fonts or not.
void AddFontSizesToList(PCWSTR pwszTTFace,
PCWSTR pwszAltTTFace,
const LONG_PTR dwExStyle,
const BOOL fDbcsCharSet,
const BOOL fRasterFont,
const HWND hWndShow,
const BOOL fAddBoldFonts)
{
WCHAR wszText[80];
auto iLastShowX = 0;
auto iLastShowY = 0;
auto nSameSize = 0;
for (ULONG i = 0; i < NumberOfFonts; i++)
{
if (!fRasterFont == !TM_IS_TT_FONT(FontInfo[i].Family))
{
DBGFONTS((" Font %x not right type\n", i));
continue;
}
if (fDbcsCharSet)
{
if (!IS_DBCS_OR_OEM_CHARSET(FontInfo[i].tmCharSet))
{
DBGFONTS((" Font %x not right type for DBCS character set\n", i));
continue;
}
}
else
{
if (IS_ANY_DBCS_CHARSET(FontInfo[i].tmCharSet))
{
DBGFONTS((" Font %x not right type for SBCS character set\n", i));
continue;
}
}
if (!fRasterFont)
{
if ((0 != lstrcmp(FontInfo[i].FaceName, pwszTTFace)) &&
(0 != lstrcmp(FontInfo[i].FaceName, pwszAltTTFace)))
{
/*
* A TrueType font, but not the one we're interested in,
* so don't add it to the list of point sizes.
*/
DBGFONTS((" Font %x is TT, but not %ls\n", i, pwszTTFace));
continue;
}
// if we're being asked to add bold fonts, add unconditionally according to weight. Otherwise, only this
// entry to the list of it's in line with user choice. Raster fonts aren't available in bold.
if (!fAddBoldFonts && gbBold != IS_BOLD(FontInfo[i].Weight))
{
DBGFONTS((" Font %x has weight %d, but we wanted %sbold\n",
i,
FontInfo[i].Weight,
gbBold ? "" : "not "));
continue;
}
}
int ShowX;
if (FontInfo[i].SizeWant.X > 0)
{
ShowX = FontInfo[i].SizeWant.X;
}
else
{
ShowX = FontInfo[i].Size.X;
}
int ShowY;
if (FontInfo[i].SizeWant.Y > 0)
{
ShowY = FontInfo[i].SizeWant.Y;
}
else
{
ShowY = FontInfo[i].Size.Y;
}
/*
* Add the size description string to the end of the right list
*/
if (TM_IS_TT_FONT(FontInfo[i].Family))
{
// point size
StringCchPrintf(wszText,
ARRAYSIZE(wszText),
TEXT("%2d"),
FontInfo[i].SizeWant.Y);
}
else
{
// pixel size
if ((iLastShowX == ShowX) && (iLastShowY == ShowY))
{
nSameSize++;
}
else
{
iLastShowX = ShowX;
iLastShowY = ShowY;
nSameSize = 0;
}
/*
* The number nSameSize is appended to the string to distinguish
* between Raster fonts of the same size. It is not intended to
* be visible and exists off the edge of the list
*/
if (((dwExStyle & WS_EX_RIGHT) && !(dwExStyle & WS_EX_LAYOUTRTL)) ||
(!(dwExStyle & WS_EX_RIGHT) && (dwExStyle & WS_EX_LAYOUTRTL)))
{
// flip it so that the hidden part be at the far left
StringCchPrintf(wszText,
ARRAYSIZE(wszText),
TEXT("#%d %2d x %2d"),
nSameSize,
ShowX,
ShowY);
}
else
{
StringCchPrintf(wszText,
ARRAYSIZE(wszText),
TEXT("%2d x %2d #%d"),
ShowX,
ShowY,
nSameSize);
}
}
auto lListIndex = lcbFINDSTRINGEXACT(hWndShow, fRasterFont, wszText);
if (lListIndex == LB_ERR)
{
lListIndex = lcbADDSTRING(hWndShow, fRasterFont, wszText);
}
DBGFONTS((" added %ls to %sSLIST(%p) index %lx\n",
wszText,
fRasterFont ? "PIXEL" : "POINT",
hWndShow,
lListIndex));
lcbSETITEMDATA(hWndShow, fRasterFont, (DWORD)lListIndex, i);
}
}
/*++
Initializes the font list by enumerating all fonts and picking the
@@ -861,25 +610,6 @@ int FontListCreate(
SetWindowLongPtr(hWndShow, GWL_EXSTYLE, dwExStyle | WS_EX_RTLREADING);
}
/* Initialize hWndShow list/combo box */
const BOOL fIsBoldOnlyTTFont = (!bLB && IsBoldOnlyTTFont(pwszTTFace, pwszAltTTFace));
AddFontSizesToList(pwszTTFace,
pwszAltTTFace,
dwExStyle,
g_fEastAsianSystem,
bLB,
hWndShow,
fIsBoldOnlyTTFont);
if (fIsBoldOnlyTTFont)
{
// since this is a bold-only font, check and disable the bold checkbox
EnableWindow(GetDlgItem(hDlg, IDD_BOLDFONT), FALSE);
CheckDlgButton(hDlg, IDD_BOLDFONT, TRUE);
}
/*
* Get the FontIndex from the currently selected item.
* (i will be LB_ERR if no currently selected item).
@@ -887,6 +617,43 @@ int FontListCreate(
lListIndex = lcbGETCURSEL(hWndShow, bLB);
i = lcbGETITEMDATA(hWndShow, bLB, lListIndex);
/* Initialize hWndShow list/combo box */
static constexpr SHORT TTPoints[] = {
5,
6,
7,
8,
10,
12,
14,
16,
18,
20,
24,
28,
36,
72
};
for (const auto p : TTPoints) {
UNREFERENCED_PARAMETER(p);
auto fRasterFont = true;
auto wszText = L"foo";
auto lListIndex2 = lcbFINDSTRINGEXACT(hWndShow, fRasterFont, wszText);
if (lListIndex2 == LB_ERR)
{
lListIndex2 = lcbADDSTRING(hWndShow, fRasterFont, wszText);
}
lcbSETITEMDATA(hWndShow, fRasterFont, (DWORD)lListIndex2, i);
}
if (!bLB && IsBoldOnlyTTFont(pwszTTFace, pwszAltTTFace))
{
// since this is a bold-only font, check and disable the bold checkbox
EnableWindow(GetDlgItem(hDlg, IDD_BOLDFONT), FALSE);
CheckDlgButton(hDlg, IDD_BOLDFONT, TRUE);
}
DBGFONTS(("FontListCreate returns 0x%x\n", i));
FAIL_FAST_IF(!(i == LB_ERR || (ULONG)i < NumberOfFonts));
return i;
@@ -1101,7 +868,7 @@ Return Value:
case WM_DPICHANGED:
// DPI has changed -- recreate our font handles to get appropriately scaled fonts
RecreateFontHandles(hWnd);
// TODO: InvalidateRect() needed?
break;
default:
@@ -1227,15 +994,6 @@ TryFindExactFont:
continue;
}
/*
* Skip non-matching sizes
*/
if ((FontInfo[i].SizeWant.Y != Size.Y) &&
!SIZE_EQUAL(FontInfo[i].Size, Size))
{
continue;
}
/*
* Skip non-matching weights
*/
@@ -1278,7 +1036,7 @@ TryFindExactFont:
{
Size.Y = -Size.Y;
}
bFontOK = DoFontEnum(nullptr, pwszFace, &Size.Y, 1);
bFontOK = DoFontEnum(nullptr, pwszFace);
if (bFontOK)
{
DBGFONTS(("FindCreateFont created font!\n"));
@@ -1322,13 +1080,6 @@ TryFindExactFont:
continue;
}
}
if (FontInfo[i].Size.Y >= Size.Y && FontInfo[i].Size.X >= Size.X)
{
// Same family, size >= desired.
FontIndex = i;
break;
}
}
if (FontIndex < 0)
@@ -1436,7 +1187,7 @@ int SelectCurrentSize(HWND hDlg, BOOL bLB, int FontIndex)
{
iCB--;
FontIndex = lcbGETITEMDATA(hWndList, bLB, iCB);
if (FontInfo[FontIndex].Size.Y <= HIWORD(Size))
if (FontInfo[FontIndex].Size.cy <= HIWORD(Size))
{
lcbSETCURSEL(hWndList, bLB, iCB);
break;
@@ -1501,7 +1252,8 @@ BOOL PreviewInit(
if (g_fHostedInFileProperties)
{
gpStateInfo->FontFamily = FontInfo[g_currentFontIndex].Family;
gpStateInfo->FontSize = FontInfo[g_currentFontIndex].Size;
gpStateInfo->FontSize.X = (SHORT)FontInfo[g_currentFontIndex].Size.cx;
gpStateInfo->FontSize.Y = (SHORT)FontInfo[g_currentFontIndex].Size.cy;
gpStateInfo->FontWeight = FontInfo[g_currentFontIndex].Weight;
StringCchCopyW(gpStateInfo->FaceName, ARRAYSIZE(gpStateInfo->FaceName), FontInfo[g_currentFontIndex].FaceName);
}
@@ -1614,11 +1366,11 @@ BOOL PreviewUpdate(
SetDlgItemText(hDlg, IDD_GROUP, wszFace);
/* Put the font size in the static boxes */
StringCchPrintf(wszText, ARRAYSIZE(wszText), TEXT("%u"), lpFont->Size.X);
StringCchPrintf(wszText, ARRAYSIZE(wszText), TEXT("%u"), lpFont->Size.cy);
hWnd = GetDlgItem(hDlg, IDD_FONTWIDTH);
SetWindowText(hWnd, wszText);
InvalidateRect(hWnd, nullptr, TRUE);
StringCchPrintf(wszText, ARRAYSIZE(wszText), TEXT("%u"), lpFont->Size.Y);
StringCchPrintf(wszText, ARRAYSIZE(wszText), TEXT("%u"), lpFont->Size.cy);
hWnd = GetDlgItem(hDlg, IDD_FONTHEIGHT);
SetWindowText(hWnd, wszText);
InvalidateRect(hWnd, nullptr, TRUE);

View File

@@ -36,52 +36,11 @@ ULONG gDebugFlag = 0;
#define TERMINAL_FACENAME L"Terminal"
/*
* TTPoints -- Initial font pixel heights for TT fonts
*/
SHORT TTPoints[] = {
5,
6,
7,
8,
10,
12,
14,
16,
18,
20,
24,
28,
36,
72
};
/*
* TTPointsDbcs -- Initial font pixel heights for TT fonts of DBCS.
* So, This list except odd point size because font width is (SBCS:DBCS != 1:2).
*/
SHORT TTPointsDbcs[] = {
6,
8,
10,
12,
14,
16,
18,
20,
24,
28,
36,
72
};
typedef struct _FONTENUMDATA
{
HDC hDC;
BOOL bFindFaces;
ULONG ulFE;
__field_ecount_opt(nTTPoints) PSHORT pTTPoints;
UINT nTTPoints;
} FONTENUMDATA, *PFONTENUMDATA;
PFACENODE
@@ -134,71 +93,6 @@ VOID DestroyFaceNodes(VOID)
gpFaceNames = nullptr;
}
// TODO: Refactor into lib for use by both conhost and console.dll
// see http://osgvsowi/677457
UINT GetCurrentDPI(const HWND hWnd, const BOOL fReturnYDPI)
{
UINT dpiX = 0;
UINT dpiY = 0;
GetDpiForMonitor(MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST),
MDT_EFFECTIVE_DPI,
&dpiX,
&dpiY);
return (fReturnYDPI) ? dpiY : dpiX;
}
int GetDPIScaledPixelSize(const int px, const int iCurrentDPI)
{
return MulDiv(px, iCurrentDPI, 96);
}
int GetDPIYScaledPixelSize(const HWND hWnd, const int px)
{
return GetDPIScaledPixelSize(px, GetCurrentDPI(hWnd, TRUE));
}
int GetDPIXScaledPixelSize(const HWND hWnd, const int px)
{
return GetDPIScaledPixelSize(px, GetCurrentDPI(hWnd, FALSE));
}
// If we're running the V2 console, enumerate all of our TrueType fonts and rescale them as appropriate to match the
// current monitor's DPI. This function gets triggered when either the DPI of a single monitor changes, or when the
// properties dialog is moved between monitors of differing DPIs.
void RecreateFontHandles(const HWND hWnd)
{
if (gpStateInfo->fIsV2Console)
{
for (UINT iCurrFont = 0; iCurrFont < NumberOfFonts; iCurrFont++)
{
// if the current font is a TrueType font
if (TM_IS_TT_FONT(FontInfo[iCurrFont].Family))
{
LOGFONT lf = { 0 };
lf.lfWidth = GetDPIXScaledPixelSize(hWnd, FontInfo[iCurrFont].Size.X);
lf.lfHeight = GetDPIYScaledPixelSize(hWnd, FontInfo[iCurrFont].Size.Y);
lf.lfWeight = FontInfo[iCurrFont].Weight;
lf.lfCharSet = FontInfo[iCurrFont].tmCharSet;
// NOTE: not using what GDI gave us because some fonts don't quite roundtrip (e.g. MS Gothic and VL Gothic)
lf.lfPitchAndFamily = (FIXED_PITCH | FF_MODERN);
if (SUCCEEDED(StringCchCopy(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), FontInfo[iCurrFont].FaceName)))
{
auto hRescaledFont = CreateFontIndirect(&lf);
if (hRescaledFont != nullptr)
{
// Only replace the existing font if we've got a replacement. The worst that can happen is that
// we fail to create our scaled font, so the user sees an incorrectly-scaled font preview.
DeleteObject(FontInfo[iCurrFont].hFont);
FontInfo[iCurrFont].hFont = hRescaledFont;
}
}
}
}
}
}
// Routine Description:
// - Add the font described by the LOGFONT structure to the font table if
// it's not already there.
@@ -212,20 +106,10 @@ int AddFont(
HFONT hFont;
TEXTMETRIC tm;
ULONG nFont;
COORD SizeToShow, SizeActual, SizeWant, SizeOriginal;
BYTE tmFamily;
SIZE Size;
auto fCreatingBoldFont = FALSE;
auto ptszFace = pelf->elfLogFont.lfFaceName;
/* get font info */
SizeWant.X = (SHORT)pelf->elfLogFont.lfWidth;
SizeWant.Y = (SHORT)pelf->elfLogFont.lfHeight;
/* save original size request so that we can use it unmodified when doing DPI calculations */
SizeOriginal.X = (SHORT)pelf->elfLogFont.lfWidth;
SizeOriginal.Y = (SHORT)pelf->elfLogFont.lfHeight;
CreateBoldFont:
pelf->elfLogFont.lfQuality = DEFAULT_QUALITY;
hFont = CreateFontIndirect(&pelf->elfLogFont);
@@ -241,30 +125,6 @@ CreateBoldFont:
GetTextMetrics(hDC, &tm);
GetTextExtentPoint32(hDC, TEXT("0"), 1, &Size);
SizeActual.X = (SHORT)Size.cx;
SizeActual.Y = (SHORT)(tm.tmHeight + tm.tmExternalLeading);
DBGFONTS2((" actual size %d,%d\n", SizeActual.X, SizeActual.Y));
tmFamily = tm.tmPitchAndFamily;
if (TM_IS_TT_FONT(tmFamily) && (SizeWant.Y >= 0))
{
SizeToShow = SizeWant;
if (SizeWant.X == 0)
{
// Asking for zero width height gets a default aspect-ratio width.
// It's better to show that width rather than 0.
SizeToShow.X = SizeActual.X;
}
}
else
{
SizeToShow = SizeActual;
}
DBGFONTS2((" SizeToShow = (%d,%d), SizeActual = (%d,%d)\n",
SizeToShow.X,
SizeToShow.Y,
SizeActual.X,
SizeActual.Y));
/*
* NOW, determine whether this font entry has already been cached
@@ -277,51 +137,16 @@ CreateBoldFont:
*/
for (nFont = 0; nFont < NumberOfFonts; ++nFont)
{
COORD SizeShown;
if (FontInfo[nFont].hFont == nullptr)
{
DBGFONTS(("! Font %x has a NULL hFont\n", nFont));
continue;
}
if (FontInfo[nFont].SizeWant.X > 0)
{
SizeShown.X = FontInfo[nFont].SizeWant.X;
}
else
{
SizeShown.X = FontInfo[nFont].Size.X;
}
if (FontInfo[nFont].SizeWant.Y > 0)
{
// This is a font specified by cell height.
SizeShown.Y = FontInfo[nFont].SizeWant.Y;
}
else
{
SizeShown.Y = FontInfo[nFont].Size.Y;
if (FontInfo[nFont].SizeWant.Y < 0)
{
// This is a TT font specified by character height.
if (SizeWant.Y < 0 && SizeWant.Y > FontInfo[nFont].SizeWant.Y)
{
// Requested pixelheight is smaller than this one.
DBGFONTS(("INSERT %d pt at %x, before %d pt\n",
-SizeWant.Y,
nFont,
-FontInfo[nFont].SizeWant.Y));
break;
}
}
}
// Note that we're relying on pntm->tmWeight below because some fonts (e.g. Iosevka Extralight) show up as bold
// via GetTextMetrics. pntm->tmWeight doesn't have this issue. However, on the second pass through (see
// :CreateBoldFont) we should use what's in tm.tmWeight
if (SIZE_EQUAL(SizeShown, SizeToShow) &&
FontInfo[nFont].Family == tmFamily &&
if (FontInfo[nFont].Family == tm.tmPitchAndFamily &&
FontInfo[nFont].Weight == ((fCreatingBoldFont) ? tm.tmWeight : pntm->tmWeight) &&
0 == lstrcmp(FontInfo[nFont].FaceName, ptszFace))
{
@@ -332,16 +157,6 @@ CreateBoldFont:
DeleteObject(hFont);
return FE_FONTOK;
}
if ((SizeToShow.Y < SizeShown.Y) ||
(SizeToShow.Y == SizeShown.Y && SizeToShow.X < SizeShown.X))
{
/*
* This new font is smaller than nFont
*/
DBGFONTS(("INSERT at %x, SizeToShow = (%d,%d)\n", nFont, SizeToShow.X, SizeToShow.Y));
break;
}
}
/*
@@ -379,45 +194,13 @@ CreateBoldFont:
sizeof(FONT_INFO) * (NumberOfFonts - nFont));
}
/*
* If we're adding a truetype font for the V2 console, secretly swap out the current hFont with one that's scaled
* appropriately for DPI
*/
if (nFontType == TRUETYPE_FONTTYPE && gpStateInfo->fIsV2Console)
{
DeleteObject(hFont);
pelf->elfLogFont.lfWidth = GetDPIXScaledPixelSize(gpStateInfo->hWnd, SizeOriginal.X);
pelf->elfLogFont.lfHeight = GetDPIYScaledPixelSize(gpStateInfo->hWnd, SizeOriginal.Y);
hFont = CreateFontIndirect(&pelf->elfLogFont);
if (!hFont)
{
return FE_SKIPFONT;
}
}
/*
* Store the font info
*/
if (FontInfo[nFont].hFont != nullptr)
{
DeleteObject(FontInfo[nFont].hFont);
}
FontInfo[nFont].hFont = hFont;
FontInfo[nFont].Family = tmFamily;
FontInfo[nFont].Size = SizeActual;
if (TM_IS_TT_FONT(tmFamily))
{
FontInfo[nFont].SizeWant = SizeWant;
}
else
{
FontInfo[nFont].SizeWant.X = 0;
FontInfo[nFont].SizeWant.Y = 0;
}
FontInfo[nFont].Family = tm.tmPitchAndFamily;
FontInfo[nFont].Weight = tm.tmWeight;
FontInfo[nFont].FaceName = pFN->atch;
FontInfo[nFont].tmCharSet = tm.tmCharSet;
++NumberOfFonts;
@@ -428,8 +211,6 @@ CreateBoldFont:
if (nFontType == TRUETYPE_FONTTYPE && !IS_BOLD(FontInfo[nFont].Weight))
{
pelf->elfLogFont.lfWeight = FW_BOLD;
pelf->elfLogFont.lfWidth = SizeOriginal.X;
pelf->elfLogFont.lfHeight = SizeOriginal.Y;
fCreatingBoldFont = TRUE;
goto CreateBoldFont;
}
@@ -471,8 +252,6 @@ VOID DestroyFonts(VOID)
*/
int CALLBACK FontEnumForV2Console(ENUMLOGFONT* pelf, NEWTEXTMETRIC* pntm, int nFontType, LPARAM lParam)
{
FAIL_FAST_IF(!(ShouldAllowAllMonoTTFonts()));
UINT i;
LPCTSTR ptszFace = pelf->elfLogFont.lfFaceName;
PFACENODE pFN;
auto pfed = (PFONTENUMDATA)lParam;
@@ -572,31 +351,10 @@ int CALLBACK FontEnumForV2Console(ENUMLOGFONT* pelf, NEWTEXTMETRIC* pntm, int nF
return FE_SKIPFONT;
}
/*
* Add the font to the table. If this is a true type font, add the
* sizes from the array. Otherwise, just add the size we got.
*/
if (nFontType & TRUETYPE_FONTTYPE)
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
for (i = 0; i < pfed->nTTPoints; i++)
{
pelf->elfLogFont.lfHeight = pfed->pTTPoints[i];
pelf->elfLogFont.lfWidth = 0;
pelf->elfLogFont.lfWeight = pntm->tmWeight;
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
return FE_ABANDONFONT;
}
}
}
else
{
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
return FE_ABANDONFONT;
}
return FE_ABANDONFONT;
}
return FE_FONTOK; // and continue enumeration
@@ -619,7 +377,6 @@ int
int nFontType,
LPARAM lParam)
{
UINT i;
LPCTSTR ptszFace = pelf->elfLogFont.lfFaceName;
PFACENODE pFN;
auto pfed = (PFONTENUMDATA)lParam;
@@ -748,41 +505,16 @@ int
// return FE_SKIPFONT;
}
/*
* Add the font to the table. If this is a true type font, add the
* sizes from the array. Otherwise, just add the size we got.
*/
if (nFontType & TRUETYPE_FONTTYPE)
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
for (i = 0; i < pfed->nTTPoints; i++)
{
pelf->elfLogFont.lfHeight = pfed->pTTPoints[i];
pelf->elfLogFont.lfWidth = 0;
pelf->elfLogFont.lfWeight = 400;
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
return FE_ABANDONFONT;
}
}
}
else
{
pfed->ulFE |= AddFont(pelf, pntm, nFontType, pfed->hDC, pFN);
if (pfed->ulFE == FE_ABANDONFONT)
{
return FE_ABANDONFONT;
}
return FE_ABANDONFONT;
}
return FE_FONTOK; // and continue enumeration
}
BOOL DoFontEnum(
__in_opt HDC hDC,
__in_ecount_opt(LF_FACESIZE) LPTSTR ptszFace,
__in_ecount_opt(nTTPoints) PSHORT pTTPoints,
__in UINT nTTPoints)
BOOL DoFontEnum(__in_opt HDC hDC, __in_ecount_opt(LF_FACESIZE) LPTSTR ptszFace)
{
auto bDeleteDC = FALSE;
FONTENUMDATA fed;
@@ -798,8 +530,6 @@ BOOL DoFontEnum(
fed.hDC = hDC;
fed.bFindFaces = (ptszFace == nullptr);
fed.ulFE = 0;
fed.pTTPoints = pTTPoints;
fed.nTTPoints = nTTPoints;
RtlZeroMemory(&LogFont, sizeof(LOGFONT));
LogFont.lfCharSet = DEFAULT_CHARSET;
if (ptszFace != nullptr)
@@ -868,61 +598,6 @@ VOID RemoveFace(__in_ecount(LF_FACESIZE) LPCTSTR ptszFace)
NumberOfFonts -= nToRemove;
}
// Given a desired SHORT size, search pTTPoints to determine if size is in the list.
static bool IsSizePresentInList(const __in SHORT sSizeDesired, __in_ecount(nTTPoints) PSHORT pTTPoints, __in UINT nTTPoints)
{
auto fSizePresent = false;
for (UINT i = 0; i < nTTPoints; i++)
{
if (pTTPoints[i] == sSizeDesired)
{
fSizePresent = true;
break;
}
}
return fSizePresent;
}
// Given a face name, determine if the size provided is custom (i.e. not on the hard-coded list of sizes). Note that the
// list of sizes we use varies depending on the codepage being used
bool IsFontSizeCustom(__in PCWSTR pszFaceName, const __in SHORT sSize)
{
bool fUsingCustomFontSize;
if (g_fEastAsianSystem && !IsAvailableTTFontCP(pszFaceName, 0))
{
fUsingCustomFontSize = !IsSizePresentInList(sSize, TTPointsDbcs, ARRAYSIZE(TTPointsDbcs));
}
else
{
fUsingCustomFontSize = !IsSizePresentInList(sSize, TTPoints, ARRAYSIZE(TTPoints));
}
return fUsingCustomFontSize;
}
// Determines if the currently-selected font is using a custom size
static bool IsCurrentFontSizeCustom()
{
return IsFontSizeCustom(gpStateInfo->FaceName, gpStateInfo->FontSize.Y);
}
// Given a size, iterate through all TT fonts and load them in the provided size (only used for custom (non-hard-coded)
// font sizes)
void CreateSizeForAllTTFonts(const __in SHORT sSize)
{
auto hDC = CreateCompatibleDC(nullptr);
// for each font face
for (auto pFN = gpFaceNames; pFN; pFN = pFN->pNext)
{
if (pFN->dwFlag & EF_TTFONT)
{
// if it's a TT font, load the supplied size
DoFontEnum(hDC, pFN->atch, (PSHORT)&sSize, 1);
}
}
}
[[nodiscard]] NTSTATUS
EnumerateFonts(
DWORD Flags)
@@ -997,7 +672,7 @@ EnumerateFonts(
// All facenames found will be put in gpFaceNames with
// the EF_NEW bit set.
//
DoFontEnum(hDC, nullptr, TTPoints, 1);
DoFontEnum(hDC, nullptr);
gbEnumerateFaces = FALSE;
}
@@ -1026,36 +701,17 @@ EnumerateFonts(
continue;
}
if (pFN->dwFlag & EF_TTFONT)
{
if (g_fEastAsianSystem && !IsAvailableTTFontCP(pFN->atch, 0))
DoFontEnum(hDC, pFN->atch, TTPointsDbcs, ARRAYSIZE(TTPointsDbcs));
else
DoFontEnum(hDC, pFN->atch, TTPoints, ARRAYSIZE(TTPoints));
}
else
{
DoFontEnum(hDC, pFN->atch, nullptr, 0);
}
DoFontEnum(hDC, pFN->atch);
pFN->dwFlag |= EF_ENUMERATED;
}
// Now check to see if the currently selected font is using a custom size not in the hard-coded list (TTPoints or
// TTPointsDbcs depending on locale). If so, make sure we populate all of our fonts at that size.
if (IsCurrentFontSizeCustom())
{
CreateSizeForAllTTFonts(gpStateInfo->FontSize.Y);
}
DeleteDC(hDC);
if (g_fEastAsianSystem)
{
for (FontIndex = 0; FontIndex < NumberOfFonts; FontIndex++)
{
if (FontInfo[FontIndex].Size.X == DefaultFontSize.X &&
FontInfo[FontIndex].Size.Y == DefaultFontSize.Y &&
IS_DBCS_OR_OEM_CHARSET(FontInfo[FontIndex].tmCharSet) &&
if (IS_DBCS_OR_OEM_CHARSET(FontInfo[FontIndex].tmCharSet) &&
FontInfo[FontIndex].Family == DefaultFontFamily)
{
break;
@@ -1066,9 +722,7 @@ EnumerateFonts(
{
for (FontIndex = 0; FontIndex < NumberOfFonts; FontIndex++)
{
if (FontInfo[FontIndex].Size.X == DefaultFontSize.X &&
FontInfo[FontIndex].Size.Y == DefaultFontSize.Y &&
FontInfo[FontIndex].Family == DefaultFontFamily)
if (FontInfo[FontIndex].Family == DefaultFontFamily)
{
break;
}
@@ -1086,5 +740,21 @@ EnumerateFonts(
DBGFONTS(("EnumerateFonts : DefaultFontIndex = %ld\n", DefaultFontIndex));
std::vector<std::wstring> fonts;
for (FontIndex = 0; FontIndex < NumberOfFonts; FontIndex++)
{
const auto& f = FontInfo[FontIndex];
wchar_t buffer[512];
const auto len = swprintf_s(buffer, L"%-32s %4d %4d %4d\n", f.FaceName, f.Weight, f.Family, f.tmCharSet);
fonts.emplace_back(&buffer[0], len);
}
std::stable_sort(fonts.begin(), fonts.end());
for (const auto& s : fonts)
{
OutputDebugStringW(s.c_str());
}
return STATUS_SUCCESS;
}

View File

@@ -52,8 +52,6 @@ VOID UpdatePreviewRect(VOID)
--*/
{
POINT MinSize;
POINT MaxSize;
POINT WindowSize;
PFONT_INFO lpFont;
HMONITOR hMonitor;
@@ -67,12 +65,8 @@ VOID UpdatePreviewRect(VOID)
/*
* Get the window size
*/
MinSize.x = (GetSystemMetrics(SM_CXMIN) - NonClientSize.x) / lpFont->Size.X;
MinSize.y = (GetSystemMetrics(SM_CYMIN) - NonClientSize.y) / lpFont->Size.Y;
MaxSize.x = GetSystemMetrics(SM_CXFULLSCREEN) / lpFont->Size.X;
MaxSize.y = GetSystemMetrics(SM_CYFULLSCREEN) / lpFont->Size.Y;
WindowSize.x = std::max(MinSize.x, std::min<LONG>(MaxSize.x, gpStateInfo->WindowSize.X));
WindowSize.y = std::max(MinSize.y, std::min<LONG>(MaxSize.y, gpStateInfo->WindowSize.Y));
WindowSize.x = gpStateInfo->WindowSize.X;
WindowSize.y = gpStateInfo->WindowSize.Y;
/*
* Get the window rectangle, making sure it's at least twice the
@@ -80,13 +74,13 @@ VOID UpdatePreviewRect(VOID)
*/
WindowRect.left = gpStateInfo->WindowPosX;
WindowRect.top = gpStateInfo->WindowPosY;
WindowRect.right = WindowSize.x * lpFont->Size.X + NonClientSize.x;
WindowRect.right = NonClientSize.x;
if (WindowRect.right < NonClientSize.x * 2)
{
WindowRect.right = NonClientSize.x * 2;
}
WindowRect.right += WindowRect.left;
WindowRect.bottom = WindowSize.y * lpFont->Size.Y + NonClientSize.y;
WindowRect.bottom = NonClientSize.y;
if (WindowRect.bottom < NonClientSize.y * 2)
{
WindowRect.bottom = NonClientSize.y * 2;

View File

@@ -46,29 +46,6 @@ int __cdecl wmain(int /*argc*/, WCHAR* /*argv[]*/)
#define CP_SC ((UINT)936)
#define IsEastAsianCP(cp) ((cp) == CP_JPN || (cp) == CP_WANSUNG || (cp) == CP_TC || (cp) == CP_SC)
/*
* TTPoints -- Initial font pixel heights for TT fonts
* NOTE:
* Font pixel heights for TT fonts of DBCS are the same list except
* odd point size because font width is (SBCS:DBCS != 1:2).
*/
SHORT TTPoints[] = {
5,
6,
7,
8,
10,
12,
14,
16,
18,
20,
24,
28,
36,
72
};
int CALLBACK FontEnumForV2Console(ENUMLOGFONT* pelf, NEWTEXTMETRIC* pntm, int nFontType, LPARAM lParam)
{
UINT i;
@@ -188,28 +165,7 @@ int CALLBACK FontEnumForV2Console(ENUMLOGFONT* pelf, NEWTEXTMETRIC* pntm, int nF
return CONTINUE_ENUM;
}
if (nFontType & TRUETYPE_FONTTYPE)
{
for (i = 0; i < ARRAYSIZE(TTPoints); i++)
{
pelf->elfLogFont.lfHeight = TTPoints[i];
// If it's an East Asian enum, skip all odd height fonts.
if (fIsEastAsianCP && (pelf->elfLogFont.lfHeight % 2) != 0)
{
continue;
}
pelf->elfLogFont.lfWidth = 0;
pelf->elfLogFont.lfWeight = pntm->tmWeight;
AddFont(pelf, pntm, nFontType, (HDC)lParam);
}
}
else
{
AddFont(pelf, pntm, nFontType, (HDC)lParam);
}
AddFont(pelf, pntm, nFontType, (HDC)lParam);
return CONTINUE_ENUM; // and continue enumeration
}