Skip to content

Commit d332edc

Browse files
katahiromzJoachimHenze
authored andcommitted
[0.4.11] [FONT][GDI32] Fix font enumeration functions (reactos#1221)
Fix EnumFonts, EnumFontFamilies and EnumFontFamiliesEx functions. The charsets of the font substitutes are also enumerated. Delete meaningless codes. Fixes regression CORE-15558 cherry picked from commit 0.4.12-dev-320-g 6e4e5a0
1 parent ec2f30d commit d332edc

File tree

2 files changed

+136
-158
lines changed

2 files changed

+136
-158
lines changed

win32ss/gdi/gdi32/objects/font.c

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,88 @@ NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw)
204204
tma->ntmFontSig = tmw->ntmFontSig;
205205
}
206206

207+
// IntFontFamilyCompareEx's flags
208+
#define IFFCX_CHARSET 1
209+
#define IFFCX_STYLE 2
210+
211+
FORCEINLINE int FASTCALL
212+
IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
213+
const FONTFAMILYINFO *ffi2, DWORD dwCompareFlags)
214+
{
215+
const LOGFONTW *plf1 = &ffi1->EnumLogFontEx.elfLogFont;
216+
const LOGFONTW *plf2 = &ffi2->EnumLogFontEx.elfLogFont;
217+
ULONG WeightDiff1, WeightDiff2;
218+
int cmp = _wcsicmp(plf1->lfFaceName, plf2->lfFaceName);
219+
if (cmp)
220+
return cmp;
221+
if (dwCompareFlags & IFFCX_STYLE)
222+
{
223+
WeightDiff1 = labs(plf1->lfWeight - FW_NORMAL);
224+
WeightDiff2 = labs(plf2->lfWeight - FW_NORMAL);
225+
if (WeightDiff1 < WeightDiff2)
226+
return -1;
227+
if (WeightDiff1 > WeightDiff2)
228+
return 1;
229+
if (plf1->lfItalic < plf2->lfItalic)
230+
return -1;
231+
if (plf1->lfItalic > plf2->lfItalic)
232+
return 1;
233+
}
234+
if (dwCompareFlags & IFFCX_CHARSET)
235+
{
236+
if (plf1->lfCharSet < plf2->lfCharSet)
237+
return -1;
238+
if (plf1->lfCharSet > plf2->lfCharSet)
239+
return 1;
240+
}
241+
return 0;
242+
}
243+
244+
static int __cdecl
245+
IntFontFamilyCompare(const void *ffi1, const void *ffi2)
246+
{
247+
return IntFontFamilyCompareEx(ffi1, ffi2, IFFCX_STYLE | IFFCX_CHARSET);
248+
}
249+
250+
// IntEnumFontFamilies' flags:
251+
#define IEFF_UNICODE 1
252+
#define IEFF_EXTENDED 2
253+
254+
int FASTCALL
255+
IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
256+
const LOGFONTW *plf, DWORD dwFlags)
257+
{
258+
FONTFAMILYINFO *first, *last, *result;
259+
DWORD dwCompareFlags = 0;
260+
261+
if (plf->lfFaceName[0])
262+
dwCompareFlags |= IFFCX_STYLE;
263+
264+
if ((dwFlags & IEFF_EXTENDED) && plf->lfCharSet == DEFAULT_CHARSET)
265+
dwCompareFlags |= IFFCX_CHARSET;
266+
267+
// std::unique(first, last, IntFontFamilyCompareEx);
268+
if (nCount == 0)
269+
return 0;
270+
271+
result = first = InfoList;
272+
last = &InfoList[nCount];
273+
while (++first != last)
274+
{
275+
if (IntFontFamilyCompareEx(result, first, dwCompareFlags) != 0 &&
276+
++result != first)
277+
{
278+
*result = *first;
279+
}
280+
}
281+
nCount = (int)(++result - InfoList);
282+
283+
return nCount;
284+
}
285+
207286
static int FASTCALL
208287
IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
209-
BOOL Unicode)
288+
DWORD dwFlags)
210289
{
211290
int FontFamilyCount;
212291
int FontFamilySize;
@@ -256,9 +335,15 @@ IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
256335
}
257336
}
258337

338+
DPRINT("qsort\n");
339+
qsort(Info, FontFamilyCount, sizeof(*Info), IntFontFamilyCompare);
340+
DPRINT("qsort done\n");
341+
FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, LogFont, dwFlags);
342+
DPRINT("unique done\n");
343+
259344
for (i = 0; i < FontFamilyCount; i++)
260345
{
261-
if (Unicode)
346+
if (dwFlags & IEFF_UNICODE)
262347
{
263348
Ret = ((FONTENUMPROCW) EnumProc)(
264349
(VOID*)&Info[i].EnumLogFontEx,
@@ -299,7 +384,8 @@ int WINAPI
299384
EnumFontFamiliesExW(HDC hdc, LPLOGFONTW lpLogfont, FONTENUMPROCW lpEnumFontFamExProc,
300385
LPARAM lParam, DWORD dwFlags)
301386
{
302-
return IntEnumFontFamilies(hdc, lpLogfont, lpEnumFontFamExProc, lParam, TRUE);
387+
return IntEnumFontFamilies(hdc, lpLogfont, lpEnumFontFamExProc, lParam,
388+
IEFF_UNICODE | IEFF_EXTENDED);
303389
}
304390

305391

@@ -320,7 +406,7 @@ EnumFontFamiliesW(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc,
320406
lstrcpynW(LogFont.lfFaceName, lpszFamily, LF_FACESIZE);
321407
}
322408

323-
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, TRUE);
409+
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, IEFF_UNICODE);
324410
}
325411

326412

@@ -341,7 +427,7 @@ EnumFontFamiliesExA (HDC hdc, LPLOGFONTA lpLogfont, FONTENUMPROCA lpEnumFontFamE
341427
else pLogFontW = NULL;
342428

343429
/* no need to convert LogFontW back to lpLogFont b/c it's an [in] parameter only */
344-
return IntEnumFontFamilies(hdc, pLogFontW, lpEnumFontFamExProc, lParam, FALSE);
430+
return IntEnumFontFamilies(hdc, pLogFontW, lpEnumFontFamExProc, lParam, IEFF_EXTENDED);
345431
}
346432

347433

@@ -362,7 +448,7 @@ EnumFontFamiliesA(HDC hdc, LPCSTR lpszFamily, FONTENUMPROCA lpEnumFontFamProc,
362448
MultiByteToWideChar(CP_THREAD_ACP, 0, lpszFamily, -1, LogFont.lfFaceName, LF_FACESIZE);
363449
}
364450

365-
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, FALSE);
451+
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, 0);
366452
}
367453

368454

0 commit comments

Comments
 (0)