@@ -204,9 +204,88 @@ NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw)
204
204
tma -> ntmFontSig = tmw -> ntmFontSig ;
205
205
}
206
206
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
+
207
286
static int FASTCALL
208
287
IntEnumFontFamilies (HDC Dc , LPLOGFONTW LogFont , PVOID EnumProc , LPARAM lParam ,
209
- BOOL Unicode )
288
+ DWORD dwFlags )
210
289
{
211
290
int FontFamilyCount ;
212
291
int FontFamilySize ;
@@ -256,9 +335,15 @@ IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
256
335
}
257
336
}
258
337
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
+
259
344
for (i = 0 ; i < FontFamilyCount ; i ++ )
260
345
{
261
- if (Unicode )
346
+ if (dwFlags & IEFF_UNICODE )
262
347
{
263
348
Ret = ((FONTENUMPROCW ) EnumProc )(
264
349
(VOID * )& Info [i ].EnumLogFontEx ,
@@ -299,7 +384,8 @@ int WINAPI
299
384
EnumFontFamiliesExW (HDC hdc , LPLOGFONTW lpLogfont , FONTENUMPROCW lpEnumFontFamExProc ,
300
385
LPARAM lParam , DWORD dwFlags )
301
386
{
302
- return IntEnumFontFamilies (hdc , lpLogfont , lpEnumFontFamExProc , lParam , TRUE);
387
+ return IntEnumFontFamilies (hdc , lpLogfont , lpEnumFontFamExProc , lParam ,
388
+ IEFF_UNICODE | IEFF_EXTENDED );
303
389
}
304
390
305
391
@@ -320,7 +406,7 @@ EnumFontFamiliesW(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc,
320
406
lstrcpynW (LogFont .lfFaceName , lpszFamily , LF_FACESIZE );
321
407
}
322
408
323
- return IntEnumFontFamilies (hdc , & LogFont , lpEnumFontFamProc , lParam , TRUE );
409
+ return IntEnumFontFamilies (hdc , & LogFont , lpEnumFontFamProc , lParam , IEFF_UNICODE );
324
410
}
325
411
326
412
@@ -341,7 +427,7 @@ EnumFontFamiliesExA (HDC hdc, LPLOGFONTA lpLogfont, FONTENUMPROCA lpEnumFontFamE
341
427
else pLogFontW = NULL ;
342
428
343
429
/* 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 );
345
431
}
346
432
347
433
@@ -362,7 +448,7 @@ EnumFontFamiliesA(HDC hdc, LPCSTR lpszFamily, FONTENUMPROCA lpEnumFontFamProc,
362
448
MultiByteToWideChar (CP_THREAD_ACP , 0 , lpszFamily , -1 , LogFont .lfFaceName , LF_FACESIZE );
363
449
}
364
450
365
- return IntEnumFontFamilies (hdc , & LogFont , lpEnumFontFamProc , lParam , FALSE );
451
+ return IntEnumFontFamilies (hdc , & LogFont , lpEnumFontFamProc , lParam , 0 );
366
452
}
367
453
368
454
0 commit comments