Nikolay Sivov : dwrite: Prefer different family names for typographical collections.

Alexandre Julliard julliard at winehq.org
Mon Apr 25 16:30:32 CDT 2022


Module: wine
Branch: master
Commit: 7e3edfabc5ae2d6c696e936ecb6956d07bc75da9
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=7e3edfabc5ae2d6c696e936ecb6956d07bc75da9

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Mon Apr 25 13:31:47 2022 +0300

dwrite: Prefer different family names for typographical collections.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/dwrite_private.h |  3 ++-
 dlls/dwrite/font.c           | 21 ++++++++++-------
 dlls/dwrite/opentype.c       | 56 ++++++++++++++++++++++++++++++++------------
 3 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 00fe325518f..35cf5add34b 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -469,7 +469,8 @@ extern void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc,
         unsigned int *descent) DECLSPEC_HIDDEN;
 extern HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_desc,
         DWRITE_INFORMATIONAL_STRING_ID id, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN;
-extern HRESULT opentype_get_font_familyname(struct file_stream_desc*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
+extern HRESULT opentype_get_font_familyname(const struct file_stream_desc *desc, DWRITE_FONT_FAMILY_MODEL family_model,
+        IDWriteLocalizedStrings **names) DECLSPEC_HIDDEN;
 extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
 extern void opentype_get_typographic_features(struct ot_gsubgpos_table *table, unsigned int script_index,
         unsigned int language_index, struct tag_array *tags) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index bdd8c7fcc8b..e32b2d0f4cb 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -4279,7 +4279,8 @@ static BOOL font_apply_differentiation_rules(struct dwrite_font_data *font, WCHA
     return TRUE;
 }
 
-static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_font_data **ret)
+static HRESULT init_font_data(const struct fontface_desc *desc, DWRITE_FONT_FAMILY_MODEL family_model,
+        struct dwrite_font_data **ret)
 {
     static const float width_axis_values[] =
     {
@@ -4319,10 +4320,9 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo
     opentype_get_font_metrics(&stream_desc, &data->metrics, NULL);
     opentype_get_font_facename(&stream_desc, props.lf.lfFaceName, &data->names);
 
-    /* get family name from font file */
-    hr = opentype_get_font_familyname(&stream_desc, &data->family_names);
-    if (FAILED(hr)) {
-        WARN("unable to get family name from font\n");
+    if (FAILED(hr = opentype_get_font_familyname(&stream_desc, family_model, &data->family_names)))
+    {
+        WARN("Unable to get family name from the font file, hr %#lx.\n", hr);
         release_font_data(data);
         return hr;
     }
@@ -4337,7 +4337,10 @@ static HRESULT init_font_data(const struct fontface_desc *desc, struct dwrite_fo
 
     fontstrings_get_en_string(data->family_names, familyW, ARRAY_SIZE(familyW));
     fontstrings_get_en_string(data->names, faceW, ARRAY_SIZE(faceW));
-    if (font_apply_differentiation_rules(data, familyW, faceW)) {
+
+    if (family_model == DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE
+            && font_apply_differentiation_rules(data, familyW, faceW))
+    {
         set_en_localizedstring(data->family_names, familyW);
         set_en_localizedstring(data->names, faceW);
     }
@@ -4722,7 +4725,7 @@ HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerat
             desc.font_data = NULL;
 
             /* Allocate an initialize new font data structure. */
-            hr = init_font_data(&desc, &font_data);
+            hr = init_font_data(&desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data);
             if (FAILED(hr))
             {
                 /* move to next one */
@@ -5060,7 +5063,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory7 *factory, struct dwrit
         desc.simulations = DWRITE_FONT_SIMULATIONS_NONE;
         desc.font_data = NULL;
 
-        hr = init_font_data(&desc, &font_data);
+        hr = init_font_data(&desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data);
         if (FAILED(hr))
             continue;
 
@@ -5388,7 +5391,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
     }
     else
     {
-        hr = init_font_data(desc, &font_data);
+        hr = init_font_data(desc, DWRITE_FONT_FAMILY_MODEL_WEIGHT_STRETCH_STYLE, &font_data);
         if (FAILED(hr))
         {
             IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface);
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index c671218c486..c4b2177639b 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -2565,12 +2565,26 @@ HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_des
     return S_OK;
 }
 
-/* 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(struct file_stream_desc *stream_desc, IDWriteLocalizedStrings **names)
+HRESULT opentype_get_font_familyname(const struct file_stream_desc *stream_desc, DWRITE_FONT_FAMILY_MODEL family_model,
+        IDWriteLocalizedStrings **names)
 {
+    static const unsigned int wws_candidates[] =
+    {
+        OPENTYPE_STRING_WWS_FAMILY_NAME,
+        OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME,
+        OPENTYPE_STRING_FAMILY_NAME,
+        ~0u,
+    };
+    static const unsigned int typographic_candidates[] =
+    {
+        OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME,
+        OPENTYPE_STRING_WWS_FAMILY_NAME,
+        OPENTYPE_STRING_FAMILY_NAME,
+        ~0u,
+    };
     struct dwrite_fonttable os2, name;
-    UINT16 fsselection;
+    const unsigned int *id;
+    BOOL try_wws_name;
     HRESULT hr;
 
     opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2);
@@ -2578,20 +2592,32 @@ HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWri
 
     *names = NULL;
 
-    /* If Preferred Family doesn't conform to WWS model try WWS name. */
-    fsselection = os2.data ? table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) : 0;
-    if (os2.data && !(fsselection & OS2_FSSELECTION_WWS))
-        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_WWS_FAMILY_NAME, names);
+    if (family_model == DWRITE_FONT_FAMILY_MODEL_TYPOGRAPHIC)
+    {
+        id = typographic_candidates;
+    }
     else
-        hr = E_FAIL;
+    {
+        /* 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. */
 
-    if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, names);
-    if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_FAMILY_NAME, names);
+        opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2);
+        /* If Preferred Family doesn't conform to WWS model try WWS name. */
+        try_wws_name = os2.data && !(table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) & OS2_FSSELECTION_WWS);
+        if (os2.context)
+            IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context);
+
+        id = wws_candidates;
+        if (!try_wws_name) id++;
+    }
+
+    while (*id != ~0u)
+    {
+        if (SUCCEEDED(hr = opentype_get_font_strings_from_id(&name, *id, names)))
+            break;
+        id++;
+    }
 
-    if (os2.context)
-        IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context);
     if (name.context)
         IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context);
 




More information about the wine-cvs mailing list