mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[GDI32][NTGDI][SETUP] Fix font enumeration part 2 (#1492)
Eliminate some bugs about font enumeration. CORE-15755 - Add "Microsoft Sans Serif" font substitution. - Fix and improve the treatment of the nominal font names. - Split IntGetFontFamilyInfo function from NtGdiGetFontFamilyInfo. - Add DoFontSystemUnittest function for font system unittest to GDI32. - Call DoFontSystemUnittest function at CreateFontIndirectW first call.
This commit is contained in:
parent
cfdf36e442
commit
811faed421
5 changed files with 252 additions and 96 deletions
|
@ -11,6 +11,7 @@ MUI_SUBFONT LatinFonts[] =
|
||||||
{ L"Helv", L"Tahoma" },
|
{ L"Helv", L"Tahoma" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Sans Serif", L"Tahoma" },
|
{ L"MS Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg", L"Tahoma" },
|
{ L"MS Shell Dlg", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg 2", L"Tahoma" },
|
{ L"MS Shell Dlg 2", L"Tahoma" },
|
||||||
|
@ -37,6 +38,7 @@ MUI_SUBFONT CyrillicFonts[] =
|
||||||
{ L"Helv", L"Tahoma" },
|
{ L"Helv", L"Tahoma" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Sans Serif", L"Tahoma" },
|
{ L"MS Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg", L"Tahoma" },
|
{ L"MS Shell Dlg", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg 2", L"Tahoma" },
|
{ L"MS Shell Dlg 2", L"Tahoma" },
|
||||||
|
@ -63,6 +65,7 @@ MUI_SUBFONT GreekFonts[] =
|
||||||
{ L"Helv", L"DejaVu Sans" },
|
{ L"Helv", L"DejaVu Sans" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"DejaVu Sans" },
|
||||||
{ L"MS Sans Serif", L"DejaVu Sans" },
|
{ L"MS Sans Serif", L"DejaVu Sans" },
|
||||||
{ L"MS Shell Dlg", L"DejaVu Sans" },
|
{ L"MS Shell Dlg", L"DejaVu Sans" },
|
||||||
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
|
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
|
||||||
|
@ -89,6 +92,7 @@ MUI_SUBFONT HebrewFonts[] =
|
||||||
{ L"Helv", L"Tahoma" },
|
{ L"Helv", L"Tahoma" },
|
||||||
{ L"Helvetica", L"Tahoma" },
|
{ L"Helvetica", L"Tahoma" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Sans Serif", L"Tahoma" },
|
{ L"MS Sans Serif", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg", L"Tahoma" },
|
{ L"MS Shell Dlg", L"Tahoma" },
|
||||||
{ L"MS Shell Dlg 2", L"Tahoma" },
|
{ L"MS Shell Dlg 2", L"Tahoma" },
|
||||||
|
@ -121,6 +125,7 @@ MUI_SUBFONT ChineseSimplifiedFonts[] =
|
||||||
{ L"Helv", L"Droid Sans Fallback" },
|
{ L"Helv", L"Droid Sans Fallback" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
||||||
|
@ -163,6 +168,7 @@ MUI_SUBFONT ChineseTraditionalFonts[] =
|
||||||
{ L"Helv", L"Droid Sans Fallback" },
|
{ L"Helv", L"Droid Sans Fallback" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
||||||
|
@ -206,6 +212,7 @@ MUI_SUBFONT JapaneseFonts[] =
|
||||||
{ L"Helv", L"Droid Sans Fallback" },
|
{ L"Helv", L"Droid Sans Fallback" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
||||||
|
@ -250,6 +257,7 @@ MUI_SUBFONT KoreanFonts[] =
|
||||||
{ L"Helv", L"Droid Sans Fallback" },
|
{ L"Helv", L"Droid Sans Fallback" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
{ L"MS Sans Serif", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg", L"Droid Sans Fallback" },
|
||||||
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
{ L"MS Shell Dlg 2", L"Droid Sans Fallback" },
|
||||||
|
@ -293,6 +301,7 @@ MUI_SUBFONT UnicodeFonts[] =
|
||||||
{ L"Helv", L"DejaVu Sans" },
|
{ L"Helv", L"DejaVu Sans" },
|
||||||
{ L"Helvetica", L"DejaVu Sans" },
|
{ L"Helvetica", L"DejaVu Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"DejaVu Sans" },
|
||||||
{ L"MS Sans Serif", L"DejaVu Sans" },
|
{ L"MS Sans Serif", L"DejaVu Sans" },
|
||||||
{ L"MS Shell Dlg", L"DejaVu Sans" },
|
{ L"MS Shell Dlg", L"DejaVu Sans" },
|
||||||
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
|
{ L"MS Shell Dlg 2", L"DejaVu Sans" },
|
||||||
|
@ -320,6 +329,7 @@ MUI_SUBFONT HindiFonts[] =
|
||||||
{ L"Helv", L"Tahoma" },
|
{ L"Helv", L"Tahoma" },
|
||||||
{ L"Helvetica", L"Liberation Sans" },
|
{ L"Helvetica", L"Liberation Sans" },
|
||||||
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
{ L"Lucida Console", L"DejaVu Sans Mono" },
|
||||||
|
{ L"Microsoft Sans Serif", L"FreeSans" },
|
||||||
{ L"MS Sans Serif", L"FreeSans" },
|
{ L"MS Sans Serif", L"FreeSans" },
|
||||||
{ L"MS Shell Dlg", L"FreeSans" },
|
{ L"MS Shell Dlg", L"FreeSans" },
|
||||||
{ L"MS Shell Dlg 2", L"FreeSans" },
|
{ L"MS Shell Dlg 2", L"FreeSans" },
|
||||||
|
|
|
@ -50,6 +50,7 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Fixedsys",0
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Helv",0x00000000,"Tahoma"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Helv",0x00000000,"Tahoma"
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Helvetica",0x00000000,"Liberation Sans"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Helvetica",0x00000000,"Liberation Sans"
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Lucida Console",0x00000000,"DejaVu Sans Mono"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Lucida Console",0x00000000,"DejaVu Sans Mono"
|
||||||
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","Microsoft Sans Serif",0x00000000,"Tahoma"
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Sans Serif",0x00000000,"Tahoma"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Sans Serif",0x00000000,"Tahoma"
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Shell Dlg",0x00000000,"Tahoma"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Shell Dlg",0x00000000,"Tahoma"
|
||||||
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Shell Dlg 2",0x00000000,"Tahoma"
|
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes","MS Shell Dlg 2",0x00000000,"Tahoma"
|
||||||
|
|
|
@ -218,6 +218,13 @@ IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
|
||||||
int cmp = _wcsicmp(plf1->lfFaceName, plf2->lfFaceName);
|
int cmp = _wcsicmp(plf1->lfFaceName, plf2->lfFaceName);
|
||||||
if (cmp)
|
if (cmp)
|
||||||
return cmp;
|
return cmp;
|
||||||
|
if (dwCompareFlags & IFFCX_CHARSET)
|
||||||
|
{
|
||||||
|
if (plf1->lfCharSet < plf2->lfCharSet)
|
||||||
|
return -1;
|
||||||
|
if (plf1->lfCharSet > plf2->lfCharSet)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (dwCompareFlags & IFFCX_STYLE)
|
if (dwCompareFlags & IFFCX_STYLE)
|
||||||
{
|
{
|
||||||
WeightDiff1 = labs(plf1->lfWeight - FW_NORMAL);
|
WeightDiff1 = labs(plf1->lfWeight - FW_NORMAL);
|
||||||
|
@ -231,13 +238,6 @@ IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
|
||||||
if (plf1->lfItalic > plf2->lfItalic)
|
if (plf1->lfItalic > plf2->lfItalic)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (dwCompareFlags & IFFCX_CHARSET)
|
|
||||||
{
|
|
||||||
if (plf1->lfCharSet < plf2->lfCharSet)
|
|
||||||
return -1;
|
|
||||||
if (plf1->lfCharSet > plf2->lfCharSet)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
|
||||||
first = InfoList;
|
first = InfoList;
|
||||||
last = &InfoList[nCount];
|
last = &InfoList[nCount];
|
||||||
|
|
||||||
// std::unique(first, last, IntFontFamilyCompareEx);
|
/* std::unique(first, last, IntFontFamilyCompareEx); */
|
||||||
if (first == last)
|
if (first == last)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -285,60 +285,70 @@ IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FASTCALL
|
static int FASTCALL
|
||||||
IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
|
IntEnumFontFamilies(HDC Dc, const LOGFONTW *LogFont, PVOID EnumProc, LPARAM lParam,
|
||||||
DWORD dwFlags)
|
DWORD dwFlags)
|
||||||
{
|
{
|
||||||
int FontFamilyCount;
|
int FontFamilyCount;
|
||||||
int FontFamilySize;
|
|
||||||
PFONTFAMILYINFO Info;
|
PFONTFAMILYINFO Info;
|
||||||
int Ret = 1;
|
int Ret = 1;
|
||||||
int i;
|
int i;
|
||||||
ENUMLOGFONTEXA EnumLogFontExA;
|
ENUMLOGFONTEXA EnumLogFontExA;
|
||||||
NEWTEXTMETRICEXA NewTextMetricExA;
|
NEWTEXTMETRICEXA NewTextMetricExA;
|
||||||
LOGFONTW lfW;
|
LOGFONTW lfW;
|
||||||
|
LONG DataSize, InfoCount;
|
||||||
|
|
||||||
Info = RtlAllocateHeap(GetProcessHeap(), 0,
|
DataSize = INITIAL_FAMILY_COUNT * sizeof(FONTFAMILYINFO);
|
||||||
INITIAL_FAMILY_COUNT * sizeof(FONTFAMILYINFO));
|
Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
|
||||||
if (NULL == Info)
|
if (Info == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the LOGFONT structure */
|
||||||
|
ZeroMemory(&lfW, sizeof(lfW));
|
||||||
if (!LogFont)
|
if (!LogFont)
|
||||||
{
|
{
|
||||||
lfW.lfCharSet = DEFAULT_CHARSET;
|
lfW.lfCharSet = DEFAULT_CHARSET;
|
||||||
lfW.lfPitchAndFamily = 0;
|
}
|
||||||
lfW.lfFaceName[0] = 0;
|
else
|
||||||
LogFont = &lfW;
|
{
|
||||||
|
lfW.lfCharSet = LogFont->lfCharSet;
|
||||||
|
lfW.lfPitchAndFamily = LogFont->lfPitchAndFamily;
|
||||||
|
StringCbCopyW(lfW.lfFaceName, sizeof(lfW.lfFaceName), LogFont->lfFaceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, LogFont, Info, INITIAL_FAMILY_COUNT);
|
/* Retrieve the font information */
|
||||||
|
InfoCount = INITIAL_FAMILY_COUNT;
|
||||||
|
FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, &lfW, Info, &InfoCount);
|
||||||
if (FontFamilyCount < 0)
|
if (FontFamilyCount < 0)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (INITIAL_FAMILY_COUNT < FontFamilyCount)
|
|
||||||
|
/* Resize the buffer if the buffer is too small */
|
||||||
|
if (INITIAL_FAMILY_COUNT < InfoCount)
|
||||||
{
|
{
|
||||||
FontFamilySize = FontFamilyCount;
|
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
||||||
Info = RtlAllocateHeap(GetProcessHeap(), 0,
|
DataSize = InfoCount * sizeof(FONTFAMILYINFO);
|
||||||
FontFamilyCount * sizeof(FONTFAMILYINFO));
|
Info = RtlAllocateHeap(GetProcessHeap(), 0, DataSize);
|
||||||
if (NULL == Info)
|
if (Info == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, LogFont, Info, FontFamilySize);
|
FontFamilyCount = NtGdiGetFontFamilyInfo(Dc, &lfW, Info, &InfoCount);
|
||||||
if (FontFamilyCount < 0 || FontFamilySize < FontFamilyCount)
|
if (FontFamilyCount < 0 || FontFamilyCount < InfoCount)
|
||||||
{
|
{
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
RtlFreeHeap(GetProcessHeap(), 0, Info);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort and remove redundant information */
|
||||||
qsort(Info, FontFamilyCount, sizeof(*Info), IntFontFamilyCompare);
|
qsort(Info, FontFamilyCount, sizeof(*Info), IntFontFamilyCompare);
|
||||||
FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, LogFont, dwFlags);
|
FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, &lfW, dwFlags);
|
||||||
|
|
||||||
|
/* call the callback */
|
||||||
for (i = 0; i < FontFamilyCount; i++)
|
for (i = 0; i < FontFamilyCount; i++)
|
||||||
{
|
{
|
||||||
if (dwFlags & IEFF_UNICODE)
|
if (dwFlags & IEFF_UNICODE)
|
||||||
|
@ -1693,6 +1703,78 @@ CreateFontIndirectA(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
VOID DumpFamilyInfo(const FONTFAMILYINFO *Info, LONG Count)
|
||||||
|
{
|
||||||
|
LONG i;
|
||||||
|
const LOGFONTW *plf;
|
||||||
|
|
||||||
|
DPRINT1("---\n");
|
||||||
|
DPRINT1("Count: %d\n", Count);
|
||||||
|
for (i = 0; i < Count; ++i)
|
||||||
|
{
|
||||||
|
plf = &Info[i].EnumLogFontEx.elfLogFont;
|
||||||
|
DPRINT1("%d: '%S',%u,'%S', %ld:%ld, %ld, %d, %d\n", i,
|
||||||
|
plf->lfFaceName, plf->lfCharSet, Info[i].EnumLogFontEx.elfFullName,
|
||||||
|
plf->lfHeight, plf->lfWidth, plf->lfWeight, plf->lfItalic, plf->lfPitchAndFamily);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID DoFontSystemUnittest(VOID)
|
||||||
|
{
|
||||||
|
LOGFONTW LogFont;
|
||||||
|
FONTFAMILYINFO Info[4];
|
||||||
|
UNICODE_STRING Str1, Str2;
|
||||||
|
LONG ret, InfoCount;
|
||||||
|
|
||||||
|
//DumpFontInfo(TRUE);
|
||||||
|
|
||||||
|
/* L"" DEFAULT_CHARSET */
|
||||||
|
RtlZeroMemory(&LogFont, sizeof(LogFont));
|
||||||
|
LogFont.lfCharSet = DEFAULT_CHARSET;
|
||||||
|
InfoCount = RTL_NUMBER_OF(Info);
|
||||||
|
ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
|
||||||
|
DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
|
||||||
|
DumpFamilyInfo(Info, ret);
|
||||||
|
ASSERT(ret == RTL_NUMBER_OF(Info));
|
||||||
|
ASSERT(InfoCount > 32);
|
||||||
|
|
||||||
|
/* L"Microsoft Sans Serif" ANSI_CHARSET */
|
||||||
|
RtlZeroMemory(&LogFont, sizeof(LogFont));
|
||||||
|
LogFont.lfCharSet = ANSI_CHARSET;
|
||||||
|
StringCbCopyW(LogFont.lfFaceName, sizeof(LogFont.lfFaceName), L"Microsoft Sans Serif");
|
||||||
|
InfoCount = RTL_NUMBER_OF(Info);
|
||||||
|
ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
|
||||||
|
DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
|
||||||
|
DumpFamilyInfo(Info, ret);
|
||||||
|
ASSERT(ret != -1);
|
||||||
|
ASSERT(InfoCount > 0);
|
||||||
|
ASSERT(InfoCount < 16);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Str1, Info[0].EnumLogFontEx.elfLogFont.lfFaceName);
|
||||||
|
RtlInitUnicodeString(&Str2, L"Microsoft Sans Serif");
|
||||||
|
ret = RtlCompareUnicodeString(&Str1, &Str2, TRUE);
|
||||||
|
ASSERT(ret == 0);
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Str1, Info[0].EnumLogFontEx.elfFullName);
|
||||||
|
RtlInitUnicodeString(&Str2, L"Tahoma");
|
||||||
|
ret = RtlCompareUnicodeString(&Str1, &Str2, TRUE);
|
||||||
|
ASSERT(ret == 0);
|
||||||
|
|
||||||
|
/* L"Non-Existent" DEFAULT_CHARSET */
|
||||||
|
RtlZeroMemory(&LogFont, sizeof(LogFont));
|
||||||
|
LogFont.lfCharSet = ANSI_CHARSET;
|
||||||
|
StringCbCopyW(LogFont.lfFaceName, sizeof(LogFont.lfFaceName), L"Non-Existent");
|
||||||
|
InfoCount = RTL_NUMBER_OF(Info);
|
||||||
|
ret = NtGdiGetFontFamilyInfo(NULL, &LogFont, Info, &InfoCount);
|
||||||
|
DPRINT1("ret: %ld, InfoCount: %ld\n", ret, InfoCount);
|
||||||
|
DumpFamilyInfo(Info, ret);
|
||||||
|
ASSERT(ret == 0);
|
||||||
|
ASSERT(InfoCount == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* EOF */
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -1702,6 +1784,14 @@ CreateFontIndirectW(
|
||||||
CONST LOGFONTW *lplf
|
CONST LOGFONTW *lplf
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#if DBG
|
||||||
|
static BOOL bDidTest = FALSE;
|
||||||
|
if (!bDidTest)
|
||||||
|
{
|
||||||
|
DoFontSystemUnittest();
|
||||||
|
bDidTest = TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (lplf)
|
if (lplf)
|
||||||
{
|
{
|
||||||
ENUMLOGFONTEXDVW Logfont;
|
ENUMLOGFONTEXDVW Logfont;
|
||||||
|
|
|
@ -2675,18 +2675,18 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOLEAN FASTCALL
|
static BOOLEAN FASTCALL
|
||||||
GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
GetFontFamilyInfoForList(const LOGFONTW *LogFont,
|
||||||
PFONTFAMILYINFO Info,
|
PFONTFAMILYINFO Info,
|
||||||
LPCWSTR NominalName,
|
LPCWSTR NominalName,
|
||||||
DWORD *pCount,
|
LONG *pCount,
|
||||||
DWORD MaxCount,
|
LONG MaxCount,
|
||||||
PLIST_ENTRY Head)
|
PLIST_ENTRY Head)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
PFONT_ENTRY CurrentEntry;
|
PFONT_ENTRY CurrentEntry;
|
||||||
FONTGDI *FontGDI;
|
FONTGDI *FontGDI;
|
||||||
FONTFAMILYINFO InfoEntry;
|
FONTFAMILYINFO InfoEntry;
|
||||||
DWORD Count = *pCount;
|
LONG Count = *pCount;
|
||||||
|
|
||||||
for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
|
for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
|
||||||
{
|
{
|
||||||
|
@ -2697,29 +2697,15 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
||||||
if (LogFont->lfCharSet != DEFAULT_CHARSET &&
|
if (LogFont->lfCharSet != DEFAULT_CHARSET &&
|
||||||
LogFont->lfCharSet != FontGDI->CharSet)
|
LogFont->lfCharSet != FontGDI->CharSet)
|
||||||
{
|
{
|
||||||
continue;
|
continue; /* charset mismatch */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogFont->lfFaceName[0] == UNICODE_NULL)
|
/* get one info entry */
|
||||||
{
|
FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI);
|
||||||
if (Count < MaxCount)
|
|
||||||
{
|
|
||||||
FontFamilyFillInfo(&Info[Count], NominalName, NULL, FontGDI);
|
|
||||||
}
|
|
||||||
Count++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontFamilyFillInfo(&InfoEntry, NominalName, NULL, FontGDI);
|
if (LogFont->lfFaceName[0] != UNICODE_NULL)
|
||||||
|
|
||||||
if (NominalName)
|
|
||||||
{
|
|
||||||
RtlStringCchCopyW(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
|
|
||||||
RTL_NUMBER_OF(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
|
|
||||||
NominalName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
/* check name */
|
||||||
if (_wcsnicmp(LogFont->lfFaceName,
|
if (_wcsnicmp(LogFont->lfFaceName,
|
||||||
InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
|
InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
|
||||||
RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
|
RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
|
||||||
|
@ -2731,7 +2717,16 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Count < MaxCount)
|
if (NominalName)
|
||||||
|
{
|
||||||
|
/* store the nominal name */
|
||||||
|
RtlStringCbCopyW(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
|
||||||
|
sizeof(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
|
||||||
|
NominalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store one entry to Info */
|
||||||
|
if (0 <= Count && Count < MaxCount)
|
||||||
{
|
{
|
||||||
RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
|
RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
|
||||||
}
|
}
|
||||||
|
@ -2744,10 +2739,10 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOLEAN FASTCALL
|
static BOOLEAN FASTCALL
|
||||||
GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
|
GetFontFamilyInfoForSubstitutes(const LOGFONTW *LogFont,
|
||||||
PFONTFAMILYINFO Info,
|
PFONTFAMILYINFO Info,
|
||||||
DWORD *pCount,
|
LONG *pCount,
|
||||||
DWORD MaxCount)
|
LONG MaxCount)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
|
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
|
||||||
PFONTSUBST_ENTRY pCurrentEntry;
|
PFONTSUBST_ENTRY pCurrentEntry;
|
||||||
|
@ -2762,6 +2757,7 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
|
||||||
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
|
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
|
||||||
if (LogFont->lfFaceName[0] != UNICODE_NULL)
|
if (LogFont->lfFaceName[0] != UNICODE_NULL)
|
||||||
{
|
{
|
||||||
|
/* check name */
|
||||||
if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
|
if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
|
||||||
continue; /* mismatch */
|
continue; /* mismatch */
|
||||||
}
|
}
|
||||||
|
@ -2771,18 +2767,22 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
|
||||||
pCurrentEntry->CharSets[FONTSUBST_FROM] ==
|
pCurrentEntry->CharSets[FONTSUBST_FROM] ==
|
||||||
pCurrentEntry->CharSets[FONTSUBST_TO])
|
pCurrentEntry->CharSets[FONTSUBST_TO])
|
||||||
{
|
{
|
||||||
|
/* identical mapping */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* substitute and get the real name */
|
||||||
IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
|
IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
|
||||||
SubstituteFontRecurse(&lf);
|
SubstituteFontRecurse(&lf);
|
||||||
if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet != lf.lfCharSet)
|
if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet != lf.lfCharSet)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* search in global fonts */
|
||||||
IntLockGlobalFonts();
|
IntLockGlobalFonts();
|
||||||
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount, &g_FontListHead);
|
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount, &g_FontListHead);
|
||||||
IntUnLockGlobalFonts();
|
IntUnLockGlobalFonts();
|
||||||
|
|
||||||
|
/* search in private fonts */
|
||||||
IntLockProcessPrivateFonts(Win32Process);
|
IntLockProcessPrivateFonts(Win32Process);
|
||||||
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
|
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
|
||||||
&Win32Process->PrivateFontListHead);
|
&Win32Process->PrivateFontListHead);
|
||||||
|
@ -5407,41 +5407,22 @@ ftGdiGetKerningPairs( PFONTGDI Font,
|
||||||
// Functions needing sorting.
|
// Functions needing sorting.
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
int APIENTRY
|
|
||||||
NtGdiGetFontFamilyInfo(HDC Dc,
|
LONG FASTCALL
|
||||||
LPLOGFONTW UnsafeLogFont,
|
IntGetFontFamilyInfo(HDC Dc,
|
||||||
PFONTFAMILYINFO UnsafeInfo,
|
const LOGFONTW *SafeLogFont,
|
||||||
DWORD Size)
|
PFONTFAMILYINFO SafeInfo,
|
||||||
|
LONG InfoCount)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
LONG AvailCount = 0;
|
||||||
LOGFONTW LogFont;
|
|
||||||
PFONTFAMILYINFO Info;
|
|
||||||
DWORD Count;
|
|
||||||
PPROCESSINFO Win32Process;
|
PPROCESSINFO Win32Process;
|
||||||
|
|
||||||
/* Make a safe copy */
|
|
||||||
Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
|
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate space for a safe copy */
|
|
||||||
Info = ExAllocatePoolWithTag(PagedPool, Size * sizeof(FONTFAMILYINFO), GDITAG_TEXT);
|
|
||||||
if (NULL == Info)
|
|
||||||
{
|
|
||||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enumerate font families in the global list */
|
/* Enumerate font families in the global list */
|
||||||
IntLockGlobalFonts();
|
IntLockGlobalFonts();
|
||||||
Count = 0;
|
if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
|
||||||
if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size, &g_FontListHead) )
|
InfoCount, &g_FontListHead))
|
||||||
{
|
{
|
||||||
IntUnLockGlobalFonts();
|
IntUnLockGlobalFonts();
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
IntUnLockGlobalFonts();
|
IntUnLockGlobalFonts();
|
||||||
|
@ -5449,28 +5430,103 @@ NtGdiGetFontFamilyInfo(HDC Dc,
|
||||||
/* Enumerate font families in the process local list */
|
/* Enumerate font families in the process local list */
|
||||||
Win32Process = PsGetCurrentProcessWin32Process();
|
Win32Process = PsGetCurrentProcessWin32Process();
|
||||||
IntLockProcessPrivateFonts(Win32Process);
|
IntLockProcessPrivateFonts(Win32Process);
|
||||||
if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
|
if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount, InfoCount,
|
||||||
&Win32Process->PrivateFontListHead))
|
&Win32Process->PrivateFontListHead))
|
||||||
{
|
{
|
||||||
IntUnLockProcessPrivateFonts(Win32Process);
|
IntUnLockProcessPrivateFonts(Win32Process);
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
IntUnLockProcessPrivateFonts(Win32Process);
|
IntUnLockProcessPrivateFonts(Win32Process);
|
||||||
|
|
||||||
/* Enumerate font families in the registry */
|
/* Enumerate font families in the registry */
|
||||||
if (! GetFontFamilyInfoForSubstitutes(&LogFont, Info, &Count, Size))
|
if (!GetFontFamilyInfoForSubstitutes(SafeLogFont, SafeInfo, &AvailCount, InfoCount))
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return data to caller */
|
return AvailCount;
|
||||||
if (0 != Count)
|
}
|
||||||
|
|
||||||
|
LONG NTAPI
|
||||||
|
NtGdiGetFontFamilyInfo(HDC Dc,
|
||||||
|
const LOGFONTW *UnsafeLogFont,
|
||||||
|
PFONTFAMILYINFO UnsafeInfo,
|
||||||
|
LPLONG UnsafeInfoCount)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
LOGFONTW LogFont;
|
||||||
|
PFONTFAMILYINFO Info;
|
||||||
|
LONG GotCount, AvailCount, DataSize, SafeInfoCount;
|
||||||
|
|
||||||
|
if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
|
||||||
{
|
{
|
||||||
Status = MmCopyToCaller(UnsafeInfo, Info,
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
(Count < Size ? Count : Size) * sizeof(FONTFAMILYINFO));
|
return -1;
|
||||||
if (! NT_SUCCESS(Status))
|
}
|
||||||
|
|
||||||
|
Status = MmCopyFromCaller(&SafeInfoCount, UnsafeInfoCount, sizeof(SafeInfoCount));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
GotCount = 0;
|
||||||
|
Status = MmCopyToCaller(UnsafeInfoCount, &GotCount, sizeof(*UnsafeInfoCount));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (SafeInfoCount <= 0)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate space for a safe copy */
|
||||||
|
DataSize = SafeInfoCount * sizeof(FONTFAMILYINFO);
|
||||||
|
if (DataSize <= 0)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Info = ExAllocatePoolWithTag(PagedPool, DataSize, GDITAG_TEXT);
|
||||||
|
if (Info == NULL)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve the information */
|
||||||
|
AvailCount = IntGetFontFamilyInfo(Dc, &LogFont, Info, SafeInfoCount);
|
||||||
|
GotCount = min(AvailCount, SafeInfoCount);
|
||||||
|
SafeInfoCount = AvailCount;
|
||||||
|
|
||||||
|
/* Return data to caller */
|
||||||
|
if (GotCount > 0)
|
||||||
|
{
|
||||||
|
DataSize = GotCount * sizeof(FONTFAMILYINFO);
|
||||||
|
if (DataSize <= 0)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Status = MmCopyToCaller(UnsafeInfo, Info, DataSize);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
||||||
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Status = MmCopyToCaller(UnsafeInfoCount, &SafeInfoCount, sizeof(*UnsafeInfoCount));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
||||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
@ -5480,7 +5536,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
|
||||||
|
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
||||||
|
|
||||||
return Count;
|
return GotCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -6618,7 +6674,7 @@ NtGdiGetCharABCWidthsW(
|
||||||
if(Safepwch)
|
if(Safepwch)
|
||||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||||
|
|
||||||
if (! NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -50,14 +50,13 @@ typedef struct tagFONTFAMILYINFO
|
||||||
} FONTFAMILYINFO, *PFONTFAMILYINFO;
|
} FONTFAMILYINFO, *PFONTFAMILYINFO;
|
||||||
|
|
||||||
/* Should be using NtGdiEnumFontChunk */
|
/* Should be using NtGdiEnumFontChunk */
|
||||||
INT
|
LONG
|
||||||
NTAPI
|
NTAPI
|
||||||
NtGdiGetFontFamilyInfo(
|
NtGdiGetFontFamilyInfo(
|
||||||
HDC Dc,
|
HDC Dc,
|
||||||
LPLOGFONTW LogFont,
|
const LOGFONTW *LogFont,
|
||||||
PFONTFAMILYINFO Info,
|
PFONTFAMILYINFO Info,
|
||||||
DWORD Size
|
LPLONG UnsafeInfoCount);
|
||||||
);
|
|
||||||
|
|
||||||
/* Use NtGdiGetDCPoint with GdiGetViewPortExt */
|
/* Use NtGdiGetDCPoint with GdiGetViewPortExt */
|
||||||
BOOL APIENTRY NtGdiGetViewportExtEx(HDC hDC, LPSIZE viewportExt);
|
BOOL APIENTRY NtGdiGetViewportExtEx(HDC hDC, LPSIZE viewportExt);
|
||||||
|
|
Loading…
Reference in a new issue