From 2ac68e91a46ddd3f185804ea0e7010c4a1ceeeaa Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 12 Aug 2015 21:10:46 +0300 Subject: [PATCH] dwrite: Improve face name extraction. --- dlls/dwrite/dwrite_private.h | 3 +- dlls/dwrite/font.c | 19 ++++++------- dlls/dwrite/opentype.c | 53 +++++++++++++++++++++++++++++++----- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 0fbe44f1e90..42395ee0f0c 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -153,7 +153,8 @@ extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANG extern void opentype_get_font_properties(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,struct dwrite_font_props*) DECLSPEC_HIDDEN; extern void opentype_get_font_metrics(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_info_strings(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; -extern HRESULT opentype_get_font_familyname(IDWriteFontFileStream*,UINT32,DWRITE_FONT_FACE_TYPE,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; +extern HRESULT opentype_get_font_familyname(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; +extern HRESULT opentype_get_font_facename(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN; extern BOOL opentype_get_vdmx_size(const void*,INT,UINT16*,UINT16*) DECLSPEC_HIDDEN; extern UINT32 opentype_get_cpal_palettecount(const void*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index c77c7c5264d..56a0c4d6734 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -59,6 +59,7 @@ struct dwrite_font_data { DWRITE_FONT_METRICS1 metrics; IDWriteLocalizedStrings *info_strings[DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME+1]; + IDWriteLocalizedStrings *names; /* data needed to create fontface instance */ IDWriteFactory2 *factory; @@ -315,6 +316,7 @@ static void release_font_data(struct dwrite_font_data *data) if (data->info_strings[i]) IDWriteLocalizedStrings_Release(data->info_strings[i]); } + IDWriteLocalizedStrings_Release(data->names); IDWriteFontFile_Release(data->file); IDWriteFactory2_Release(data->factory); @@ -1233,11 +1235,8 @@ static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont2 *iface, IDWriteLocali *names = NULL; - if (This->simulations == DWRITE_FONT_SIMULATIONS_NONE) { - BOOL exists; - return IDWriteFont2_GetInformationalStrings(iface, DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES, - names, &exists); - } + if (This->simulations == DWRITE_FONT_SIMULATIONS_NONE) + return clone_localizedstring(This->data->names, names); switch (This->simulations) { case DWRITE_FONT_SIMULATIONS_BOLD|DWRITE_FONT_SIMULATIONS_OBLIQUE: @@ -1940,7 +1939,7 @@ HRESULT get_filestream_from_file(IDWriteFontFile *file, IDWriteFontFileStream ** return hr; } -static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, UINT32 face_index, DWRITE_FONT_FACE_TYPE face_type, +static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, DWRITE_FONT_FACE_TYPE face_type, UINT32 face_index, IDWriteFontFileStream **stream, struct dwrite_font_data **ret) { void *os2_context, *head_context; @@ -1972,6 +1971,7 @@ static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, U opentype_get_font_properties(*stream, face_type, face_index, &props); opentype_get_font_metrics(*stream, face_type, face_index, &data->metrics, NULL); + opentype_get_font_facename(*stream, face_type, face_index, &data->names); data->style = props.style; data->stretch = props.stretch; @@ -2038,9 +2038,8 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat DWRITE_FONT_FACE_TYPE face_type; DWRITE_FONT_FILE_TYPE file_type; IDWriteFontFile *file; - UINT32 face_count; + UINT32 face_count, i; BOOL supported; - int i; current = FALSE; hr = IDWriteFontFileEnumerator_MoveNext(enumerator, ¤t); @@ -2068,12 +2067,12 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat UINT32 index; /* alloc and init new font data structure */ - hr = init_font_data(factory, file, i, face_type, &stream, &font_data); + hr = init_font_data(factory, file, face_type, i, &stream, &font_data); if (FAILED(hr)) break; /* get family name from font file */ - hr = opentype_get_font_familyname(stream, i, face_type, &family_name); + hr = opentype_get_font_familyname(stream, face_type, i, &family_name); IDWriteFontFileStream_Release(stream); if (FAILED(hr)) { WARN("unable to get family name from font\n"); diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 76b5c68fd6c..d0411bdd88f 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -780,11 +780,12 @@ HRESULT opentype_get_font_table(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_ void * ttc_context; hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&ttc_header, 0, sizeof(*ttc_header), &ttc_context); if (SUCCEEDED(hr)) { - table_offset = GET_BE_DWORD(ttc_header->OffsetTable[0]); if (font_index >= GET_BE_DWORD(ttc_header->numFonts)) hr = E_INVALIDARG; - else + else { + table_offset = GET_BE_DWORD(ttc_header->OffsetTable[font_index]); hr = IDWriteFontFileStream_ReadFileFragment(stream, (const void**)&font_header, table_offset, sizeof(*font_header), &sfnt_context); + } IDWriteFontFileStream_ReleaseFileFragment(stream, ttc_context); } } @@ -1200,6 +1201,7 @@ HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_ const TT_NAME_V0 *header; BYTE *storage_area = 0; USHORT count = 0; + WORD format; BOOL exists; HRESULT hr; int i; @@ -1211,14 +1213,17 @@ HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_ if (FAILED(hr)) return hr; header = table_data; + format = GET_BE_WORD(header->format); - switch (header->format) { + switch (format) { case 0: + case 1: break; default: - FIXME("unsupported NAME format %d\n", header->format); + FIXME("unsupported NAME format %d\n", format); } + storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset); count = GET_BE_WORD(header->count); @@ -1300,9 +1305,9 @@ HRESULT opentype_get_font_info_strings(const void *table_data, DWRITE_INFORMATIO return opentype_get_font_strings_from_id(table_data, dwriteid_to_opentypeid[id], strings); } -/* Name locating order is WWS Family Name -> Preferred Name -> Family Name. If font claims to - have 'Preferred Name' in WWS format, then WWS name is not used. */ -HRESULT opentype_get_font_familyname(IDWriteFontFileStream *stream, UINT32 index, DWRITE_FONT_FACE_TYPE facetype, +/* FamilyName locating order is WWS Family Name -> Preferred Family Name -> Family Name. If font claims to + have 'Preferred Family Name' in WWS format, then WWS name is not used. */ +HRESULT opentype_get_font_familyname(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE facetype, UINT32 index, IDWriteLocalizedStrings **names) { const TT_OS2_V2 *tt_os2; @@ -1334,6 +1339,40 @@ HRESULT opentype_get_font_familyname(IDWriteFontFileStream *stream, UINT32 index return hr; } +/* FaceName locating order is WWS Face Name -> Preferred Face Name -> Face Name. If font claims to + have 'Preferred Face Name' in WWS format, then WWS name is not used. */ +HRESULT opentype_get_font_facename(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE facetype, UINT32 index, + IDWriteLocalizedStrings **names) +{ + const TT_OS2_V2 *tt_os2; + void *os2_context, *name_context; + const void *name_table; + HRESULT hr; + + opentype_get_font_table(stream, facetype, index, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL); + opentype_get_font_table(stream, facetype, index, MS_NAME_TAG, &name_table, &name_context, NULL, NULL); + + *names = NULL; + + /* if Preferred Family doesn't conform to WWS model try WWS name */ + if (tt_os2 && !(GET_BE_WORD(tt_os2->fsSelection) & OS2_FSSELECTION_WWS)) + hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_WWS_SUBFAMILY_NAME, names); + else + hr = E_FAIL; + + if (FAILED(hr)) + hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_PREFERRED_SUBFAMILY_NAME, names); + if (FAILED(hr)) + hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_SUBFAMILY_NAME, names); + + if (tt_os2) + IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context); + if (name_context) + IDWriteFontFileStream_ReleaseFileFragment(stream, name_context); + + return hr; +} + static inline const OT_Script *opentype_get_script(const OT_ScriptList *scriptlist, UINT32 scripttag) { UINT16 j;