in src/propsheet/fontdlg.cpp [688:893]
int FontListCreate(
__in HWND hDlg,
__in_ecount_opt(LF_FACESIZE) LPWSTR pwszTTFace,
__in BOOL bNewFaceList)
{
LONG lListIndex;
ULONG i;
HWND hWndShow; // List or Combo box
HWND hWndHide; // Combo or List box
HWND hWndFaceCombo;
BOOL bLB;
UINT CodePage = gpStateInfo->CodePage;
BOOL fFindTTFont = FALSE;
LPWSTR pwszAltTTFace;
LONG_PTR dwExStyle;
FAIL_FAST_IF(!(OEMCP != 0)); // must be initialized
bLB = ((pwszTTFace == nullptr) || (pwszTTFace[0] == TEXT('\0')));
if (bLB)
{
pwszAltTTFace = nullptr;
}
else
{
if (ShouldAllowAllMonoTTFonts() || IsAvailableTTFont(pwszTTFace))
{
pwszAltTTFace = GetAltFaceName(pwszTTFace);
}
else
{
pwszAltTTFace = pwszTTFace;
}
}
DBGFONTS(("FontListCreate %p, %s, %s new FaceList\n", hDlg, bLB ? "Raster" : "TrueType", bNewFaceList ? "Make" : "No"));
/*
* This only enumerates face names and font sizes if necessary.
*/
if (!NT_SUCCESS(EnumerateFonts(bLB ? EF_OEMFONT : EF_TTFONT)))
{
return LB_ERR;
}
/* init the TTFaceNames */
DBGFONTS((" Create %s fonts\n", bLB ? "Raster" : "TrueType"));
if (bNewFaceList)
{
PFACENODE panFace;
hWndFaceCombo = GetDlgItem(hDlg, IDD_FACENAME);
// empty faces list
SendMessage(hWndFaceCombo, LB_RESETCONTENT, 0, 0);
// before doing anything else, add raster fonts to the list. Note that the item data being set here indicates
// that it's a raster font. the actual font indices are stored as item data on the pixels list.
lListIndex = (LONG)SendMessage(hWndFaceCombo, LB_ADDSTRING, 0, (LPARAM)wszRasterFonts);
SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, TRUE);
DBGFONTS(("Added \"%ls\", set Item Data %d = TRUE\n", wszRasterFonts, lListIndex));
// now enumerate all of the new truetype font face names we've loaded that are appropriate for our codepage. add them to
// the faces list. if we find an exact match for pwszTTFace or pwszAltTTFace, note that in fFindTTFont.
for (panFace = gpFaceNames; panFace; panFace = panFace->pNext)
{
if ((panFace->dwFlag & (EF_TTFONT | EF_NEW)) != (EF_TTFONT | EF_NEW))
{
continue;
}
if (!g_fEastAsianSystem && (panFace->dwFlag & EF_DBCSFONT))
{
continue;
}
// NOTE: in v2 we don't depend on the registry list to determine if a TT font should be listed in the font
// face dialog list -- this is handled in DoFontEnum by using the FontEnumForV2Console enumerator
if (ShouldAllowAllMonoTTFonts() ||
(g_fEastAsianSystem && IsAvailableTTFontCP(panFace->atch, CodePage)) ||
(!g_fEastAsianSystem && IsAvailableTTFontCP(panFace->atch, 0)))
{
if (!bLB &&
(lstrcmp(pwszTTFace, panFace->atch) == 0 ||
lstrcmp(pwszAltTTFace, panFace->atch) == 0))
{
fFindTTFont = TRUE;
}
lListIndex = (LONG)SendMessage(hWndFaceCombo, LB_ADDSTRING, 0, (LPARAM)panFace->atch);
SendMessage(hWndFaceCombo, LB_SETITEMDATA, lListIndex, FALSE);
DBGFONTS(("Added \"%ls\", set Item Data %d = FALSE\n",
panFace->atch,
lListIndex));
}
}
// if we haven't found the specific TT font we're looking for, choose *any* TT font that's appropriate for our
// codepage
if (!bLB && !fFindTTFont)
{
for (panFace = gpFaceNames; panFace; panFace = panFace->pNext)
{
if ((panFace->dwFlag & (EF_TTFONT | EF_NEW)) != (EF_TTFONT | EF_NEW))
{
continue;
}
if (!g_fEastAsianSystem && (panFace->dwFlag & EF_DBCSFONT))
{
continue;
}
if ((g_fEastAsianSystem && IsAvailableTTFontCP(panFace->atch, CodePage)) ||
(!g_fEastAsianSystem && IsAvailableTTFontCP(panFace->atch, 0)))
{
if (lstrcmp(pwszTTFace, panFace->atch) != 0)
{
// found a reasonably appropriate font that isn't the one being requested (we couldn't find that
// one). use this one instead.
StringCchCopy(pwszTTFace,
LF_FACESIZE,
panFace->atch);
break;
}
}
}
}
}
// update the state of the bold checkbox. check the box if the currently selected TT font is bold. some TT fonts
// aren't allowed to be bold depending on the charset. also, raster fonts aren't allowed to be bold.
hWndShow = GetDlgItem(hDlg, IDD_BOLDFONT);
/*
* For JAPAN, We uses "MS Gothic" TT font.
* So, Bold of this font is not 1:2 width between SBCS:DBCS.
*/
if (g_fEastAsianSystem && IsDisableBoldTTFont(pwszTTFace))
{
EnableWindow(hWndShow, FALSE);
gbBold = FALSE;
CheckDlgButton(hDlg, IDD_BOLDFONT, FALSE);
}
else
{
CheckDlgButton(hDlg, IDD_BOLDFONT, (bLB || !gbBold) ? FALSE : TRUE);
EnableWindow(hWndShow, bLB ? FALSE : TRUE);
}
// if the current font is raster, disable and hide the point size list.
// if the current font is TT, disable and hide the pixel size list.
hWndHide = GetDlgItem(hDlg, bLB ? IDD_POINTSLIST : IDD_PIXELSLIST);
ShowWindow(hWndHide, SW_HIDE);
EnableWindow(hWndHide, FALSE);
// if the current font is raster, enable and show the pixel size list.
// if the current font is TT, enable and show the point size list.
hWndShow = GetDlgItem(hDlg, bLB ? IDD_PIXELSLIST : IDD_POINTSLIST);
ShowWindow(hWndShow, SW_SHOW);
EnableWindow(hWndShow, TRUE);
// if we're building a new face list (basically any time we're not handling a selection change), empty the contents
// of the pixel size list (raster) or point size list (TT) as appropriate.
if (bNewFaceList)
{
lcbRESETCONTENT(hWndShow, bLB);
}
dwExStyle = GetWindowLongPtr(hWndShow, GWL_EXSTYLE);
if ((dwExStyle & WS_EX_LAYOUTRTL) && !(dwExStyle & WS_EX_RTLREADING))
{
// if mirrored RTL Reading means LTR !!
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).
*/
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;
}