From: Akihiro Sagawa sagawa.aki@gmail.com
Signed-off-by: Akihiro Sagawa sagawa.aki@gmail.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 57 +++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 26 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index e8efa1d196..67a1a20427 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -1935,10 +1935,9 @@ static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_a
static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings) { + int i, count, candidate_mac, candidate_unicode; const TT_NAME_V0 *header; BYTE *storage_area = 0; - USHORT count = 0; - int i, candidate; WORD format; BOOL exists; HRESULT hr; @@ -1964,7 +1963,7 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP count = GET_BE_WORD(header->count);
exists = FALSE; - candidate = -1; + candidate_unicode = candidate_mac = -1; for (i = 0; i < count; i++) { const TT_NameRecord *record = &header->nameRecord[i]; USHORT platform; @@ -1972,34 +1971,40 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP if (GET_BE_WORD(record->nameID) != id) continue;
- /* Right now only accept unicode and windows encoded fonts */ platform = GET_BE_WORD(record->platformID); - if (platform != OPENTYPE_PLATFORM_UNICODE && - platform != OPENTYPE_PLATFORM_MAC && - platform != OPENTYPE_PLATFORM_WIN) + switch (platform) { - FIXME("platform %i not supported\n", platform); - continue; - } - - /* Skip such entries for now, fonts tend to duplicate those strings as - WIN platform entries. If font does not have WIN or MAC entry for this id, we will - use this Unicode platform entry while assuming en-US locale. */ - if (platform == OPENTYPE_PLATFORM_UNICODE) { - candidate = i; - continue; + /* Skip Unicode or Mac entries for now, fonts tend to duplicate those + strings as WIN platform entries. If font does not have WIN entry for + this id, we will use Mac or Unicode platform entry while assuming + en-US locale. */ + case OPENTYPE_PLATFORM_UNICODE: + if (candidate_unicode == -1) + candidate_unicode = i; + break; + case OPENTYPE_PLATFORM_MAC: + if (candidate_mac == -1) + candidate_mac = i; + break; + case OPENTYPE_PLATFORM_WIN: + if (opentype_decode_namerecord(header, storage_area, i, *strings)) + exists = TRUE; + break; + default: + FIXME("platform %i not supported\n", platform); + break; } - - if (!opentype_decode_namerecord(header, storage_area, i, *strings)) - continue; - - exists = TRUE; }
- if (!exists) { - if (candidate != -1) - exists = opentype_decode_namerecord(header, storage_area, candidate, *strings); - else { + if (!exists) + { + if (candidate_mac != -1) + exists = opentype_decode_namerecord(header, storage_area, candidate_mac, *strings); + + if (!exists && candidate_unicode != -1) + exists = opentype_decode_namerecord(header, storage_area, candidate_unicode, *strings); + else + { IDWriteLocalizedStrings_Release(*strings); *strings = NULL; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
Some Noto Sans CJK versions otherwise return Chinese (zh-*) names first. In addition to that I manually tested with Arabic langid (0x1401) and it's returned before en-us, so en-us is not special.
dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/main.c | 14 ++++++++++++++ dlls/dwrite/opentype.c | 3 +++ 3 files changed, 18 insertions(+)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 32ccd63c3e..d0fed98d6f 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -237,6 +237,7 @@ extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDE extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN; extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN; extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN; +extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN; extern HRESULT get_system_fontcollection(IDWriteFactory5*,IDWriteFontCollection1**) DECLSPEC_HIDDEN; extern HRESULT get_eudc_fontcollection(IDWriteFactory5*,IDWriteFontCollection1**) DECLSPEC_HIDDEN; extern IDWriteTextAnalyzer *get_text_analyzer(void) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index 3fe2b7eaa7..fc72013feb 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -520,6 +520,20 @@ void set_en_localizedstring(IDWriteLocalizedStrings *iface, const WCHAR *string) } }
+static int localizedstrings_sorting_compare(const void *left, const void *right) +{ + const struct localizedpair *_l = left, *_r = right; + + return strcmpW(_l->locale, _r->locale); +}; + +void sort_localizedstrings(IDWriteLocalizedStrings *iface) +{ + struct localizedstrings *strings = impl_from_IDWriteLocalizedStrings(iface); + + qsort(strings->data, strings->count, sizeof(*strings->data), localizedstrings_sorting_compare); +} + struct collectionloader { struct list entry; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 67a1a20427..1c85ffa30c 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -2010,6 +2010,9 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP } }
+ if (*strings) + sort_localizedstrings(*strings); + return exists ? S_OK : E_FAIL; }
Nikolay Sivov nsivov@codeweavers.com writes:
From: Akihiro Sagawa sagawa.aki@gmail.com
Signed-off-by: Akihiro Sagawa sagawa.aki@gmail.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/dwrite/opentype.c | 57 +++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 26 deletions(-)
It crashes here:
../../../tools/runtest -q -P wine -T ../../.. -M dwrite.dll -p dwrite_test.exe analyzer && touch analyzer.ok wine: Unhandled page fault on read access to 0x00000000 at address 7EB728DD (thread 0009), starting debugger... Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x7eb728dd). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:7eb728dd ESP:0078e8f0 EBP:0078e9e8 EFLAGS:00010206( R- -- I - -P- ) EAX:00000006 EBX:0078eb7c ECX:00000000 EDX:0078e91c ESI:0078ea28 EDI:0078e926 Stack dump: 0x0078e8f0: 00ef58e4 0078ea28 0078e978 00000000 0x0078e900: 008a55f8 00000000 00000000 00000000 0x0078e910: 0208a03c 02015928 00ef58e4 00000000 0x0078e920: 008a55f8 00650000 002d006e 00530055 0x0078e930: 00000000 0078f4fa 0078e978 00000000 0x0078e940: 00000000 00000000 0078e978 00000000 Backtrace: =>0 0x7eb728dd opentype_get_font_facename+0x12d() [Z:\home\julliard\wine\wine\dlls\dwrite....\include\dwrite.h:1450] in dwrite (0x0078e9e8) 1 0x7eb5290e init_font_data+0xdd(desc=<is not available>, family_name=<is not available>, ret=<is not available>) [Z:\home\julliard\wine\wine\dlls\dwrite\font.c:3464] in dwrite (0x0078f6f8) 2 0x7eb5710c create_font_collection+0x3db(enumerator=<is not available>) [Z:\home\julliard\wine\wine\dlls\dwrite\font.c:3862] in dwrite (0x0078fac8) 3 0x7eb57974 get_system_fontcollection+0xb3() [Z:\home\julliard\wine\wine\dlls\dwrite\font.c:4133] in dwrite (0x0078faf8) 4 0x7eb6c5ad factory_get_system_collection+0x3c() in dwrite (0x0078fb28) 5 0x7eb6c650 dwritefactory3_GetSystemFontCollection+0x3f(iface=<couldn't compute location>, include_downloadable=<couldn't compute location>, collection=<couldn't compute location>, check_for_updates=<couldn't compute location>) [Z:\home\julliard\wine\wine\dlls\dwrite\main.c:1511] in dwrite (0x0078fb58) 6 0x7eb5d384 gdiinterop1_CreateFontFromLOGFONT+0x133(iface=<couldn't compute location>, logfont=<couldn't compute location>, collection=<couldn't compute location>, font=<couldn't compute location>) [Z:\home\julliard\wine\wine\dlls\dwrite....\include\dwrite_3.h:10574] in dwrite (0x0078fbb8) 7 0x7eb5cd5e gdiinterop_CreateFontFromLOGFONT+0x4d(iface=<couldn't compute location>, logfont=<couldn't compute location>, font=<couldn't compute location>) [Z:\home\julliard\wine\wine\dlls\dwrite....\include\dwrite_3.h:6889] in dwrite (0x0078fbf8) 8 0x004017ed create_fontface+0xac() [Z:\home\julliard\wine\wine\dlls\dwrite\tests......\include\dwrite.h:3574] in dwrite_test (0x0078fc98) 9 0x00406d23 func_analyzer+0x1422() [Z:\home\julliard\wine\wine\dlls\dwrite\tests\analyzer.c:1312] in dwrite_test (0x0078fdb8) 10 0x0044f0fd main+0x2ac(argc=<is not available>, argv=<is not available>) [Z:\home\julliard\wine\wine\dlls\dwrite\tests......\include\wine\test.h:637] in dwrite_test (0x0078fe88) 11 0x0040138b obj+0x40138a() in dwrite_test (0x0078ff28) 12 0x7b46a482 call_process_entry+0x11() in kernel32 (0x0078ff48) 13 0x7b46c4a5 start_process+0x124(entry=<is not available>, peb=<is not available>) [Z:\home\julliard\wine\wine\dlls\kernel32\process.c:1288] in kernel32 (0x0078ffd8) 14 0x7b46a48e start_process_wrapper+0x9() in kernel32 (0x0078ffec) 0x7eb728dd opentype_get_font_facename+0x12d [Z:\home\julliard\wine\wine\dlls\dwrite....\include\dwrite.h:1450] in dwrite: movl 0x0(%ecx),%eax 1450 return This->lpVtbl->FindLocaleName(This,locale_name,index,exists);