dwrite: Prefer different family names for typographical collections.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2022-04-25 13:31:47 +03:00 committed by Alexandre Julliard
parent b3cf1df4f4
commit 7e3edfabc5
3 changed files with 55 additions and 25 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);