dwrite: Accept platform 0 name records if there's nothing, else.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-02-08 12:31:07 +03:00 committed by Alexandre Julliard
parent b274ce44b0
commit ec3c7d9d3a

View File

@ -1281,20 +1281,69 @@ static void get_name_record_locale(enum OPENTYPE_PLATFORM_ID platform, USHORT la
strcpyW(locale, enusW); strcpyW(locale, enusW);
} }
break; break;
case OPENTYPE_PLATFORM_UNICODE:
strcpyW(locale, enusW);
break;
default: default:
FIXME("unknown platform %d\n", platform); FIXME("unknown platform %d\n", platform);
} }
} }
static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_area, USHORT recid, IDWriteLocalizedStrings *strings)
{
const TT_NameRecord *record = &header->nameRecord[recid];
USHORT lang_id, length, offset, encoding, platform;
BOOL ret = FALSE;
platform = GET_BE_WORD(record->platformID);
lang_id = GET_BE_WORD(record->languageID);
length = GET_BE_WORD(record->length);
offset = GET_BE_WORD(record->offset);
encoding = GET_BE_WORD(record->encodingID);
if (lang_id < 0x8000) {
WCHAR locale[LOCALE_NAME_MAX_LENGTH];
WCHAR *name_string;
UINT codepage;
codepage = get_name_record_codepage(platform, encoding);
get_name_record_locale(platform, lang_id, locale, sizeof(locale)/sizeof(WCHAR));
if (codepage) {
DWORD len = MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, NULL, 0);
name_string = heap_alloc(sizeof(WCHAR) * (len+1));
MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, name_string, len);
name_string[len] = 0;
}
else {
int i;
length /= sizeof(WCHAR);
name_string = heap_strdupnW((LPWSTR)(storage_area + offset), length);
for (i = 0; i < length; i++)
name_string[i] = GET_BE_WORD(name_string[i]);
}
TRACE("string %s for locale %s found\n", debugstr_w(name_string), debugstr_w(locale));
add_localizedstring(strings, locale, name_string);
heap_free(name_string);
ret = TRUE;
}
else
FIXME("handle NAME format 1\n");
return ret;
}
static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings) static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings)
{ {
const TT_NAME_V0 *header; const TT_NAME_V0 *header;
BYTE *storage_area = 0; BYTE *storage_area = 0;
USHORT count = 0; USHORT count = 0;
int i, candidate;
WORD format; WORD format;
BOOL exists; BOOL exists;
HRESULT hr; HRESULT hr;
int i;
if (!table_data) if (!table_data)
return E_FAIL; return E_FAIL;
@ -1313,20 +1362,18 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP
FIXME("unsupported NAME format %d\n", format); FIXME("unsupported NAME format %d\n", format);
} }
storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset); storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset);
count = GET_BE_WORD(header->count); count = GET_BE_WORD(header->count);
exists = FALSE; exists = FALSE;
candidate = -1;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
const TT_NameRecord *record = &header->nameRecord[i]; const TT_NameRecord *record = &header->nameRecord[i];
USHORT lang_id, length, offset, encoding, platform; USHORT platform;
if (GET_BE_WORD(record->nameID) != id) if (GET_BE_WORD(record->nameID) != id)
continue; continue;
exists = TRUE;
/* Right now only accept unicode and windows encoded fonts */ /* Right now only accept unicode and windows encoded fonts */
platform = GET_BE_WORD(record->platformID); platform = GET_BE_WORD(record->platformID);
if (platform != OPENTYPE_PLATFORM_UNICODE && if (platform != OPENTYPE_PLATFORM_UNICODE &&
@ -1337,53 +1384,25 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP
continue; continue;
} }
/* Skip such entries for now, as it's not clear which locale is implied when /* Skip such entries for now, fonts tend to duplicate those strings as
unicode platform is used. Also fonts tend to duplicate those strings as WIN platform entries. If font does not have WIN or MAC entry for this id, we will
WIN platform entries. */ use this Unicode platform entry while assuming en-US locale. */
if (platform == OPENTYPE_PLATFORM_UNICODE) if (platform == OPENTYPE_PLATFORM_UNICODE) {
continue; candidate = i;
lang_id = GET_BE_WORD(record->languageID);
length = GET_BE_WORD(record->length);
offset = GET_BE_WORD(record->offset);
encoding = GET_BE_WORD(record->encodingID);
if (lang_id < 0x8000) {
WCHAR locale[LOCALE_NAME_MAX_LENGTH];
WCHAR *name_string;
UINT codepage;
codepage = get_name_record_codepage(platform, encoding);
get_name_record_locale(platform, lang_id, locale, sizeof(locale)/sizeof(WCHAR));
if (codepage) {
DWORD len = MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, NULL, 0);
name_string = heap_alloc(sizeof(WCHAR) * (len+1));
MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, name_string, len);
name_string[len] = 0;
}
else {
int i;
length /= sizeof(WCHAR);
name_string = heap_strdupnW((LPWSTR)(storage_area + offset), length);
for (i = 0; i < length; i++)
name_string[i] = GET_BE_WORD(name_string[i]);
}
TRACE("string %s for locale %s found\n", debugstr_w(name_string), debugstr_w(locale));
add_localizedstring(*strings, locale, name_string);
heap_free(name_string);
}
else {
FIXME("handle NAME format 1\n");
continue; continue;
} }
if (!(exists = opentype_decode_namerecord(header, storage_area, i, *strings)))
continue;
} }
if (!exists) { if (!exists) {
IDWriteLocalizedStrings_Release(*strings); if (candidate != -1)
*strings = NULL; exists = opentype_decode_namerecord(header, storage_area, candidate, *strings);
else {
IDWriteLocalizedStrings_Release(*strings);
*strings = NULL;
}
} }
return exists ? S_OK : E_FAIL; return exists ? S_OK : E_FAIL;