[PATCH v2 1/7] gdi32/tests: Add test fonts with names in several languages.

Rémi Bernon rbernon at codeweavers.com
Thu Sep 17 10:01:31 CDT 2020


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

v2: The first two patches are mostly unrelated to the optimization
    goal, and are there to test and fix the face lookup logic wrt
    non-english names.

    Then, change of plans, although the series doesn't change much from
    the previous patches, I now intend to do the font parsing by hand,
    getting rid of freetype when possible, and not relying on fontconfig
    anymore. This makes the font face listing faster for all platforms
    and cases.

    In order to achieve that, as previously, I need to first invert the
    creation order between FT_Face and gdi32 Face. Making face creation
    independent of freetype first, and make it provide all required data
    to then create FT_Face from it.

    Next I intend to send patches that iteratively add font info parsing
    with a FreeType fallback to support other font formats. Ultimately
    it will also allow us to start using FreeType cache manager instead
    of creating the faces manually. It shouldn't change much for the
    initial listing --as in any case we should avoid using FreeType at
    that point-- but it could also benefit to the GdiFont logic too.

    Last in the future patches, I'm planning on improving the font
    family indexation performance, reducing the registry load once
    re-parsing the system fonts is faster than caching them, listing
    fontconfig fonts directly from its caches, and possibly then
    implementing some kind of lazy initialization.

    Overall I think it can achieve ~30% to ~50% prefix startup time
    reduction, as well as good improvements on process startup time
    (with the prefix already started).

 dlls/gdi32/tests/Makefile.in         |   3 +
 dlls/gdi32/tests/font.c              | 265 +++++++++++++++++++++++++++
 dlls/gdi32/tests/resource.rc         |   9 +
 dlls/gdi32/tests/wine_langnames.sfd  | 138 ++++++++++++++
 dlls/gdi32/tests/wine_langnames.ttf  | Bin 0 -> 2792 bytes
 dlls/gdi32/tests/wine_langnames2.sfd |  80 ++++++++
 dlls/gdi32/tests/wine_langnames2.ttf | Bin 0 -> 2016 bytes
 dlls/gdi32/tests/wine_langnames3.sfd |  78 ++++++++
 dlls/gdi32/tests/wine_langnames3.ttf | Bin 0 -> 2048 bytes
 9 files changed, 573 insertions(+)
 create mode 100644 dlls/gdi32/tests/wine_langnames.sfd
 create mode 100644 dlls/gdi32/tests/wine_langnames.ttf
 create mode 100644 dlls/gdi32/tests/wine_langnames2.sfd
 create mode 100644 dlls/gdi32/tests/wine_langnames2.ttf
 create mode 100644 dlls/gdi32/tests/wine_langnames3.sfd
 create mode 100644 dlls/gdi32/tests/wine_langnames3.ttf

diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 8b722cfe5d2..975750886e4 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -24,6 +24,9 @@ FONT_SRCS = \
 	wine_test.sfd \
 	wine_ttfnames.sfd \
 	wine_ttfnames_bold.sfd \
+	wine_langnames.sfd \
+	wine_langnames2.sfd \
+	wine_langnames3.sfd \
 	wine_vdmx.sfd
 
 RC_SRCS = resource.rc
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index f5c8d4dac3b..bfcfad30e24 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -2757,6 +2757,12 @@ struct enum_fullname_data
     ENUMLOGFONTA *elf;
 };
 
+struct enum_fullname_data_w
+{
+    int total, size;
+    ENUMLOGFONTW *elf;
+};
+
 struct enum_font_dataW
 {
     int total, size;
@@ -3110,6 +3116,23 @@ static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRIC
     return 1;
 }
 
+static INT CALLBACK enum_fullname_data_proc_w( const LOGFONTW *lf, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam )
+{
+    struct enum_fullname_data_w *efnd = (struct enum_fullname_data_w *)lParam;
+
+    if (type != TRUETYPE_FONTTYPE) return 1;
+
+    if (efnd->total >= efnd->size)
+    {
+        efnd->size = max( (efnd->total + 1) * 2, 256 );
+        efnd->elf = heap_realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
+        if (!efnd->elf) return 0;
+    }
+    efnd->elf[efnd->total++] = *(ENUMLOGFONTW *)lf;
+
+    return 1;
+}
+
 static void test_EnumFontFamiliesEx_default_charset(void)
 {
     struct enum_font_data efd;
@@ -7007,6 +7030,247 @@ static void test_ttf_names(void)
     ReleaseDC(NULL, dc);
 }
 
+static void test_lang_names(void)
+{
+    static const WCHAR name_cond_ja_w[] = {0x30d5,0x30a9,0x30f3,0x30c8,0x540d,' ','C','o','n','d',' ','(','j','a',')',0};
+    static const WCHAR name_cond_ja_reg_w[] = {0x30d5,0x30a9,0x30f3,0x30c8,0x540d,' ','C','o','n','d',' ','(','j','a',')',' ','R','e','g',0};
+    static const WCHAR name_cond_ja_reg_ja_w[] = {0x30d5,0x30a9,0x30f3,0x30c8,0x540d,' ','C','o','n','d',' ','(','j','a',')',' ','R','e','g',' ','(','j','a',')',0};
+    static const WCHAR name_wws_ja_w[] = {0x30d5,0x30a9,0x30f3,0x30c8,0x540d,' ','W','W','S',' ','(','j','a',')',0};
+
+    struct enum_fullname_data efnd;
+    struct enum_fullname_data_w efnd_w;
+    char ttf_name[MAX_PATH], ttf_name2[MAX_PATH], ttf_name3[MAX_PATH];
+    LOGFONTA font = {0};
+    LOGFONTW font_w = {0};
+    int ret, i;
+    HDC dc;
+    const WCHAR *primary_family, *primary_fullname;
+
+    if (PRIMARYLANGID(GetUserDefaultLangID()) != LANG_ENGLISH && PRIMARYLANGID(GetUserDefaultLangID()) != LANG_JAPANESE)
+    {
+        skip( "Primary language is neither English nor Japanese, skipping test\n" );
+        return;
+    }
+
+    if (!write_ttf_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 ))
+    {
+        skip( "Failed to create ttf file for testing\n" );
+        DeleteFileA( ttf_name );
+        return;
+    }
+
+    if (!write_ttf_file( "wine_langnames3.ttf", ttf_name3 ))
+    {
+        skip( "Failed to create ttf file for testing\n" );
+        DeleteFileA( ttf_name2 );
+        DeleteFileA( ttf_name );
+        return;
+    }
+
+    ret = AddFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+    ok( ret, "AddFontResourceEx() failed\n" );
+
+    dc = GetDC( NULL );
+
+    if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+    {
+        primary_family = L"Wine Lang Cond (en)";
+        primary_fullname = L"Wine Lang Cond Reg (en)";
+    }
+    else
+    {
+        primary_family = name_cond_ja_w;
+        primary_fullname = name_cond_ja_reg_w;
+    }
+
+    for (i = 0; i < 3; ++i)
+    {
+        /* check that lookup by preferred or WWS family / full names or postscript FontName doesn't work */
+
+        strcpy( font.lfFaceName, "Wine Lang (en)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang Condensed Bold (ko)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        wcscpy( font_w.lfFaceName, name_wws_ja_w );
+        memset( &efnd_w, 0, sizeof(efnd_w) );
+        EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+        ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
+
+        strcpy( font.lfFaceName, "Reg WWS (zh-tw)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang (en) Reg WWS (en)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "WineLangNamesRegular" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        /* then, the primary ttf family name always works */
+
+        wcscpy( font_w.lfFaceName, primary_family );
+        memset( &efnd_w, 0, sizeof(efnd_w) );
+        EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+        ok( efnd_w.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
+
+        if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+        {
+            wcscpy( font_w.lfFaceName, name_cond_ja_w );
+            memset( &efnd_w, 0, sizeof(efnd_w) );
+            EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+            ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
+        }
+
+        /* if there is no primary ttf family name, the english ttf name, or postscript FamilyName are used instead */
+
+        strcpy( font.lfFaceName, "Wine_Lang_Names" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        if (i == 2)
+            ok( efnd.total == 1, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+        else
+            ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        /* same goes for ttf full names */
+
+        wcscpy( font_w.lfFaceName, primary_fullname );
+        memset( &efnd_w, 0, sizeof(efnd_w) );
+        EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+        ok( efnd_w.total == 1, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
+
+        if (efnd_w.total >= 1)
+        {
+            ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfLogFont.lfFaceName, primary_family ),
+                "%d: (%d) unexpected lfFaceName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfLogFont.lfFaceName) );
+            ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfFullName, primary_fullname ),
+                "%d: (%d) unexpected elfFullName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfFullName) );
+            ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfStyle, PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH ? L"Reg (en)" : L"Reg (ja)" ),
+                "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfStyle) );
+        }
+
+        if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+        {
+            wcscpy( font_w.lfFaceName, name_cond_ja_reg_w );
+            memset( &efnd_w, 0, sizeof(efnd_w) );
+            EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+            ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
+        }
+
+        wcscpy( font_w.lfFaceName, L"Wine_Lang_Names_Regular" );
+        memset( &efnd_w, 0, sizeof(efnd_w) );
+        EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+        ok( efnd_w.total == i, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
+
+        while (efnd_w.total--)
+        {
+            ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfLogFont.lfFaceName, efnd_w.total == 1 ? L"Wine_Lang_Names" : primary_family ),
+                "%d: (%d) unexpected lfFaceName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfLogFont.lfFaceName) );
+            ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfFullName, L"Wine_Lang_Names_Regular" ),
+                "%d: (%d) unexpected elfFullName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfFullName) );
+            if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+                ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfStyle, efnd_w.total == 1 ? L"Regular" : L"Reg (en)" ),
+                    "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfStyle) );
+            else
+                ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfStyle, L"Reg (ja)" ),
+                    "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfStyle) );
+        }
+
+        if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+        {
+            wcscpy( font_w.lfFaceName, name_cond_ja_reg_ja_w );
+            memset( &efnd_w, 0, sizeof(efnd_w) );
+            EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
+            ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
+        }
+
+        /* another language can also be used for lookup, if the primary langid isn't english, then
+           english seems to have priority, otherwise or if english is already the primary langid,
+           the family name with the smallest langid is used as secondary lookup language. */
+
+        strcpy( font.lfFaceName, "Wine Lang Cond (zh-tw)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH)
+            todo_wine ok( efnd.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+        else /* (zh-tw) doesn't match here probably because there's an (en) name too */
+            ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang Cond (en)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        /* either because it's the primary language, or because it's a secondary */
+        ok( efnd.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang Cond (fr)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        /* as wine_langnames3.sfd does not specify (en) name, (fr) is preferred */
+        if (i == 2) todo_wine ok( efnd.total == 1, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+        else ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang Cond (ko)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        /* that doesn't apply to full names */
+
+        strcpy( font.lfFaceName, "Wine Lang Cond Reg (zh-tw)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        strcpy( font.lfFaceName, "Wine Lang Cond Reg (fr)" );
+        memset( &efnd, 0, sizeof(efnd) );
+        EnumFontFamiliesExA( dc, &font, enum_fullname_data_proc, (LPARAM)&efnd, 0 );
+        ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
+
+        if (i == 0)
+        {
+            ret = AddFontResourceExA( ttf_name2, FR_PRIVATE, 0 );
+            ok( ret, "AddFontResourceEx() failed\n" );
+        }
+        else if (i == 1)
+        {
+            ret = AddFontResourceExA( ttf_name3, FR_PRIVATE, 0 );
+            ok( ret, "AddFontResourceEx() failed\n" );
+        }
+    }
+
+    ret = RemoveFontResourceExA( ttf_name3, FR_PRIVATE, 0 );
+    ok( ret, "RemoveFontResourceEx() failed\n" );
+
+    DeleteFileA( ttf_name3 );
+
+    ret = RemoveFontResourceExA( ttf_name2, FR_PRIVATE, 0 );
+    ok( ret, "RemoveFontResourceEx() failed\n" );
+
+    DeleteFileA( ttf_name2 );
+
+    ret = RemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+    ok( ret, "RemoveFontResourceEx() failed\n" );
+
+    DeleteFileA( ttf_name );
+    ReleaseDC( NULL, dc );
+}
+
 typedef struct
 {
     USHORT majorVersion;
@@ -7419,6 +7683,7 @@ START_TEST(font)
     test_GetCharWidthI();
     test_long_names();
     test_ttf_names();
+    test_lang_names();
     test_char_width();
 
     /* These tests should be last test until RemoveFontResource
diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc
index b5a6107a987..6cbe789880b 100644
--- a/dlls/gdi32/tests/resource.rc
+++ b/dlls/gdi32/tests/resource.rc
@@ -37,3 +37,12 @@ wine_ttfnames.ttf RCDATA wine_ttfnames.ttf
 
 /* @makedep: wine_ttfnames_bold.ttf */
 wine_ttfnames_bold.ttf RCDATA wine_ttfnames_bold.ttf
+
+/* @makedep: wine_langnames.ttf */
+wine_langnames.ttf RCDATA wine_langnames.ttf
+
+/* @makedep: wine_langnames2.ttf */
+wine_langnames2.ttf RCDATA wine_langnames2.ttf
+
+/* @makedep: wine_langnames3.ttf */
+wine_langnames3.ttf RCDATA wine_langnames3.ttf
diff --git a/dlls/gdi32/tests/wine_langnames.sfd b/dlls/gdi32/tests/wine_langnames.sfd
new file mode 100644
index 00000000000..4ce1e70baca
--- /dev/null
+++ b/dlls/gdi32/tests/wine_langnames.sfd
@@ -0,0 +1,138 @@
+SplineFontDB: 3.2
+FontName: WineLangNamesRegular
+FullName: Wine_Lang_Names_Regular
+FamilyName: Wine_Lang_Names
+Weight: Regular
+Copyright: Copyright (c) 2020, Remi Bernon for CodeWeavers
+UComments: "2017-11-17: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -102
+UnderlineWidth: 51
+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: 1599738445
+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
+LangName: 1033 \
+    "" \
+    "Wine Lang Cond (en)" \
+    "Reg (en)" \
+    "" \
+    "Wine Lang Cond Reg (en)" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "Wine Lang (en)" \
+    "Wine Lang Condensed Reg (en)" \
+    "" \
+    "" \
+    "" \
+    "Wine Lang WWS (en)" \
+    "Reg WWS (en)"
+LangName: 1041 \
+    "" \
+    "+MNUwqTDzMMhUDQAA Cond (ja)" \
+    "Reg (ja)" \
+    "" \
+    "+MNUwqTDzMMhUDQAA Cond (ja) Reg" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "+MNUwqTDzMMhUDQAA (ja)" \
+    "+MNUwqTDzMMhUDQAA Condensed Reg (ja)" \
+    "" \
+    "" \
+    "" \
+    "+MNUwqTDzMMhUDQAA WWS (ja)" \
+    "Reg WWS (ja)"
+LangName: 1028 \
+    "" \
+    "Wine Lang Cond (zh-tw)" \
+    "Reg (zh-tw)" \
+    "" \
+    "Wine Lang Cond Reg (zh-tw)" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "" \
+    "Wine Lang (zh-tw)" \
+    "Wine Lang Condensed Reg (zh-tw)" \
+    "" \
+    "" \
+    "" \
+    "Wine Lang WWS (zh-tw)" \
+    "Reg WWS (zh-tw)"
+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_langnames.ttf b/dlls/gdi32/tests/wine_langnames.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..674fd1bc7e42c5051eaa3870bd097e5579e981d4
GIT binary patch
literal 2792
zcmdT`OKcle6g_Wd>@*>?c1cnsqB2cGNveD%c2%{NK_Q{0i_oGZiWgKkCYjhN at z}E6
zqyZ$5*swsN>_D)C1(Xd56=H{=LaIbqAOu1bD#50U5?COz;FECf_}R|KG;5yq=AC=r
z{om`+Kmpi`7hz&D9v^@FmG_q%plOBN_QxJQ9Y-r#NPi&oxv~DpL?E>Qs0``Jscb5b
zeZkwLzvCX7nlIVtFkS}CcHUd*R58D?LCa`*m-L?W+~UmVOUtxx_K?nJ+|=~`wY3Ap
zzi=PVkP&FK0<_ghx-*k4U22AUfb at 0Jp}E{t3QuF4`ZnpNZ0b at TXK<4DXGq&#D(l`K
zjs48~w}9Y}`CPHIaTCWW`aJKCLUQFUJ at fVH<i6M+xXU5~`1aUuZ_9b(h0nf32VfY+
z6_R^k2$zdGKIeQ{-Y|Si<-79J@;O#jM>Lhs8$_QkVo~HWn49s2A=Q1ge5%`ssz!1V
z;8QP&v$~#`IX%t(3}VoXZbWh3kHn9uDq=%1GDgm#`&+T*Qg?s1>u6)7#Bw`@Y at QZ>
zLJzV>{&VA+mV^q{94N^}_U5%E!p#>oEbjm3%b#V=jr>k97ei{SBJ6;P2J|f{^v9MP
zEUZSBf`K1m%cenyB~#b|VJ|lX)!(sYmT)x^4Ic_W7!4opP@!K}R*WnEOmrACG^b28
z!ijrbYOL-f`Bk49Q6uYDrFfm{qe at TEk4cRc?!m_z8=SeD8k?M at a~fMXpgz<%fRI|%
zIEWUbOXCps8c%8*M!WHj#;w?I+|sxW&1Q>Cjtnq*%)c}?&}MaOY~h&oh{hpwSPL45
z at v!x##;rJN-O#uV2Lla0mYIKwTkJQ|{t;Z(*gyy?8k?BGEsZVosh2bkz*b*q97LB|
z*Eqyn9 at 03B6UGINThVEJs&O0cHU9K*n0^nMhcu>Nvz$wq|BoZ)nC6GjVm_yF7>@ax
z#;s^KuW3x1=1&+#4tXr1fLWxGL5csiE=-}DX9SMFdx%HjB1;(?Lqr95)bmKq at GS5Y
zJJY;LaHlZu%M^j(Tz;`Io6eN%uBmQ2;zXPtd(_R&+Cy%^%X#)pu3!)6rrm^_ns*CS
zNYIBzZ5t!B<1wbPZI9L^GMBt=ip_eiJ(BX$)b^(BF4rSdViftR)To=*S8+ew667pU
zNE}4?vU7Nz;;y(&R^29XmH}ibSwvEszKA*UBwf)Npmr}`=)KiKA)fO}@mwM8+L1oT
zK4nXoNeMG~maqF_k^x<uOBHxC;PjsCm3r)!@{XjorC!T%g0U7D?W~`x&FCD)C^^c{
z1}0eHSr*-K2KpSwA*YgdrPj5S%Wf+P`}LMQ{4{hHHTBKSsusT%XSq8SUz>$xYNWH$
z)gqtL<6RPVy`nqK8LD))p4kKw8>6W at u_O{>+oolQu-LAOIo~+%IlnvC$M2 at SO1NVA
z0w;kpw<%oB*+rw0AhyU=?QP*!{M9c{J%6=iw#T>gre5VL9wozP`8w$33t?efo?H2M
zwo+^6?poVD-pO+PitO&AR)wvyl{o+Fo{iRD6&qI(C8fBxF8P>IlsfFQ6~9wzUtZ1p
XE|q(+A(~}v|M~se`X{2X`Md64$O)6Q

literal 0
HcmV?d00001

diff --git a/dlls/gdi32/tests/wine_langnames2.sfd b/dlls/gdi32/tests/wine_langnames2.sfd
new file mode 100644
index 00000000000..50199af9adf
--- /dev/null
+++ b/dlls/gdi32/tests/wine_langnames2.sfd
@@ -0,0 +1,80 @@
+SplineFontDB: 3.2
+FontName: WineLangNamesRegular
+FullName: Wine_Lang_Names_Regular
+FamilyName: Wine_Lang_Names
+Weight: Regular
+Copyright: Copyright (c) 2020, Remi Bernon for CodeWeavers
+UComments: "2017-11-17: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -102
+UnderlineWidth: 51
+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: 1599738445
+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
+LangName: 1028 \
+    "" \
+    "Wine Lang Cond (zh-tw)" \
+    "Reg (zh-tw)" \
+    "" \
+    "Wine Lang Cond Reg (zh-tw)"
+LangName: 1041 \
+    "" \
+    "+MNUwqTDzMMhUDQAA Cond (ja)" \
+    "Reg (ja)"
+LangName: 1033 \
+    "" \
+    "Wine Lang Cond (en)" \
+    "Reg (en)"
+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_langnames2.ttf b/dlls/gdi32/tests/wine_langnames2.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..47082dbd67e117529574d83755fd19e969cd205f
GIT binary patch
literal 2016
zcmdT_O>A355dL=k>@-kl0)-xk(2^ENP~yDURYfZ!SqU{ggcgM;xl}lh<oTz>&(@2Z
zHe9I0g+nEJ1c?I at 7bqv29^h1oAE{EqfkP30$`y$cI3RL at m~Yn4b}SW%EBiFNGqW?Z
z-^`BoK>>IWR}jN;F1PUF)sGu4Fz_X{BQHFEI)_JanDU1rpL=;KwHWs<0jflKd8Ojj
za42z?@^_?}m5sW=sD2BGjd0&7dh4}Ti;*$#KIH?&wavm;jV9yACMefRzPI|&?(Pxt
zzmiUrsE7|bamG4E`B<q^zkCqtNy at h<53N;KJiLkp`WwpkRlLhJoWV)%pP_65ui{@A
zyqe|yd!#$H>UzDkjT1b-&i!W~xstYT&NlLgGJoQJhYH}^<G+6(>yK}I{xwDct at U+^
z2cSjEK_9C*-?rD<Mr!Z1XUA%su8(*stIHy3O&pqB19Q{w>Md&CZm;St(rS=e#5qSp
zaCXN_h109Jf-JJJbSsVX7Kz2wH8D^`M&vBICB>Rc-7SqoXfu=~@(7I#SBIa-S>BPI
zTVF($P>J3FN^%j}Kl%{v-{|pj{QrE|US{9O_bhYKQe&0k4a6{jWJ6&p(;RTHlWHX5
zKV_ORO%{!qsN<q;4kXlHnI=oPlS&UiG5mCT_~@t_`fY1VU;le?R2LXd#nc=-?j5PI
zdW_;XNj0bD_HIb=9>y=7JHZr|BVJMeX~b*x+;+sr*h}Xk-oX*|NyNu7q;?`cfx~)C
zIzbu|6Z*M`*LYOF7V!>_>o+YgJ^2br><4N86s|?Q#t^n5K86B*j(7)2)$xtPsN0b~
zfibmb`C-O+Tz?kvjHAEDEUKts6CuhdqJ%m-bPOvP=bD0RX at dMbd{k&-FhedxK)--e
zfosTB;;eFKiR59!+N=Y!)!JrQE|%(MY-QY}+>|?E=KV_9%=lqY4NRdLn%U~AzvO!x
zen^KUo)OU7V2*JDVrs_ at 7+sM0)Q!`u9QbC=3ySm(R?V0nP$?M2zH2q_7o)A5g<FTL
zA&umK6dwqe>nT#_*nIccJkAn8g_i5cN1-objXFtJe5UC=$wzRqTPWnJK|NOui at r%E
zU31C^%)G$NpXC#|o+qG-YhK8mX?ODEq|~FA at _#$qrhbo at z#_4RL|eAG8lrQFQF4^e
z(0~;#v*@lnopfE7noioCTK7_J*RqqaJyi0rX+&A{-2d&eUS~s1vZXG`mF>HpetieT
zy`%Ilwa?4F<9_7+;oe$!fSF12bsFRXZ>ayYj)oAT*R*v5X-bOJKjaZtv^r|litlsp
ak8_a!W7(G&;@S4L^AEdwH^pQB|Lh+tiXH<1

literal 0
HcmV?d00001

diff --git a/dlls/gdi32/tests/wine_langnames3.sfd b/dlls/gdi32/tests/wine_langnames3.sfd
new file mode 100644
index 00000000000..ea0dbff57d9
--- /dev/null
+++ b/dlls/gdi32/tests/wine_langnames3.sfd
@@ -0,0 +1,78 @@
+SplineFontDB: 3.2
+FontName: WineLangNamesRegular
+FullName: Wine_Lang_Names_Regular
+FamilyName: Wine_Lang_Names
+Weight: Regular
+Copyright: Copyright (c) 2020, Remi Bernon for CodeWeavers
+UComments: "2017-11-17: Created with FontForge (http://fontforge.org)"
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -102
+UnderlineWidth: 51
+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: 1599738445
+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
+LangName: 1036 \
+    "" \
+    "Wine Lang Cond (fr)" \
+    "Reg (fr)" \
+    "" \
+    "Wine Lang Cond Reg (fr)"
+LangName: 1042 \
+    "" \
+    "Wine Lang Cond (ko)" \
+    "Reg (ko)" \
+    "" \
+    "Wine Lang Cond Reg (ko)"
+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_langnames3.ttf b/dlls/gdi32/tests/wine_langnames3.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..dd76bd478bbb2546cfbbb7e9184cc7f602c59303
GIT binary patch
literal 2048
zcmdT_O>7%Q6#iy*ZMRU79|cv22rX%W1SQU9jVfCCU?tS_U<xWxaw#}lXZ<7MwY70W
zbD~EMNc6y=NZjC54q&U|ghT~GLMTX-1FBlo6Sq=&BI*HRzL_06i4Sc#GS=Jq-kbM7
zFB1p=Pv9aftmN~HuYK@&+XYg;Q#$_YD<|`K5 at Y0lQ2gs}&U#A;|6M>-$*+{^eiK8<
zJLGSW=1Utb2NUvrz#8YdUGdkO-7Y;Nb&dRi%Gzf6`*w%^t!eVjYT&PqZf_qZ{)2R^
zN<reFouIFy<d0VCtqX at Bo+Gc~53e;!KF(p0_73^S>i&f$PT at GuPmy;*zaD&H?a-I?
z3F&^bvEJ(5#xchKi03at)k<3Y at vX0lL)pLZxJ?1@>r3}ORr{^?zWoUkfRyqI*#nSD
z%0(M3IUDOssXfJK at z>T8yKkc`g_h-z)+#ntE`hblkL4C6AI7`5gN!&xDH8merSj~r
zH_9hhaS=J>tV}n9vpN%<Q(wh_U}nsmP1hvYbJcfE<0jiIIpukrN)C6MKgH*GNBZ0S
z&S*j;cLNAji=w at 2Uxs@RcCiZoKVN#5IXCL}GHa2l$HL<cSV$q=7MRU;Qa0{-?PTJ&
zY{!y>Xj at 90P~uK1DgMrO*uuMBX5`tC7cwJ9CdBZcTU+wVKT8v`On1T(1y0;$)noBA
z+3RUh5QUwqs(EAB?%fGyv0|{m5WX~6GLxSTwm3^UgKZoZpBbFMu()k-5 at YfyH3_zw
zx3 at _#7I+4i43>Nmt{H5hj2i~qNQ;)i2{__wgOivP_cZ38E1s8WgC&OLlEJi<RgFir
z&Sis at P8@5L^O%;uU;zy at v55#ZR8U2W(>jR~rnq}>HBA$rL4Z1S9Ly6%2x%9RD|3&y
zD?h6|Stj||&^qhDLZi7E)hgANGg+E)JlAuloijnb=FA6C*a)3+BXSlRtHE;MZv+ty
zmKh_YbrA*n37Jz7r-|y6spDE06bpV>DW2y0LxIYxg7a9TPDD1SoL}<^@;bkk-Xm%R
z%+cfP;Br4fdT^ZLfZy0=j at C1L0cZN1LB0{T@{OnxI9}RyPB;Vk6-_=onR923&!`4G
ztj59EgEjYj0!yqaVpnSBE?nj}r)yNmp#oc4W0zfbF73K5CB3qH&E0M7KqFNls?WO3
z{jT=Ro&N2_Hy`ru)!dYs&lIOTcD7gYV9WoiKZ$o(^ZrOZ$)iT<>6_QKdleaGE=c>A
ndgKM)iz8Yr_<ryHM>@neL!B!h$}+ar-<#Vz-zbZ{|L^_<2BRY9

literal 0
HcmV?d00001

-- 
2.28.0




More information about the wine-devel mailing list