[PATCH 1/2] dwrite: Enable common positional features for all scripts.

Nikolay Sivov nsivov at codeweavers.com
Tue May 5 05:45:54 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/analyzer.c       | 78 +++++++++++++-----------------
 dlls/dwrite/dwrite_private.h |  4 +-
 dlls/dwrite/shape.c          | 92 ++++++++++++++++--------------------
 3 files changed, 74 insertions(+), 100 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 5ee057028f..c2fd5c54d3 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);
-
-        hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
-    }
 
-    return hr;
+    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);
+
+    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);
-
-        hr = shape_get_positions(&context, scriptprops->scripttags, scriptprops->ops->gpos_features);
-    }
 
-    return hr;
+    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);
+
+    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 28ac05a1c1..0b863147af 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 533efe6cc7..a5a1a232e7 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,16 +259,9 @@ HRESULT shape_get_positions(struct scriptshaping_context *context, const DWORD *
         if (context->u.pos.glyph_props[i].isZeroWidthSpace)
             context->advances[i] = 0.0f;
 
-    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;
+    heap_free(features.features);
 
-    features->features[features->count++].tag = tag;
+    return S_OK;
 }
 
 static unsigned int shape_get_script_lang_index(struct scriptshaping_context *context, const unsigned int *scripts,
-- 
2.26.2




More information about the wine-devel mailing list