Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- 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);