[PATCH 1/3] dwrite: Fix family name extraction order

Nikolay Sivov nsivov at codeweavers.com
Wed Aug 12 13:09:58 CDT 2015


---

-------------- next part --------------
From c26fbc05e1dd761c45ca2547d155f6ea66a22b55 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun, 9 Aug 2015 16:06:43 +0300
Subject: [PATCH 1/3] dwrite: Fix family name extraction order

---
 dlls/dwrite/dwrite_private.h |  3 ++-
 dlls/dwrite/font.c           | 22 ++------------------
 dlls/dwrite/gdiinterop.c     |  2 +-
 dlls/dwrite/opentype.c       | 48 +++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 1b7bd3a..0fbe44f 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -152,7 +152,8 @@ extern HRESULT opentype_get_font_table(IDWriteFontFileStream*,DWRITE_FONT_FACE_T
 extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANGE*,UINT32*) DECLSPEC_HIDDEN;
 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_strings_from_id(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) 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_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 eda6378..c77c7c5 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -1108,24 +1108,6 @@ static const IDWriteFontFace2Vtbl dwritefontfacevtbl = {
     dwritefontface2_GetRecommendedRenderingMode
 };
 
-HRESULT get_family_names_from_stream(IDWriteFontFileStream *stream, UINT32 index, DWRITE_FONT_FACE_TYPE facetype,
-    IDWriteLocalizedStrings **names)
-{
-    const void *name_table = NULL;
-    void *name_context;
-    HRESULT hr = E_FAIL;
-
-    opentype_get_font_table(stream, facetype, index, MS_NAME_TAG, &name_table, &name_context, NULL, NULL);
-    if (name_table) {
-        hr = opentype_get_font_strings_from_id(name_table, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, names);
-        IDWriteFontFileStream_ReleaseFileFragment(stream, name_context);
-    }
-    else
-        *names = NULL;
-
-    return hr;
-}
-
 static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace2 **fontface)
 {
     struct dwrite_font_data *data = font->data;
@@ -1318,7 +1300,7 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont2 *iface,
             WARN("no NAME table found.\n");
 
         if (table_exists) {
-            hr = opentype_get_font_strings_from_id(table_data, stringid, &data->info_strings[stringid]);
+            hr = opentype_get_font_info_strings(table_data, stringid, &data->info_strings[stringid]);
             if (FAILED(hr) || !data->info_strings[stringid])
                 return hr;
             IDWriteFontFace2_ReleaseFontTable(fontface, context);
@@ -2091,7 +2073,7 @@ HRESULT create_font_collection(IDWriteFactory2* factory, IDWriteFontFileEnumerat
                 break;
 
             /* get family name from font file */
-            hr = get_family_names_from_stream(stream, i, face_type, &family_name);
+            hr = opentype_get_font_familyname(stream, i, face_type, &family_name);
             IDWriteFontFileStream_Release(stream);
             if (FAILED(hr)) {
                 WARN("unable to get family name from font\n");
diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c
index 21c1105..e84682e 100644
--- a/dlls/dwrite/gdiinterop.c
+++ b/dlls/dwrite/gdiinterop.c
@@ -716,7 +716,7 @@ static HRESULT WINAPI gdiinterop_ConvertFontFaceToLOGFONT(IDWriteGdiInterop *ifa
     index = IDWriteFontFace_GetIndex(fontface);
     face_type = IDWriteFontFace_GetType(fontface);
     opentype_get_font_properties(stream, face_type, index, &props);
-    hr = get_family_names_from_stream(stream, index, face_type, &familynames);
+    hr = opentype_get_font_familyname(stream, index, face_type, &familynames);
     IDWriteFontFile_Release(file);
     IDWriteFontFileStream_Release(stream);
     if (FAILED(hr))
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index c6d4ec3..76b5c68 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -33,6 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
 #define MS_TTCF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','t','c','f')
 #define MS_GPOS_TAG DWRITE_MAKE_OPENTYPE_TAG('G','P','O','S')
 #define MS_GSUB_TAG DWRITE_MAKE_OPENTYPE_TAG('G','S','U','B')
+#define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
 
 #ifdef WORDS_BIGENDIAN
 #define GET_BE_WORD(x) (x)
@@ -1194,12 +1195,11 @@ static void get_name_record_locale(enum OPENTYPE_PLATFORM_ID platform, USHORT la
     }
 }
 
-HRESULT opentype_get_font_strings_from_id(const void *table_data, DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings)
+HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings)
 {
     const TT_NAME_V0 *header;
     BYTE *storage_area = 0;
     USHORT count = 0;
-    UINT16 name_id;
     BOOL exists;
     HRESULT hr;
     int i;
@@ -1222,14 +1222,12 @@ HRESULT opentype_get_font_strings_from_id(const void *table_data, DWRITE_INFORMA
     storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset);
     count = GET_BE_WORD(header->count);
 
-    name_id = dwriteid_to_opentypeid[id];
-
     exists = FALSE;
     for (i = 0; i < count; i++) {
         const TT_NameRecord *record = &header->nameRecord[i];
         USHORT lang_id, length, offset, encoding, platform;
 
-        if (GET_BE_WORD(record->nameID) != name_id)
+        if (GET_BE_WORD(record->nameID) != id)
             continue;
 
         exists = TRUE;
@@ -1293,6 +1291,46 @@ HRESULT opentype_get_font_strings_from_id(const void *table_data, DWRITE_INFORMA
         *strings = NULL;
     }
 
+    return exists ? S_OK : E_FAIL;
+}
+
+/* Provides a conversion from DWRITE to OpenType name ids, input id be valid, it's not checked. */
+HRESULT opentype_get_font_info_strings(const void *table_data, DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings)
+{
+    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,
+    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_FAMILY_NAME, names);
+    else
+        hr = E_FAIL;
+
+    if (FAILED(hr))
+        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_PREFERRED_FAMILY_NAME, names);
+    if (FAILED(hr))
+        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_FAMILY_NAME, names);
+
+    if (tt_os2)
+        IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
+    if (name_context)
+        IDWriteFontFileStream_ReleaseFileFragment(stream, name_context);
+
     return hr;
 }
 
-- 
2.1.4



More information about the wine-patches mailing list