dwrite: Enable common positional features for all scripts.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-05-05 13:45:54 +03:00 committed by Alexandre Julliard
parent dd41471f07
commit 33ec962e27
3 changed files with 72 additions and 98 deletions

View File

@ -94,7 +94,7 @@ static const struct dwritescript_properties dwritescripts_properties[Script_Last
{ /* Khar */ { 0x7261684b, 305, 15, 0x0020, 1, 0, 1, 0, 0, 0, 0 }, { _OT('k','h','a','r') } },
{ /* Khmr */ { 0x726d684b, 355, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('k','h','m','r') }, TRUE },
{ /* Laoo */ { 0x6f6f614c, 356, 8, 0x0020, 1, 0, 1, 0, 1, 0, 0 }, { _OT('l','a','o',' ') }, TRUE },
{ /* Latn */ { 0x6e74614c, 215, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','a','t','n') }, FALSE, &latn_shaping_ops },
{ /* Latn */ { 0x6e74614c, 215, 1, 0x0020, 0, 1, 1, 0, 0, 0, 0 }, { _OT('l','a','t','n') } },
{ /* Lepc */ { 0x6370654c, 335, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('l','e','p','c') } },
{ /* Limb */ { 0x626d694c, 336, 8, 0x0020, 1, 1, 1, 0, 0, 0, 0 }, { _OT('l','i','m','b') } },
{ /* Linb */ { 0x626e694c, 401, 1, 0x0020, 0, 0, 1, 1, 0, 0, 0 }, { _OT('l','i','n','b') } },
@ -1279,9 +1279,9 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2
UINT32 const* feature_range_lengths, UINT32 feature_ranges, float *advances, DWRITE_GLYPH_OFFSET *offsets)
{
const struct dwritescript_properties *scriptprops;
struct scriptshaping_context context;
struct dwrite_fontface *font_obj;
unsigned int i, script;
HRESULT hr = S_OK;
TRACE("(%s %p %p %u %p %p %u %p %.2f %d %d %s %s %p %p %u %p %p)\n", debugstr_wn(text, text_len),
clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, is_sideways,
@ -1307,29 +1307,23 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2
}
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
scriptprops = &dwritescripts_properties[script];
if (scriptprops->ops && scriptprops->ops->gpos_features)
{
struct scriptshaping_context context;
context.cache = fontface_get_shaping_cache(font_obj);
context.text = text;
context.length = text_len;
context.is_rtl = is_rtl;
context.u.pos.glyphs = glyphs;
context.u.pos.glyph_props = glyph_props;
context.glyph_count = glyph_count;
context.emsize = emSize;
context.measuring_mode = DWRITE_MEASURING_MODE_NATURAL;
context.advances = advances;
context.offsets = offsets;
context.language_tag = get_opentype_language(locale);
context.cache = fontface_get_shaping_cache(font_obj);
context.text = text;
context.length = text_len;
context.is_rtl = is_rtl;
context.is_sideways = is_sideways;
context.u.pos.glyphs = glyphs;
context.u.pos.glyph_props = glyph_props;
context.glyph_count = glyph_count;
context.emsize = emSize;
context.measuring_mode = DWRITE_MEASURING_MODE_NATURAL;
context.advances = advances;
context.offsets = offsets;
context.language_tag = get_opentype_language(locale);
hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
}
return hr;
return shape_get_positions(&context, scriptprops->scripttags);
}
static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWriteTextAnalyzer2 *iface,
@ -1341,10 +1335,10 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
UINT32 const* feature_range_lengths, UINT32 feature_ranges, float *advances, DWRITE_GLYPH_OFFSET *offsets)
{
const struct dwritescript_properties *scriptprops;
struct scriptshaping_context context;
DWRITE_MEASURING_MODE measuring_mode;
struct dwrite_fontface *font_obj;
unsigned int i, script;
HRESULT hr = S_OK;
TRACE("(%s %p %p %u %p %p %u %p %.2f %.2f %p %d %d %d %s %s %p %p %u %p %p)\n", debugstr_wn(text, text_len),
clustermap, props, text_len, glyphs, glyph_props, glyph_count, fontface, emSize, ppdip,
@ -1372,29 +1366,23 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
}
script = analysis->script > Script_LastId ? Script_Unknown : analysis->script;
scriptprops = &dwritescripts_properties[script];
if (scriptprops->ops && scriptprops->ops->gpos_features)
{
struct scriptshaping_context context;
context.cache = fontface_get_shaping_cache(font_obj);
context.text = text;
context.length = text_len;
context.is_rtl = is_rtl;
context.u.pos.glyphs = glyphs;
context.u.pos.glyph_props = glyph_props;
context.glyph_count = glyph_count;
context.emsize = emSize * ppdip;
context.measuring_mode = measuring_mode;
context.advances = advances;
context.offsets = offsets;
context.language_tag = get_opentype_language(locale);
context.cache = fontface_get_shaping_cache(font_obj);
context.text = text;
context.length = text_len;
context.is_rtl = is_rtl;
context.is_sideways = is_sideways;
context.u.pos.glyphs = glyphs;
context.u.pos.glyph_props = glyph_props;
context.glyph_count = glyph_count;
context.emsize = emSize * ppdip;
context.measuring_mode = measuring_mode;
context.advances = advances;
context.offsets = offsets;
context.language_tag = get_opentype_language(locale);
hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
}
return hr;
return shape_get_positions(&context, scriptprops->scripttags);
}
static HRESULT apply_cluster_spacing(float leading_spacing, float trailing_spacing, float min_advance_width,

View File

@ -536,8 +536,6 @@ struct scriptshaping_ops
};
extern const struct scriptshaping_ops default_shaping_ops DECLSPEC_HIDDEN;
extern const struct scriptshaping_ops latn_shaping_ops DECLSPEC_HIDDEN;
extern HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned int *scripts) DECLSPEC_HIDDEN;
extern HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *scripts,
const struct shaping_features *features) DECLSPEC_HIDDEN;
extern HRESULT shape_get_positions(struct scriptshaping_context *context, const unsigned int *scripts) DECLSPEC_HIDDEN;

View File

@ -148,41 +148,6 @@ static HRESULT default_set_text_glyphs_props(struct scriptshaping_context *conte
return S_OK;
}
static HRESULT latn_set_text_glyphs_props(struct scriptshaping_context *context, UINT16 *clustermap, UINT16 *glyph_indices,
UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props)
{
HRESULT hr;
UINT32 i;
hr = default_set_text_glyphs_props(context, clustermap, glyph_indices, glyphcount, text_props, glyph_props);
for (i = 0; i < glyphcount; i++)
if (glyph_props[i].isZeroWidthSpace)
glyph_props[i].justification = SCRIPT_JUSTIFY_NONE;
return hr;
}
static struct shaping_feature std_gpos_tags[] =
{
{ DWRITE_FONT_FEATURE_TAG_KERNING },
{ DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING },
{ DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING },
};
static const struct shaping_features std_gpos_features =
{
std_gpos_tags,
ARRAY_SIZE(std_gpos_tags),
};
const struct scriptshaping_ops latn_shaping_ops =
{
NULL,
latn_set_text_glyphs_props,
&std_gpos_features,
};
const struct scriptshaping_ops default_shaping_ops =
{
NULL,
@ -236,13 +201,43 @@ static DWORD shape_select_language(const struct scriptshaping_cache *cache, DWOR
return 0;
}
HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *scripts,
const struct shaping_features *features)
static void shape_add_feature(struct shaping_features *features, unsigned int tag)
{
if (!dwrite_array_reserve((void **)&features->features, &features->capacity, features->count + 1,
sizeof(*features->features)))
return;
features->features[features->count++].tag = tag;
}
HRESULT shape_get_positions(struct scriptshaping_context *context, const unsigned int *scripts)
{
static const unsigned int common_features[] =
{
DWRITE_MAKE_OPENTYPE_TAG('a','b','v','m'),
DWRITE_MAKE_OPENTYPE_TAG('b','l','w','m'),
DWRITE_MAKE_OPENTYPE_TAG('m','a','r','k'),
DWRITE_MAKE_OPENTYPE_TAG('m','k','m','k'),
};
static const unsigned int horizontal_features[] =
{
DWRITE_MAKE_OPENTYPE_TAG('c','u','r','s'),
DWRITE_MAKE_OPENTYPE_TAG('d','i','s','t'),
DWRITE_MAKE_OPENTYPE_TAG('k','e','r','n'),
};
struct scriptshaping_cache *cache = context->cache;
unsigned int script_index, language_index;
unsigned int i;
DWORD script;
unsigned int script_index, language_index, script, i;
struct shaping_features features = { 0 };
for (i = 0; i < ARRAY_SIZE(common_features); ++i)
shape_add_feature(&features, common_features[i]);
/* Horizontal features */
if (!context->is_sideways)
{
for (i = 0; i < ARRAY_SIZE(horizontal_features); ++i)
shape_add_feature(&features, horizontal_features[i]);
}
/* Resolve script tag to actually supported script. */
if (cache->gpos.table.data)
@ -253,9 +248,9 @@ HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *
if ((language = shape_select_language(cache, MS_GPOS_TAG, script_index, language, &language_index)))
{
TRACE("script %s, language %s.\n", debugstr_tag(script),
language != ~0u ? debugstr_tag(language) : "deflangsys");
opentype_layout_apply_gpos_features(context, script_index, language_index, features);
TRACE("script %s, language %s.\n", debugstr_tag(script), language != ~0u ?
debugstr_tag(language) : "deflangsys");
opentype_layout_apply_gpos_features(context, script_index, language_index, &features);
}
}
}
@ -264,18 +259,11 @@ HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *
if (context->u.pos.glyph_props[i].isZeroWidthSpace)
context->advances[i] = 0.0f;
heap_free(features.features);
return S_OK;
}
static void shape_add_feature(struct shaping_features *features, unsigned int tag)
{
if (!dwrite_array_reserve((void **)&features->features, &features->capacity, features->count + 1,
sizeof(*features->features)))
return;
features->features[features->count++].tag = tag;
}
static unsigned int shape_get_script_lang_index(struct scriptshaping_context *context, const unsigned int *scripts,
unsigned int table, unsigned int *script_index, unsigned int *language_index)
{