Index: reactos/win32ss/gdi/ntgdi/freetype.c =================================================================== --- reactos/win32ss/gdi/ntgdi/freetype.c (revision 75370) +++ reactos/win32ss/gdi/ntgdi/freetype.c (working copy) @@ -2450,22 +2450,44 @@ return FindFaceNameInInfo(FaceName, Info, InfoEntries) < 0; } +static BOOL FASTCALL +FontFamilyFound(PFONTFAMILYINFO InfoEntry, + PFONTFAMILYINFO Info, DWORD InfoCount) +{ + LPLOGFONTW plf1 = &InfoEntry->EnumLogFontEx.elfLogFont; + LPWSTR pFullName1 = InfoEntry->EnumLogFontEx.elfFullName; + LPWSTR pFullName2; + DWORD i; + + for (i = 0; i < InfoCount; ++i) + { + LPLOGFONTW plf2 = &Info[i].EnumLogFontEx.elfLogFont; + if (plf1->lfCharSet != plf2->lfCharSet) + continue; + + pFullName2 = Info[i].EnumLogFontEx.elfFullName; + if (_wcsicmp(pFullName1, pFullName2) != 0) + continue; + + return TRUE; + } + return FALSE; +} + static BOOLEAN FASTCALL GetFontFamilyInfoForList(LPLOGFONTW LogFont, PFONTFAMILYINFO Info, DWORD *Count, - DWORD Size, + DWORD MaxCount, PLIST_ENTRY Head) { PLIST_ENTRY Entry; PFONT_ENTRY CurrentEntry; - ANSI_STRING EntryFaceNameA; - UNICODE_STRING EntryFaceNameW; FONTGDI *FontGDI; - NTSTATUS status; + FONTFAMILYINFO InfoEntry; + ENUMLOGFONTEXW *pLog; - Entry = Head->Flink; - while (Entry != Head) + for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink) { CurrentEntry = (PFONT_ENTRY) CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry); @@ -2472,30 +2494,39 @@ FontGDI = CurrentEntry->Font; ASSERT(FontGDI); - RtlInitAnsiString(&EntryFaceNameA, FontGDI->SharedFace->Face->family_name); - status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA, TRUE); - if (!NT_SUCCESS(status)) + if (LogFont->lfCharSet != DEFAULT_CHARSET && + LogFont->lfCharSet != FontGDI->CharSet) { - return FALSE; + continue; } - if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length) + if (LogFont->lfFaceName[0] == UNICODE_NULL) { - EntryFaceNameW.Length = (LF_FACESIZE - 1) * sizeof(WCHAR); - EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0'; + if (*Count < MaxCount) + { + FontFamilyFillInfo(&Info[*Count], NULL, NULL, FontGDI); + } + (*Count)++; + continue; } - if (FontFamilyInclude(LogFont, &EntryFaceNameW, Info, min(*Count, Size))) + FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI); + + pLog = &InfoEntry.EnumLogFontEx; + if (_wcsicmp(LogFont->lfFaceName, pLog->elfLogFont.lfFaceName) != 0 && + _wcsicmp(LogFont->lfFaceName, pLog->elfFullName) != 0) { - if (*Count < Size) + continue; + } + + if (!FontFamilyFound(&InfoEntry, Info, min(*Count, MaxCount))) + { + if (*Count < MaxCount) { - FontFamilyFillInfo(Info + *Count, EntryFaceNameW.Buffer, - NULL, FontGDI); + RtlCopyMemory(&Info[*Count], &InfoEntry, sizeof(InfoEntry)); } (*Count)++; } - RtlFreeUnicodeString(&EntryFaceNameW); - Entry = Entry->Flink; } return TRUE; Index: rostests/winetests/gdi32/font.c =================================================================== --- rostests/winetests/gdi32/font.c (revision 75370) +++ rostests/winetests/gdi32/font.c (working copy) @@ -21,7 +21,7 @@ #include #include - +#include #include "windef.h" #include "winbase.h" #include "wingdi.h" @@ -3245,17 +3245,17 @@ SelectObject(hdc, hfont_prev); DeleteObject(hfont); - ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX && - gm1.gmBlackBoxY == gm2.gmBlackBoxY && - gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x && +gm1.gmBlackBoxX != gm2.gmBlackBoxX || gm1.gmBlackBoxY != gm2.gmBlackBoxY || gm1.gmptGlyphOrigin.x != gm2.gmptGlyphOrigin.x || gm1.gmptGlyphOrigin.y != gm2.gmptGlyphOrigin.y || gm1.gmCellIncX != gm2.gmCellIncX || gm1.gmCellIncY != gm2.gmCellIncY ? ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX && + gm1.gmBlackBoxY == gm2.gmBlackBoxY && gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x && gm1.gmptGlyphOrigin.y == gm2.gmptGlyphOrigin.y && gm1.gmCellIncX == gm2.gmCellIncX && gm1.gmCellIncY == gm2.gmCellIncY, - "gm1=%d,%d,%d,%d,%d,%d gm2=%d,%d,%d,%d,%d,%d\n", + "%s/%d/%d/%d gm1=%d,%d,%d,%d,%d,%d gm2=%d,%d,%d,%d,%d,%d\n", lf->lfFaceName, lf->lfCharSet, lf->lfWeight, lf->lfItalic, gm1.gmBlackBoxX, gm1.gmBlackBoxY, gm1.gmptGlyphOrigin.x, gm1.gmptGlyphOrigin.y, gm1.gmCellIncX, gm1.gmCellIncY, gm2.gmBlackBoxX, gm2.gmBlackBoxY, gm2.gmptGlyphOrigin.x, - gm2.gmptGlyphOrigin.y, gm2.gmCellIncX, gm2.gmCellIncY); + gm2.gmptGlyphOrigin.y, gm2.gmCellIncX, gm2.gmCellIncY) : + printf("font.c,3248: %s/%d/%d/%d OK\n", lf->lfFaceName, lf->lfCharSet, lf->lfWeight, lf->lfItalic) ; } /* PANOSE is 10 bytes in size, need to pack the structure properly */ @@ -3837,8 +3837,8 @@ ascent = GET_BE_WORD(tt_os2.usWinAscent); descent = abs((SHORT)GET_BE_WORD(tt_os2.usWinDescent)); cell_height = ascent + descent; - ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n", - font_name, ntm->ntmCellHeight, cell_height, ascent, descent); +ntm->ntmCellHeight != cell_height ? ok(ntm->ntmCellHeight == cell_height, "%s/%d/%d/%d: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n", + font_name, lf->lfCharSet, lf->lfWeight, lf->lfItalic, ntm->ntmCellHeight, cell_height, ascent, descent) : printf("font.c,3840: %s/%d/%d/%d OK\n", font_name, lf->lfCharSet, lf->lfWeight, lf->lfItalic) ; version = GET_BE_WORD(tt_os2.version); @@ -3912,15 +3912,15 @@ "GetTextMetricsW error %u\n", GetLastError()); if (ret) { - /* Wine uses the os2 first char */ +/* Wine uses the os2 first char */ printf("cmap_first=%d, os2_first_char=%d, cmap_type=%d, cmap_ms_symbol=%d\n", cmap_first, os2_first_char, cmap_type, cmap_ms_symbol); todo_wine_if(cmap_first != os2_first_char && cmap_type != cmap_ms_symbol) - ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n", - font_name, tmW.tmFirstChar, expect_first_W); +tmW.tmFirstChar != expect_first_W ? ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s/%d/%d/%d got %02x expected %02x\n", + font_name, lf->lfCharSet, lf->lfWeight, lf->lfItalic, tmW.tmFirstChar, expect_first_W) : printf("font.c,3917: %s/%d/%d/%d OK\n", font_name, lf->lfCharSet, lf->lfWeight, lf->lfItalic) ; - /* Wine uses the os2 last char */ +/* Wine uses the os2 last char */ printf("expect_last_W=%d, os2_last_char=%d, cmap_type=%d, cmap_ms_symbol=%d\n", expect_last_W, os2_last_char, cmap_type, cmap_ms_symbol); todo_wine_if(expect_last_W != os2_last_char && cmap_type != cmap_ms_symbol) - ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s got %02x expected %02x\n", - font_name, tmW.tmLastChar, expect_last_W); +tmW.tmLastChar == expect_last_W ? ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s/%d/%d/%d got %02x expected %02x\n", + font_name,lf->lfCharSet, lf->lfWeight, lf->lfItalic, tmW.tmLastChar, expect_last_W) : printf("font.c,3922: %s/%d/%d/%d OK\n", font_name, lf->lfCharSet, lf->lfWeight, lf->lfItalic) ; ok(tmW.tmBreakChar == expect_break_W, "W: tmBreakChar for %s got %02x expected %02x\n", font_name, tmW.tmBreakChar, expect_break_W); ok(tmW.tmDefaultChar == expect_default_W || broken(sys_lang_non_english), @@ -5477,7 +5477,7 @@ EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0); if (efnd.total == 0) skip("%s is not installed\n", lf.lfFaceName); - +printf("efnd.total is %d for font: %s\n", efnd.total, lf.lfFaceName); for (i = 0; i < efnd.total; i++) { FamilyName = (char *)efnd.elf[i].elfLogFont.lfFaceName; @@ -5524,9 +5524,9 @@ ok(ret, "FULL_NAME (face name) could not be read\n"); if (want_vertical) bufW = prepend_at(bufW); WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); - ok(!lstrcmpA(FaceName, bufA), "%s: font face names don't match: returned %s, expect %s\n", FamilyName, FaceName, bufA); +ok(!lstrcmpA(FaceName, bufA), "#%d of %d:%s: font face names don't match: returned %s, expect %s\n", i, efnd.total, FamilyName, FaceName, bufA); otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFaceName; - ok(!lstrcmpA(FaceName, otmStr), "%s: FaceName %s doesn't match otmpFaceName %s\n", FamilyName, FaceName, otmStr); +ok(!lstrcmpA(FaceName, otmStr), "#%d of %d:%s: FaceName %s doesn't match otmpFaceName %s\n", i, efnd.total, FamilyName, FaceName, otmStr); bufW[0] = 0; bufA[0] = 0; @@ -5534,9 +5534,9 @@ if (!ret) ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FONT_SUBFAMILY, bufW, buf_size, TT_MS_LANGID_ENGLISH_UNITED_STATES); ok(ret, "%s: SUBFAMILY (style name) could not be read\n", FamilyName); WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); - ok(!lstrcmpA(StyleName, bufA), "%s: style names don't match: returned %s, expect %s\n", FamilyName, StyleName, bufA); +ok(!lstrcmpA(StyleName, bufA), "#%d of %d:%s: style names don't match: returned %s, expect %s\n", i, efnd.total, FamilyName, StyleName, bufA); otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpStyleName; - ok(!lstrcmpA(StyleName, otmStr), "%s: StyleName %s doesn't match otmpStyleName %s\n", FamilyName, StyleName, otmStr); +ok(!lstrcmpA(StyleName, otmStr), "#%d of %d:%s: StyleName %s doesn't match otmpStyleName %s\n", i, efnd.total, FamilyName, StyleName, otmStr); bufW[0] = 0; bufA[0] = 0;