[PATCH 7/9] dwrite: Prefer different family names for typographical collections.
Nikolay Sivov
nsivov at codeweavers.com
Mon Apr 25 05:31:47 CDT 2022
Signed-off-by: Nikolay Sivov <nsivov at 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);
--
2.35.1
More information about the wine-devel
mailing list