From 6f790606c0befdf5c683d4a20789470c43b6f6a9 Mon Sep 17 00:00:00 2001 From: Fabian Maurer Date: Sun, 26 Nov 2017 14:33:17 +0100 Subject: [PATCH] gdi32: In AddFaceToList allow fonts with long names and add tests. Signed-off-by: Fabian Maurer Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/freetype.c | 45 +++++++++----------- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/font.c | 54 +++++++++++++++++++++++ dlls/gdi32/tests/resource.rc | 3 ++ dlls/gdi32/tests/wine_longname.sfd | 66 +++++++++++++++++++++++++++++ dlls/gdi32/tests/wine_longname.ttf | Bin 0 -> 2216 bytes 6 files changed, 143 insertions(+), 26 deletions(-) create mode 100644 dlls/gdi32/tests/wine_longname.sfd create mode 100644 dlls/gdi32/tests/wine_longname.ttf diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 346e21dc21a..7c5a7ef9797 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -1027,7 +1027,7 @@ static Face *find_face_from_filename(const WCHAR *file_name, const WCHAR *face_n LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry) { const struct list *face_list; - if(face_name && strcmpiW(face_name, family->FamilyName)) + if(face_name && strncmpiW(face_name, family->FamilyName, LF_FACESIZE - 1)) continue; face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY(face, face_list, Face, entry) @@ -1053,7 +1053,7 @@ static Family *find_family_from_name(const WCHAR *name) LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry) { - if(!strcmpiW(family->FamilyName, name)) + if(!strncmpiW(family->FamilyName, name, LF_FACESIZE -1)) return family; } @@ -1066,9 +1066,9 @@ static Family *find_family_from_any_name(const WCHAR *name) LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry) { - if(!strcmpiW(family->FamilyName, name)) + if(!strncmpiW(family->FamilyName, name, LF_FACESIZE - 1)) return family; - if(family->EnglishName && !strcmpiW(family->EnglishName, name)) + if(family->EnglishName && !strncmpiW(family->EnglishName, name, LF_FACESIZE - 1)) return family; } @@ -2141,13 +2141,6 @@ static void AddFaceToList(FT_Face ft_face, const char *file, void *font_data_ptr face = create_face( ft_face, face_index, file, font_data_ptr, font_data_size, flags ); family = get_family( ft_face, flags & ADDFONT_VERTICAL_FONT ); - if (strlenW(family->FamilyName) >= LF_FACESIZE) - { - WARN("Ignoring %s because name is too long\n", debugstr_w(family->FamilyName)); - release_face( face ); - release_family( family ); - return; - } if (insert_face_in_family_list( face, family )) { @@ -2471,7 +2464,7 @@ static SYSTEM_LINKS *find_font_link(const WCHAR *name) LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry) { - if(!strcmpiW(font_link->font_name, name)) + if(!strncmpiW(font_link->font_name, name, LF_FACESIZE - 1)) return font_link; } @@ -4320,7 +4313,7 @@ static BOOL move_to_front(const WCHAR *name) Family *family, *cursor2; LIST_FOR_EACH_ENTRY_SAFE(family, cursor2, &font_list, Family, entry) { - if(!strcmpiW(family->FamilyName, name)) + if(!strncmpiW(family->FamilyName, name, LF_FACESIZE - 1)) { list_remove(&family->entry); list_add_head(&font_list, &family->entry); @@ -5476,8 +5469,8 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) or if that's unavailable the first charset that the font supports. */ LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { - if (!strcmpiW(family->FamilyName, FaceName) || - (psub && !strcmpiW(family->FamilyName, psub->to.name))) + if (!strncmpiW(family->FamilyName, FaceName, LF_FACESIZE - 1) || + (psub && !strncmpiW(family->FamilyName, psub->to.name, LF_FACESIZE - 1))) { font_link = find_font_link(family->FamilyName); face_list = get_face_list_from_family(family); @@ -5499,7 +5492,7 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) { - if(face->FullName && !strcmpiW(face->FullName, FaceName) && + if(face->FullName && !strncmpiW(face->FullName, FaceName, LF_FACESIZE - 1) && (face->scalable || can_use_bitmap)) { if (csi.fs.fsCsb[0] & face->fs.fsCsb[0] || !csi.fs.fsCsb[0]) @@ -5518,8 +5511,8 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) */ LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry) { - if(!strcmpiW(font_link->font_name, FaceName) || - (psub && !strcmpiW(font_link->font_name,psub->to.name))) + if(!strncmpiW(font_link->font_name, FaceName, LF_FACESIZE - 1) || + (psub && !strncmpiW(font_link->font_name,psub->to.name, LF_FACESIZE - 1))) { TRACE("found entry in system list\n"); LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry) @@ -5569,7 +5562,7 @@ static HFONT freetype_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags ) else strcpyW(lf.lfFaceName, defSans); LIST_FOR_EACH_ENTRY( family, &font_list, Family, entry ) { - if(!strcmpiW(family->FamilyName, lf.lfFaceName)) { + if(!strncmpiW(family->FamilyName, lf.lfFaceName, LF_FACESIZE - 1)) { font_link = find_font_link(family->FamilyName); face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY( face, face_list, Face, entry ) { @@ -6037,20 +6030,20 @@ static BOOL family_matches(Family *family, const WCHAR *face_name) Face *face; const struct list *face_list; - if (!strcmpiW(face_name, family->FamilyName)) return TRUE; + if (!strncmpiW(face_name, family->FamilyName, LF_FACESIZE - 1)) return TRUE; face_list = get_face_list_from_family(family); LIST_FOR_EACH_ENTRY(face, face_list, Face, entry) - if (face->FullName && !strcmpiW(face_name, face->FullName)) return TRUE; + if (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1)) return TRUE; return FALSE; } static BOOL face_matches(const WCHAR *family_name, Face *face, const WCHAR *face_name) { - if (!strcmpiW(face_name, family_name)) return TRUE; + if (!strncmpiW(face_name, family_name, LF_FACESIZE - 1)) return TRUE; - return (face->FullName && !strcmpiW(face_name, face->FullName)); + return (face->FullName && !strncmpiW(face_name, face->FullName, LF_FACESIZE - 1)); } static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_charset_list *list, @@ -6082,11 +6075,11 @@ static BOOL enum_face_charsets(const Family *family, Face *face, struct enum_cha /* Font Replacement */ if (family != face->family) { - strcpyW(elf.elfLogFont.lfFaceName, family->FamilyName); + lstrcpynW(elf.elfLogFont.lfFaceName, family->FamilyName, LF_FACESIZE); if (face->FullName) - strcpyW(elf.elfFullName, face->FullName); + lstrcpynW(elf.elfFullName, face->FullName, LF_FULLFACESIZE); else - strcpyW(elf.elfFullName, family->FamilyName); + lstrcpynW(elf.elfFullName, family->FamilyName, LF_FULLFACESIZE); } if (subst) strcpyW(elf.elfLogFont.lfFaceName, subst); diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index 10e9c2a6a01..90d7223f47e 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ FONT_SRCS = \ vertical.sfd \ + wine_longname.sfd \ wine_test.sfd \ wine_vdmx.sfd diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 299fadbab1a..bd04a8b6b18 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -6679,6 +6679,59 @@ static void test_GetCharWidthI(void) ReleaseDC(0, hdc); } +static INT CALLBACK long_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lparam) +{ + BOOL *found_font = (BOOL *)lparam; + *found_font = TRUE; + return 1; +} + +static void test_long_names(void) +{ + char ttf_name[MAX_PATH]; + LOGFONTA font = {0}; + HFONT handle_font; + BOOL found_font; + int ret; + HDC dc; + + if (!write_ttf_file("wine_longname.ttf", ttf_name)) + { + skip("Failed to create ttf file for testing\n"); + return; + } + + dc = GetDC(NULL); + + ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "AddFontResourceEx() failed\n"); + + strcpy(font.lfFaceName, "wine_3_this_is_a_very_long_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n"); + + strcpy(font.lfFaceName, "wine_2_this_is_a_very_long_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n"); + + strcpy(font.lfFaceName, "wine_1_this_is_a_very_long_name"); + found_font = FALSE; + EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0); + ok(found_font == FALSE, "EnumFontFamiliesExA must not find font.\n"); + + handle_font = CreateFontIndirectA(&font); + ok(handle_font != NULL, "CreateFontIndirectA failed\n"); + DeleteObject(handle_font); + + ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0); + ok(ret, "RemoveFontResourceEx() failed\n"); + + DeleteFileA(ttf_name); + ReleaseDC(NULL, dc); +} + START_TEST(font) { init(); @@ -6742,6 +6795,7 @@ START_TEST(font) test_fake_bold_font(); test_bitmap_font_glyph_index(); test_GetCharWidthI(); + test_long_names(); /* These tests should be last test until RemoveFontResource * is properly implemented. diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index fdd95f687ad..6dcbd42ab52 100644 --- a/dlls/gdi32/tests/resource.rc +++ b/dlls/gdi32/tests/resource.rc @@ -28,3 +28,6 @@ wine_vdmx.ttf RCDATA wine_vdmx.ttf /* @makedep: vertical.ttf */ vertical.ttf RCDATA vertical.ttf + +/* @makedep: wine_longname.ttf */ +wine_longname.ttf RCDATA wine_longname.ttf diff --git a/dlls/gdi32/tests/wine_longname.sfd b/dlls/gdi32/tests/wine_longname.sfd new file mode 100644 index 00000000000..998d7cc01fb --- /dev/null +++ b/dlls/gdi32/tests/wine_longname.sfd @@ -0,0 +1,66 @@ +SplineFontDB: 3.0 +FontName: wine_1_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +FullName: wine_2_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +FamilyName: wine_3_this_is_a_very_long_name_that_might_be_too_long_for_gdi32 +Weight: Regular +Copyright: Copyright (c) 2017, Fabian Maurer +UComments: "2017-11-17: Created with FontForge (http://fontforge.org)" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -102.4 +UnderlineWidth: 51.2 +Ascent: 819 +Descent: 205 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 48 28337276 3092883] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1510948643 +ModificationTime: 1510949092 +OS2TypoAscent: 0 +OS2TypoAOffset: 1 +OS2TypoDescent: 0 +OS2TypoDOffset: 1 +OS2TypoLinegap: 0 +OS2WinAscent: 0 +OS2WinAOffset: 1 +OS2WinDescent: 0 +OS2WinDOffset: 1 +HheadAscent: 0 +HheadAOffset: 1 +HheadDescent: 0 +HheadDOffset: 1 +OS2Vendor: 'PfEd' +MarkAttachClasses: 1 +DEI: 91125 +Encoding: ISO8859-1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 64 16 4 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: at +Encoding: 64 64 0 +Width: 1024 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +259 332 m 29 + 468 664 l 29 + 514 332 l 29 + 259 332 l 29 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/wine_longname.ttf b/dlls/gdi32/tests/wine_longname.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1a519c64ad4e6d7b042f560c0a9495d7c6d19043 GIT binary patch literal 2216 zcmdT_O^6&t6#lBZXLh5@{#=CM5;~g%vtgO^bce)*IgI%kbJ)cth6ORu>7D86X_)CA zdU`h*@GwUY33^oY;6W4?5qA*13L$AkuWEXC67aTQuzITM`(C|Q z_1>#D-4Fm~F@S;Fwc5=!GD@cJabA4&>a`l?aE!c7e(bf^&pI0g|7)tW$Zyv>eiw7a z2joAoU#@Rw7MA4OfU(GRGxU4i(TF=^x9|Km@IAF`is zQBXKy7P!|*@{_Gjc6SEi6#4h$^X;VWV-q)NZ;?OO@$YtV9T&NNo!pB3PH=Sn%^9wL z$m2igCcSL5gY!K4Wv-u5k*PlO!zaIbbCo~vyh#D@)~PQB2lEmjrQ9K(hE!5E+GxqG zvA&dgr}5f&G_}M$uu+ym%c>}86_YCOg0ac>;#J;}9!KBinh?dw z0Yb&1`jhP`51(9^V0HZeyy;qI-Ka-ZkW@Jq4sXD~6iT}SXDh=g6OWwTV&Uh?(2#`K zHI%rZ#KWng__H!(3LiP{!tsTd+=UZMV*dBNJ-PGO#*%DuJ7I`bR@{3k$KplOA4_6Y ztp5F_O5Q9!-@g+a$JHDQRPkGmC8os192-~{zvS3NReqJ@0_KgQIWDq}K2w!os(QQ3 zKE?tAG;=I5E0%L?;3M%$j!g{Yxf~Z@$;UY^Vql!X6(s1Qj}#F?w2-mNPNR-x&JJvp zaRDpDHK>1a#4#pYurgzji(|MSpmNu1S^Gz=`KWLuXkoeJkLsd(lg z9X^B&-c!mFjP&hUye(Dg>ekd_0UJTui;~!~?Q+SsZAvClm!Hi=>Zr?yxw!o=!f3#M o#pGi_m^bwy64W}Ox!^Zu^3|Nh3zRAizVq~ZNocKq+b3W62d7DFwg3PC literal 0 HcmV?d00001