Nikolay Sivov : dwrite: Improve face name extraction.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Aug 13 04:23:49 CDT 2015


Module: wine
Branch: master
Commit: 2ac68e91a46ddd3f185804ea0e7010c4a1ceeeaa
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2ac68e91a46ddd3f185804ea0e7010c4a1ceeeaa

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Aug 12 21:10:46 2015 +0300

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 0fbe44f..42395ee 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 c77c7c5..56a0c4d 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, &current);
@@ -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 76b5c68..d0411bd 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;




More information about the wine-cvs mailing list