From: Arie Miller <renari@arimil.com> --- dlls/gdi32/tests/Makefile.in | 1 + dlls/gdi32/tests/cff.otf | Bin 0 -> 1788 bytes dlls/gdi32/tests/cff.sfd | 71 +++++++++++++++++++++++++++++++++++ dlls/gdi32/tests/font.c | 70 +++++++++++++++++++++++++++------- dlls/gdi32/tests/resource.rc | 3 ++ 5 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 dlls/gdi32/tests/cff.otf create mode 100644 dlls/gdi32/tests/cff.sfd diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in index 3ea3cdce957..c7b52d0229e 100644 --- a/dlls/gdi32/tests/Makefile.in +++ b/dlls/gdi32/tests/Makefile.in @@ -4,6 +4,7 @@ IMPORTS = setupapi user32 gdi32 advapi32 SOURCES = \ bitmap.c \ brush.c \ + cff.sfd \ clipping.c \ dc.c \ dib.c \ diff --git a/dlls/gdi32/tests/cff.otf b/dlls/gdi32/tests/cff.otf new file mode 100644 index 0000000000000000000000000000000000000000..bef8e3e953a69d94847ac8b82061b68e1c9102e5 GIT binary patch literal 1788 zcmeYd3Grv(W@unwW-xGeb5jVtlXH-PfmMcqfpMOjTZr$*ng0qI7}#zwFfhotySTbB zh%$&UFtF_b@%@AKjY9bn`571(6&M&85|VQh3mABruQ4z%?_gkHbjnCgOwns}+seSe z08($3k&&9nn#$6_z`*c@fq_9KBe$f2{Q|>T1_m||pCdQ1qJV)ZfPsO5QG$Vifh{jF zH+6mT|A`C?j13G7Oy&jo#U=lDFc>p1u>4_QU{GLS1Sw@;I2GalJ)Ym@D+4$43kC)T zhG!i9QV@Fc6o#`5bD3J1S{WD^I2f2fq7XeytqgM+q9E#-TEQkkCBYOE1494<SUn5# z3&sfytPBiHT}&Wf^gw9F2MmUcOdut!oM0Uw0^}YL4aNa!t|<%+3<eAa%nJW47^0Y3 z|0hH221|noh!6M}*1_$UW3Yp=85y`4N}+5f26l#tP&PAzI>SpSn}va!Q4`8$W#DHF zg|gWgxEX61m>C#ZKyI^PV1Tk28N?W3p=>4wK88jpo0-9nVJ4K#!XU;d2xYS}$T6Bi z*=!7AjHwLH4EYQN43!K;44Dk+3>ge13>pl{44MoI3`PtF3`PuQ3<?b444Djh45<tX z3;_&94EYRM45<vs3?&Q<&iMtEMVaXtB^t?^3PuJ-W(wh%d8rBkMfq8&$t4VMjUf!F z48;s349*O03~mezAVndm#U;*eZVU`T45<w145bV?42cXy3=Bc3>7_Y|MGOpX4EYRs z3?*Q?h#?(py%B>Rg8_pAgB6maP|b$O88TQf=rWiv=)yh0;Fh0P;+9{Oo~mG^XP{sO zb|};h3RVh+7P=<7AP*4d<}ij-h9ZVyhD@*<6+lUX!4T{=0|o;IhOpG4;>`R!1p@;^ zJp%&+;>-lcDJWhU7-XQaZUc%bP`+efVF2Yv76ulujKTl^3=9kg|NsBL2<C$lAsYjX z2}*}VVU)y8l#W5Kh#BI-|63W1K!F0`AxK6B78V9ZMn)dw6v)WLz{sHggP-AtG~*8$ zrXRA*KO|Usco@GYemDFn^;3#fhM|jJhJisqhM`wbhJizdahebVGf0y>gBF7+{yczW z5fT&RB0&ZwkQqvhjNN;Gxb9`#yZ7goz07;Xeo6dT`A>pv@1JtfAFe;Q{BdRH`+nue zOVQ~QS^qPz)^h%55d4w;pF!-Y*MA0Xt8f1qB<HUE&%k_U@qY#p&+7jSEIU^GXAt(_ z{?EX!ruLsfJg@5i|G$bx{~3~4g#Q2kw!-f}L&46V|NnPRdi4MQ2d6pz|MwiZ@SlNe z?~nigJ613H|9=xl=KudSQx*RI@3fr%|Npc7cK`psp3(FF|0hnf|Nr0p`0@Y$zX!Me z|9_cR^Pho1^uz!E?amti|9_mu^#A{|x7Pm|;+L-Y&meMs?tg~zBVio>|9_B5{m)SP zch!FeuWNe$8A_jv{bwlV&;8FJBkjO3g^ll5jYzj>HxCz5jPWptFt9Ly3S&sJh9p%m V`LyHrAyD`s*9o9fpZNvDSpcL@XVCxv literal 0 HcmV?d00001 diff --git a/dlls/gdi32/tests/cff.sfd b/dlls/gdi32/tests/cff.sfd new file mode 100644 index 00000000000..088dcecc704 --- /dev/null +++ b/dlls/gdi32/tests/cff.sfd @@ -0,0 +1,71 @@ +SplineFontDB: 3.0 +FontName: WineTestCFF +FullName: WineTestCFF +FamilyName: WineTestCFF +Weight: Regular +Copyright: Copyright(c) 2026 Wine Project +UComments: "#pragma makedep otf" +Version: 001.000 +ItalicAngle: 0 +UnderlinePosition: -100 +UnderlineWidth: 50 +Ascent: 800 +Descent: 200 +InvalidEm: 0 +LayerCount: 2 +Layer: 0 0 "Back" 1 +Layer: 1 0 "Fore" 0 +XUID: [1021 820 1266790224 8728248] +OS2Version: 0 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1776459418 +ModificationTime: 1776485140 +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: 0 28 11 +BeginPrivate: 0 +EndPrivate +BeginChars: 256 1 + +StartChar: zero +Encoding: 48 48 0 +Width: 1000 +Flags: H +LayerCount: 2 +Fore +SplineSet +392 624 m 0 + 389.000022888 624 386.000022888 624 383 624 c 0 + 267.939740009 595.893556721 193.103101666 477.990871628 209 360 c 0 + 188.189011503 240.233056337 277.262329295 144.585963957 398 159 c 0 + 420.568423556 158.914300294 437.595888407 160.035977779 458 174 c 0 + 576.77492213 199.252966911 654.742061929 330.670439307 644 450 c 0 + 659.739813253 565.231194559 547.015903323 635.657432906 449 645 c 0 + 425.568450805 647.870332424 406.287034473 640.721319603 386 636 c 0 + 360.384076063 632.200638278 337.488412015 620.970317136 332 603 c 0 + 320 597 l 1025 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index c56180b1ce6..df6b2518ed5 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -154,7 +154,7 @@ static BOOL write_tmp_file( const void *data, DWORD *size, char *tmp_name ) return ret; } -static BOOL write_ttf_file(const char *fontname, char *tmp_name) +static BOOL write_font_file(const char *fontname, char *tmp_name) { void *rsrc_data; DWORD rsrc_size; @@ -1671,7 +1671,7 @@ static void test_GetGlyphIndices(void) ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]); DeleteObject(SelectObject(hdc, hOldFont)); - ret = write_ttf_file("wine_nul.ttf", ttf_name); + ret = write_font_file("wine_nul.ttf", ttf_name); ok(ret, "Failed to create test font file.\n"); font = load_font(ttf_name, &font_size); ok(font != NULL, "Failed to map font file.\n"); @@ -4132,6 +4132,49 @@ static void test_GetTextMetrics(void) ReleaseDC(0, hdc); } +static void test_CFF_external_leading(void) +{ + char font_file[MAX_PATH]; + DWORD num, ret; + HDC hdc; + LOGFONTW lf; + HFONT hfont, hfont_prev; + TEXTMETRICW tm; + + if (!write_font_file("cff.otf", font_file)) + { + skip("Failed to create otf file for testing\n"); + return; + } + + num = AddFontResourceExA(font_file, FR_PRIVATE, 0); + ok(num == 1, "AddFontResourceExA should add 1 font from cff.otf, got %ld\n", num); + if (num == 0) goto cleanup; + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = -18; + wcscpy(lf.lfFaceName, L"WineTestCFF"); + hfont = CreateFontIndirectW(&lf); + ok(hfont != NULL, "CreateFontIndirectW failed\n"); + + hdc = GetDC(NULL); + hfont_prev = SelectObject(hdc, hfont); + ret = GetFontData(hdc, MS_MAKE_TAG('C','F','F',' '), 0, NULL, 0); + ok(ret != GDI_ERROR, "Expected CFF table, got GDI_ERROR\n"); + ok(GetTextMetricsW(hdc, &tm), "GetTextMetricsW failed\n"); + ok(tm.tmExternalLeading == 0, "Expected tmExternalLeading 0, got %ld\n", tm.tmExternalLeading); + + SelectObject(hdc, hfont_prev); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); + ret = RemoveFontResourceExA(font_file, FR_PRIVATE, 0); + ok(ret, "RemoveFontResourceExA error %ld\n", GetLastError()); + + cleanup: + ret = DeleteFileA(font_file); + ok(ret, "Failed to delete font file, %ld.\n", GetLastError()); +} + static void test_nonexistent_font(void) { static const struct @@ -5239,7 +5282,7 @@ static void test_AddFontMemResource(void) GetLastError()); /* Now with scalable font */ - bRet = write_ttf_file("wine_test.ttf", ttf_name); + bRet = write_font_file("wine_test.ttf", ttf_name); ok(bRet, "Failed to create test font file.\n"); font = load_font(ttf_name, &font_size); @@ -5967,7 +6010,7 @@ static void test_CreateScalableFontResource(void) ULONG (WINAPI *pNtGdiMakeFontDir)( DWORD embed, BYTE *buffer, UINT size, const WCHAR *path, UINT len ); int i; - if (!write_ttf_file("wine_test.ttf", ttf_name)) + if (!write_font_file("wine_test.ttf", ttf_name)) { skip("Failed to create ttf file for testing\n"); return; @@ -6290,7 +6333,7 @@ static void test_vertical_font(void) "@MS UI Gothic", /* has vmtx table, available on native */ }; - if (!write_ttf_file("vertical.ttf", ttf_name)) + if (!write_font_file("vertical.ttf", ttf_name)) { skip("Failed to create ttf file for testing\n"); return; @@ -6329,7 +6372,7 @@ static void test_vertical_font(void) DeleteFileA(ttf_name); - if (!write_ttf_file("vertical2.ttf", ttf_name)) + if (!write_font_file("vertical2.ttf", ttf_name)) { skip("Failed to create ttf file for testing\n"); return; @@ -7068,7 +7111,7 @@ static void test_long_names(void) int ret; HDC dc; - if (!write_ttf_file("wine_longname.ttf", ttf_name)) + if (!write_font_file("wine_longname.ttf", ttf_name)) { skip("Failed to create ttf file for testing\n"); return; @@ -7114,13 +7157,13 @@ static void test_ttf_names(void) int ret; HDC dc; - if (!write_ttf_file("wine_ttfnames.ttf", ttf_name)) + if (!write_font_file("wine_ttfnames.ttf", ttf_name)) { skip("Failed to create ttf file for testing\n"); return; } - if (!write_ttf_file("wine_ttfnames_bold.ttf", ttf_name_bold)) + if (!write_font_file("wine_ttfnames_bold.ttf", ttf_name_bold)) { skip("Failed to create ttf file for testing\n"); DeleteFileA(ttf_name); @@ -7194,20 +7237,20 @@ static void test_lang_names(void) return; } - if (!write_ttf_file( "wine_langnames.ttf", ttf_name )) + if (!write_font_file( "wine_langnames.ttf", ttf_name )) { skip( "Failed to create ttf file for testing\n" ); return; } - if (!write_ttf_file( "wine_langnames2.ttf", ttf_name2 )) + if (!write_font_file( "wine_langnames2.ttf", ttf_name2 )) { skip( "Failed to create ttf file for testing\n" ); DeleteFileA( ttf_name ); return; } - if (!write_ttf_file( "wine_langnames3.ttf", ttf_name3 )) + if (!write_font_file( "wine_langnames3.ttf", ttf_name3 )) { skip( "Failed to create ttf file for testing\n" ); DeleteFileA( ttf_name2 ); @@ -7848,7 +7891,7 @@ static void test_font_weight(void) BOOL bret; HDC hdc; - bret = write_ttf_file("wine_heavy.ttf", ttf_name); + bret = write_font_file("wine_heavy.ttf", ttf_name); ok(bret, "Failed to create test font file.\n"); count = AddFontResourceExA(ttf_name, 0, NULL); @@ -8067,6 +8110,7 @@ START_TEST(font) skip("Arial Black or Symbol/Wingdings is not installed\n"); test_EnumFontFamiliesEx_default_charset(); test_GetTextMetrics(); + test_CFF_external_leading(); test_RealizationInfo(); test_GetTextFace(); test_GetGlyphOutline(); diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc index 2f1273d1e42..340e281a145 100644 --- a/dlls/gdi32/tests/resource.rc +++ b/dlls/gdi32/tests/resource.rc @@ -55,3 +55,6 @@ wine_nul.ttf RCDATA wine_nul.ttf /* @makedep: wine_heavy.ttf */ wine_heavy.ttf RCDATA wine_heavy.ttf + +/* @makedep: cff.otf */ +cff.otf RCDATA cff.otf -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10603