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:
parent
b274ce44b0
commit
ec3c7d9d3a
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user