From b229afbe8cc10e30e2df32d748f132137029e565 Mon Sep 17 00:00:00 2001 From: Leonard Hecker Date: Wed, 22 Nov 2023 16:24:10 +0100 Subject: [PATCH] wip --- src/propsheet/console.cpp | 8 +- src/propsheet/dbcs.cpp | 7 +- src/propsheet/font.h | 12 +- src/propsheet/fontdlg.cpp | 338 +++++-------------------------- src/propsheet/misc.cpp | 388 +++--------------------------------- src/propsheet/preview.cpp | 14 +- src/tools/fontlist/main.cpp | 46 +---- 7 files changed, 86 insertions(+), 727 deletions(-) diff --git a/src/propsheet/console.cpp b/src/propsheet/console.cpp index 68b146c2e11..f70ab35e8f5 100644 --- a/src/propsheet/console.cpp +++ b/src/propsheet/console.cpp @@ -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); } diff --git a/src/propsheet/dbcs.cpp b/src/propsheet/dbcs.cpp index a7d14a46105..ef34168456d 100644 --- a/src/propsheet/dbcs.cpp +++ b/src/propsheet/dbcs.cpp @@ -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)); diff --git a/src/propsheet/font.h b/src/propsheet/font.h index d9d0b2d21e8..1f6a2d3dc0c 100644 --- a/src/propsheet/font.h +++ b/src/propsheet/font.h @@ -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 */ diff --git a/src/propsheet/fontdlg.cpp b/src/propsheet/fontdlg.cpp index 96afbcacb05..e082c8d3f70 100644 --- a/src/propsheet/fontdlg.cpp +++ b/src/propsheet/fontdlg.cpp @@ -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,32 +610,50 @@ int FontListCreate( SetWindowLongPtr(hWndShow, GWL_EXSTYLE, dwExStyle | WS_EX_RTLREADING); } - /* Initialize hWndShow list/combo box */ - - const BOOL fIsBoldOnlyTTFont = (!bLB && IsBoldOnlyTTFont(pwszTTFace, pwszAltTTFace)); + /* + * Get the FontIndex from the currently selected item. + * (i will be LB_ERR if no currently selected item). + */ + lListIndex = lcbGETCURSEL(hWndShow, bLB); + i = lcbGETITEMDATA(hWndShow, bLB, lListIndex); - AddFontSizesToList(pwszTTFace, - pwszAltTTFace, - dwExStyle, - g_fEastAsianSystem, - bLB, - hWndShow, - fIsBoldOnlyTTFont); + /* 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 (fIsBoldOnlyTTFont) + 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); } - /* - * Get the FontIndex from the currently selected item. - * (i will be LB_ERR if no currently selected item). - */ - lListIndex = lcbGETCURSEL(hWndShow, bLB); - i = lcbGETITEMDATA(hWndShow, bLB, lListIndex); - 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 @@ int FindCreateFont( 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 @@ int FindCreateFont( { 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 @@ int FindCreateFont( 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); diff --git a/src/propsheet/misc.cpp b/src/propsheet/misc.cpp index 054eef96121..ffd8699c3f8 100644 --- a/src/propsheet/misc.cpp +++ b/src/propsheet/misc.cpp @@ -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 @@ int AddFont( 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 @@ int AddFont( */ 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 @@ int AddFont( 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 @@ int AddFont( 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 @@ int AddFont( 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) - { - 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) { - 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 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; } diff --git a/src/propsheet/preview.cpp b/src/propsheet/preview.cpp index 64ed9fae402..fec212d6084 100644 --- a/src/propsheet/preview.cpp +++ b/src/propsheet/preview.cpp @@ -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(MaxSize.x, gpStateInfo->WindowSize.X)); - WindowSize.y = std::max(MinSize.y, std::min(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; diff --git a/src/tools/fontlist/main.cpp b/src/tools/fontlist/main.cpp index a22e289cdeb..d0ec84a8215 100644 --- a/src/tools/fontlist/main.cpp +++ b/src/tools/fontlist/main.cpp @@ -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 }