in src/propsheet/fontdlg.cpp [1123:1361]
int FindCreateFont(
__in DWORD Family,
__in_ecount(LF_FACESIZE) LPWSTR pwszFace,
__in COORD Size,
__in LONG Weight,
__in UINT CodePage)
{
#define NOT_CREATED_NOR_FOUND -1
#define CREATED_BUT_NOT_FOUND -2
int FontIndex = NOT_CREATED_NOR_FOUND;
BOOL bFontOK;
WCHAR AltFaceName[LF_FACESIZE];
COORD AltFontSize;
BYTE AltFontFamily;
ULONG AltFontIndex = 0, i;
LPWSTR pwszAltFace;
BYTE CharSet = CodePageToCharSet(CodePage);
FAIL_FAST_IF(!(OEMCP != 0));
DBGFONTS(("FindCreateFont Family=%x %ls (%d,%d) %d %d %x\n",
Family,
pwszFace,
Size.X,
Size.Y,
Weight,
CodePage,
CharSet));
if (g_fEastAsianSystem)
{
if (IS_DBCS_OR_OEM_CHARSET(CharSet))
{
if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
{
pwszFace = DefaultFaceName;
}
if (Size.Y == 0)
{
Size = DefaultFontSize;
}
}
else
{
MakeAltRasterFont(CodePage, &AltFontSize, &AltFontFamily, &AltFontIndex, AltFaceName);
if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
{
pwszFace = AltFaceName;
}
if (Size.Y == 0)
{
Size.X = AltFontSize.X;
Size.Y = AltFontSize.Y;
}
}
}
else
{
if (pwszFace == nullptr || *pwszFace == TEXT('\0'))
{
pwszFace = DefaultFaceName;
}
if (Size.Y == 0)
{
Size = DefaultFontSize;
}
}
// If _DefaultTTFont_ is specified, find the appropriate face name for our current codepage.
if (wcscmp(pwszFace, DEFAULT_TT_FONT_FACENAME) == 0)
{
// retrieve default font face name for this codepage, and then set it as our current face
WCHAR szDefaultCodepageTTFont[LF_FACESIZE] = { 0 };
if (NT_SUCCESS(GetTTFontFaceForCodePage(CodePage, szDefaultCodepageTTFont, ARRAYSIZE(szDefaultCodepageTTFont))) &&
NT_SUCCESS(StringCchCopyW(DefaultTTFaceName, ARRAYSIZE(DefaultTTFaceName), szDefaultCodepageTTFont)))
{
pwszFace = DefaultTTFaceName;
Size.X = 0;
}
}
if (ShouldAllowAllMonoTTFonts() || IsAvailableTTFont(pwszFace))
{
pwszAltFace = GetAltFaceName(pwszFace);
}
else
{
pwszAltFace = pwszFace;
}
/*
* Try to find the exact font
*/
TryFindExactFont:
for (i = 0; i < NumberOfFonts; i++)
{
/*
* If looking for a particular Family, skip non-matches
*/
if (Family != 0 && (BYTE)Family != FontInfo[i].Family)
{
continue;
}
/*
* Skip non-matching sizes
*/
if ((FontInfo[i].SizeWant.Y != Size.Y) &&
!SIZE_EQUAL(FontInfo[i].Size, Size))
{
continue;
}
/*
* Skip non-matching weights
*/
if ((Weight != 0) && (Weight != FontInfo[i].Weight))
{
continue;
}
if (!TM_IS_TT_FONT(FontInfo[i].Family) &&
(FontInfo[i].tmCharSet != CharSet &&
!(FontInfo[i].tmCharSet == OEM_CHARSET && g_fEastAsianSystem)))
{
continue;
}
/*
* Size (and maybe Family) match. If we don't care about the name or
* if it matches, use this font. Otherwise, if name doesn't match and
* it is a raster font, consider it.
*/
if ((pwszFace == nullptr) || (pwszFace[0] == TEXT('\0')) ||
(lstrcmp(FontInfo[i].FaceName, pwszFace) == 0) ||
(lstrcmp(FontInfo[i].FaceName, pwszAltFace) == 0))
{
FontIndex = i;
goto FoundFont;
}
else if (!TM_IS_TT_FONT(FontInfo[i].Family))
{
FontIndex = i;
}
}
if (FontIndex == NOT_CREATED_NOR_FOUND)
{
/*
* Didn't find the exact font, so try to create it
*/
if (Size.Y < 0)
{
Size.Y = -Size.Y;
}
bFontOK = DoFontEnum(nullptr, pwszFace, &Size.Y, 1);
if (bFontOK)
{
DBGFONTS(("FindCreateFont created font!\n"));
FontIndex = CREATED_BUT_NOT_FOUND;
goto TryFindExactFont;
}
else
{
DBGFONTS(("FindCreateFont failed to create font!\n"));
}
}
else if (FontIndex >= 0)
{
// a close Raster Font fit - only the name doesn't match.
goto FoundFont;
}
/*
* Failed to find exact match, even after enumeration, so now try to find
* a font of same family and same size or bigger.
*/
for (i = 0; i < NumberOfFonts; i++)
{
if (g_fEastAsianSystem)
{
if (Family != 0 && (BYTE)Family != FontInfo[i].Family)
{
continue;
}
if (!TM_IS_TT_FONT(FontInfo[i].Family) &&
FontInfo[i].tmCharSet != CharSet)
{
continue;
}
}
else
{
if ((BYTE)Family != FontInfo[i].Family)
{
continue;
}
}
if (FontInfo[i].Size.Y >= Size.Y && FontInfo[i].Size.X >= Size.X)
{
// Same family, size >= desired.
FontIndex = i;
break;
}
}
if (FontIndex < 0)
{
DBGFONTS(("FindCreateFont defaults!\n"));
if (g_fEastAsianSystem)
{
if (CodePage == OEMCP)
{
FontIndex = DefaultFontIndex;
}
else
{
FontIndex = AltFontIndex;
}
}
else
{
FontIndex = DefaultFontIndex;
}
}
FoundFont:
FAIL_FAST_IF(!(FontIndex < (int)NumberOfFonts));
DBGFONTS(("FindCreateFont returns %x : %ls (%d,%d)\n", FontIndex, FontInfo[FontIndex].FaceName, FontInfo[FontIndex].Size.X, FontInfo[FontIndex].Size.Y));
return FontIndex;
#undef NOT_CREATED_NOR_FOUND
#undef CREATED_BUT_NOT_FOUND
}