[PATCH v9 0/3] MR10603: win32u/freetype: Fix tmExternalLeading for CFF fonts.
This fixes font scaling issues with CFF fonts this was discovered from games utilizing DxLib. https://github.com/yumetodo/DxLib/tree/master https://dxlib.xsrv.jp/index.html I've ran tests on Windows and to confirm that this change is consistent with a number of fonts. Before: {width="801" height="600"} After (this matches the windows visual from testing in a VM): {width="767" height="572"} Related Proton Issue: https://github.com/ValveSoftware/Proton/issues/7299 Full Disclosure: An LLM was used to assist in finding this bug, the original fix written by the LLM wrote a loader binary that changed the pointers for `GetTextMetricsA` and `GetTextMetricsW` to point to a custom implementation that always set `tmExternalLeading`. The LLM determined that `GDI returns 0 when (winAscent + winDescent) > (Ascender - Descender)`, after testing on WIndows I found this to be incorrect, the actual difference is that CFF fonts always set `tmExternalLeading` to 0. ~~The test case for this fix was LLM generated but reviewed and tested on both Windows and Linux by me.~~ Test case: ``` WINEPREFIX=/tmp/wine-font winetricks allfonts WINEPREFIX=/tmp/wine-font ./loader/wine ./dlls/gdi32/tests/i386-windows/gdi32_test.exe ``` Patched: ``` font.c:4266: test_CFF_external_leading: tested 51 CFF fonts (0 failures) ``` Unpatched Wine: ``` font.c:4266: test_CFF_external_leading: tested 51 CFF fonts (51 failures) ``` Windows 11: ``` font.c:4266: test_CFF_external_leading: tested 48 CFF fonts (0 failures) ``` -- v9: gdi32: Add test for tmExternalLeading for CFF fonts. https://gitlab.winehq.org/wine/wine/-/merge_requests/10603
From: Arie Miller <renari@arimil.com> --- dlls/win32u/freetype.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/dlls/win32u/freetype.c b/dlls/win32u/freetype.c index a660b166a0f..42f62dc191a 100644 --- a/dlls/win32u/freetype.c +++ b/dlls/win32u/freetype.c @@ -3392,12 +3392,16 @@ static BOOL freetype_set_outline_text_metrics( struct gdi_font *font ) TM.tmHeight = TM.tmAscent + TM.tmDescent; - /* MSDN says: - el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender))) - */ - TM.tmExternalLeading = max(0, SCALE_Y(pHori->Line_Gap - - ((ascent + descent) - - (pHori->Ascender - pHori->Descender)))); + /* MSDN documents the formula: + * el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender))) + * but Windows GDI does not follow this for OpenType-CFF fonts: for any font + * containing a 'CFF ' table it reports tmExternalLeading = 0. + */ + if (font->ntmFlags & NTM_PS_OPENTYPE) + TM.tmExternalLeading = 0; + else + TM.tmExternalLeading = max(0, + SCALE_Y(pHori->Line_Gap - ((ascent + descent) - (pHori->Ascender - pHori->Descender)))); TM.tmAveCharWidth = SCALE_X(pOS2->xAvgCharWidth); if (TM.tmAveCharWidth == 0) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10603
From: Arie Miller <renari@arimil.com> --- fonts/{genttf.ff => genfont.ff} | 2 +- tools/makedep.c | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) rename fonts/{genttf.ff => genfont.ff} (71%) diff --git a/fonts/genttf.ff b/fonts/genfont.ff similarity index 71% rename from fonts/genttf.ff rename to fonts/genfont.ff index 30d1a938ee8..9dc16c4e723 100644 --- a/fonts/genttf.ff +++ b/fonts/genfont.ff @@ -3,4 +3,4 @@ flags = 0 if ($1 == "symbol.sfd") flags = 0x2000 endif -Generate($2, "ttf", flags) +Generate($2, $3, flags) diff --git a/tools/makedep.c b/tools/makedep.c index 90a522640fe..b40993be8ee 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -95,6 +95,7 @@ struct incl_file #define FLAG_RC_PO 0x00100000 /* rc file contains translations */ #define FLAG_RC_HEADER 0x00200000 /* rc file is a header */ #define FLAG_SFD_FONTS 0x00400000 /* sfd file generated bitmap fonts */ +#define FLAG_SFD_OTF 0x00800000 /* sfd file generated otf font */ #define FLAG_C_IMPLIB 0x01000000 /* file is part of an import library */ #define FLAG_C_UNIX 0x02000000 /* file is part of a Unix library */ #define FLAG_C_CXX 0x04000000 /* file uses C++ */ @@ -1022,6 +1023,10 @@ static void parse_pragma_directive( struct file *source, char *str ) strarray_add( array, xstrdup( strtok( NULL, "" ))); return; } + else if (!strcmp( flag, "otf" )) + { + source->flags |= FLAG_SFD_OTF; + } } else { @@ -1549,6 +1554,7 @@ static struct file *open_include_file( const struct makefile *make, struct incl_ if ((file = open_local_generated_file( make, source, ".tab.h", ".y" ))) return file; if ((file = open_local_generated_file( make, source, ".h", ".idl" ))) return file; if (fontforge && (file = open_local_generated_file( make, source, ".ttf", ".sfd" ))) return file; + if (fontforge && (file = open_local_generated_file( make, source, ".otf", ".sfd" ))) return file; if (convert && rsvg && icotool) { if ((file = open_local_maintainer_file( make, source, ".bmp", ".svg" ))) return file; @@ -3282,21 +3288,23 @@ static void output_source_x( struct makefile *make, struct incl_file *source, co */ static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj ) { - char *ttf_obj = strmake( "%s.ttf", obj ); - char *ttf_file = src_dir_path( make, ttf_obj ); + int is_otf = source->file->flags & FLAG_SFD_OTF; + const char *ext = is_otf ? "otf" : "ttf"; + char *font_obj = strmake( "%s.%s", obj, ext ); + char *font_file = src_dir_path( make, font_obj ); if (fontforge && !make->src_dir) { - output( "%s: %s\n", ttf_file, source->filename ); - output( "\t%s%s -script %s %s $@\n", cmd_prefix( "GEN" ), - fontforge, root_src_dir_path( "fonts/genttf.ff" ), source->filename ); - if (!(source->file->flags & FLAG_SFD_FONTS)) strarray_add( &make->font_files, ttf_obj ); - strarray_add( &make->maintainerclean_files, ttf_obj ); + output( "%s: %s\n", font_file, source->filename ); + output( "\t%s%s -script %s %s $@ %s\n", cmd_prefix( "GEN" ), + fontforge, root_src_dir_path( "fonts/genfont.ff" ), source->filename, ext ); + if (!(source->file->flags & FLAG_SFD_FONTS)) strarray_add( &make->font_files, font_obj ); + strarray_add( &make->maintainerclean_files, font_obj ); } if (source->file->flags & FLAG_INSTALL) { - install_data_file_src( make, source->name, ttf_obj, "$(datadir)/wine/fonts" ); - output_srcdir_symlink( make, ttf_obj ); + install_data_file_src( make, source->name, font_obj, "$(datadir)/wine/fonts" ); + output_srcdir_symlink( make, font_obj ); } if (source->file->flags & FLAG_SFD_FONTS) @@ -3308,8 +3316,8 @@ static void output_source_sfd( struct makefile *make, struct incl_file *source, char *args = strtok( NULL, "" ); strarray_add( &make->all_targets[0], xstrdup( font )); - output( "%s: %s %s\n", obj_dir_path( make, font ), sfnt2fon, ttf_file ); - output( "\t%s%s -q -o $@ %s %s\n", cmd_prefix( "GEN" ), sfnt2fon, ttf_file, args ); + output( "%s: %s %s\n", obj_dir_path( make, font ), sfnt2fon, font_file ); + output( "\t%s%s -q -o $@ %s %s\n", cmd_prefix( "GEN" ), sfnt2fon, font_file, args ); install_data_file( make, source->name, font, "$(datadir)/wine/fonts", NULL ); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10603
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 | 77 +++++++++++++++++++++++++++++++++++ dlls/gdi32/tests/font.c | 70 +++++++++++++++++++++++++------ dlls/gdi32/tests/resource.rc | 3 ++ 5 files changed, 138 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..854d1533a9648732c5763636fa05da08f9adfa0a GIT binary patch literal 1788 zcmeYd3Grv(W@unwW-xGeb5jVtlXH-PfmMcqfpMOjTZr$*Sv(sU7}#zwFfhotySTbB zh%$&UFtF_b@%@AKjUrl;nHU%t6&M&85|VQh3mABruQ4z%?_gkHbjnCgOwnr$`NF`! z08($3k&&9n{+hX%fq?-erjn6cQo(+K;Vc6K8;H-5n^;l6z!bp1z`!WMz`($kmzbNn zKKcJd1_s6k1_mbcg8br=|2r6r85mgpFfcGEFff9YGBE6m6Sa@$xB1Gz&HRFafq~%} zhrbkrK6shoEW=!;R;E@41_llWCXgsZ4|Bo)4#qDK^-Qf`lc17diiv?CfB~$Yh4}^J z1O`?H2Bt11kS}^5G~)vXLq;Z$5>`&I4iEuy4~PcifHc<>h64-+3<hw!K0xdSOM?iA z5BM0?!R?o0u!FK08Mqlrp=>4wc7};iHZy}d!%HZeg@Kz<6Ut^~;Aaelve_888EYAs z85mhWZnI%vfU+4G#28|sY$gUihDIoxnZb`?CX~&>AjT*NWwSEKF`7czYz$(IsSM5x z`3waNl?+7;nGER+84M*18Vtz{nhXjIMhpfFMhs>Q3Jl>4nGAUhsSFAX0SrY9`3zYM zsSL>sB@7JC`303lnduoN8p)apMg~S^3gMY~sR{u_`B|ySB@A$lAq=Su#SA43&J1o0 zZVU_{MIouhCC+Yc3=BaGsSN21r3^U?i3~*y3_+>sr8$X33=D1z`3!jsC1ARUAsuYJ z5rZCs0fPdA6_TS+&4$PsGFUL^GMF&v!ac#@mY-MRmS2>fs$isNpkM`dDAWxKRtkm| zx+c0H4-n_(FoslyB8FmyOt2djKuLnZ5bQPs1_K6$u+*aB%=|nB0|P@n0|Nu%%ml|N zC|(&DWT3Hb1Bxk7zGPrw0Ody(1{Sc4!T<jZ3=9VU|Np-T=7SO;8v~39N{2*Yl*CPx zjzO=88REkKTN#W%fdb(nNJa)076wK}Mjqr8$jHRN$e{m&pW%lz;}038AF|9pBv^WQ z7{4ceH~cB}Q;JoFp^IOJfk8lqp;u6bfkTFInh*msNRvE+7K17NJb+{o5)<SiK?Wv} z8A^<d-Ftty?q%G&_ve<q%zMRtN&Hy(Pl9dlpK{S3u0OZ@ab@TGe&xqY(diRe|1+@G za{gx!{E_~jLF}p5e+F)=Z~qx2=dS(Fz<g%$e+CiH>i-NZJ68N>5cc5y&%myx_MbsK zuj>E*zluix8Io9p{{R2B!tXyr!Oo!n|94J$^#A_{r#b)s_Z+$KpMh)dkN^KWRxkSh ze-lUM|Nk{p75@M4w4DF{|Five|Np<9(ewZRCr-2f|KI)i@&Et72e<zJf0<YFpMgR2 z!~g&7&Km#!f1Jkj|NpYL*8dsem#+BFAaZ{0e}?iSVI2See~?Q3&rtez)qe)BYkL0~ zN}r4UXDH^+{m&pH?Z7dGjqg{DNVjM=4;NC5@i2%murPoMV@R@wBvml^wBz?7Q1~I& M37}G+`31vS04A|&%>V!Z literal 0 HcmV?d00001 diff --git a/dlls/gdi32/tests/cff.sfd b/dlls/gdi32/tests/cff.sfd new file mode 100644 index 00000000000..11ff0b0731b --- /dev/null +++ b/dlls/gdi32/tests/cff.sfd @@ -0,0 +1,77 @@ +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] +FSType: 0 +OS2Version: 4 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 1 +CreationTime: 1776459418 +ModificationTime: 1776488787 +PfmFamily: 17 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 500 +VLineGap: 0 +OS2TypoAscent: 880 +OS2TypoAOffset: 0 +OS2TypoDescent: -120 +OS2TypoDOffset: 0 +OS2TypoLinegap: 500 +OS2WinAscent: 1000 +OS2WinAOffset: 0 +OS2WinDescent: 240 +OS2WinDOffset: 0 +HheadAscent: 880 +HheadAOffset: 0 +HheadDescent: -120 +HheadDOffset: 0 +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
I fixed this issue by copying the font metrics from fkKikaiChokoku to my sfd. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_136892
On Fri Apr 17 23:37:06 2026 +0000, Arie Miller wrote:
I spent a few hours looking into this and this is actually a really big change to the build system because it currently is only setup to generate `ttf` files which will not trigger this issue. The notable difference is that our tool doesn't embed timestamps for reproducible builds. You don't have to include the generated file, `cff.otf`, in your commit.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137097
Akihiro Sagawa (@sgwaki) commented about fonts/genfont.ff:
if ($1 == "symbol.sfd") flags = 0x2000 endif -Generate($2, "ttf", flags) +Generate($2, $3, flags) Although it doesn't cause an error, the second parameter of `Generate` is a bitmap type, not a type of font. See https://fontforge.org/docs/scripting/scripting-alpha.html#Generate for details.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137100
Akihiro Sagawa (@sgwaki) commented about tools/makedep.c:
if ((file = open_local_generated_file( make, source, ".tab.h", ".y" ))) return file; if ((file = open_local_generated_file( make, source, ".h", ".idl" ))) return file; if (fontforge && (file = open_local_generated_file( make, source, ".ttf", ".sfd" ))) return file; + if (fontforge && (file = open_local_generated_file( make, source, ".otf", ".sfd" ))) return file;
I would suggest the following style: ```c if (fontforge) { if ((file = open_local_generated_file( make, source, ".ttf", ".sfd" ))) return file; if ((file = open_local_generated_file( make, source, ".otf", ".sfd" ))) return file; } ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137101
Akihiro Sagawa (@sgwaki) commented about tools/makedep.c:
*/ static void output_source_sfd( struct makefile *make, struct incl_file *source, const char *obj ) { - char *ttf_obj = strmake( "%s.ttf", obj ); - char *ttf_file = src_dir_path( make, ttf_obj ); + int is_otf = source->file->flags & FLAG_SFD_OTF; + const char *ext = is_otf ? "otf" : "ttf"; + char *font_obj = strmake( "%s.%s", obj, ext ); + char *font_file = src_dir_path( make, font_obj ); As mentioned above, the third parameter is no longer needed, so this code block can be simplified.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137102
Akihiro Sagawa (@sgwaki) commented about tools/makedep.c:
strarray_add( array, xstrdup( strtok( NULL, "" ))); return; } + else if (!strcmp( flag, "otf" )) + { + source->flags |= FLAG_SFD_OTF; + }
For consistency, how about using the following style: ```c else if (!strcmp( flag, "otf" )) source->flags |= FLAG_SFD_OTF; ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137103
I imagine the work for OTF support was quite challenging. Great job on this. There are a few points to improve, but they should be easy to address. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137104
On Mon Apr 20 14:09:08 2026 +0000, Akihiro Sagawa wrote:
The notable difference is that our tool doesn't embed timestamps for reproducible builds. You don't have to include the generated file, `cff.otf`, in your commit. I saw that the other `ttf` were commit to the repo so I followed that convention, I'll remove it.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10603#note_137117
participants (3)
-
Akihiro Sagawa (@sgwaki) -
Arie Miller -
Arie Miller (@Arimil)