From 33ec962e271d2d7a88a1ec66940d52b708ec040c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 5 May 2020 13:45:54 +0300 Subject: [PATCH] dwrite: Enable common positional features for all scripts. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/analyzer.c | 74 ++++++++++++----------------- dlls/dwrite/dwrite_private.h | 4 +- dlls/dwrite/shape.c | 92 ++++++++++++++++-------------------- 3 files changed, 72 insertions(+), 98 deletions(-) diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c index 5ee057028fc..c2fd5c54d3e 100644 --- a/dlls/dwrite/analyzer.c +++ b/dlls/dwrite/analyzer.c @@ -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, diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 28ac05a1c1f..0b863147af3 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -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; diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c index 533efe6cc7b..a5a1a232e76 100644 --- a/dlls/dwrite/shape.c +++ b/dlls/dwrite/shape.c @@ -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) {