[PATCH 1/5] dwrite: Update clustermap once after all features have been applied.

Nikolay Sivov nsivov at codeweavers.com
Thu Jun 11 07:08:56 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  4 +++
 dlls/dwrite/opentype.c       | 59 ++++++++++++++++--------------------
 2 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 38863b85bd6..7c8a5c9d896 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -513,8 +513,12 @@ struct scriptshaping_cache
 
 struct shaping_glyph_info
 {
+    /* Combined features mask. */
     unsigned int mask;
+    /* Derived from glyph class, supplied by GDEF. */
     unsigned int props;
+    /* Only relevant for isClusterStart glyphs. Indicates text position for this cluster. */
+    unsigned int start_text_idx;
 };
 
 struct shaping_glyph_properties
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 72cc6f4c93c..e58ff34cb34 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -4949,30 +4949,6 @@ static BOOL opentype_layout_gsub_ensure_buffer(struct scriptshaping_context *con
     return ret;
 }
 
-static unsigned int opentype_layout_get_next_char_index(const struct scriptshaping_context *context, unsigned int idx)
-{
-    unsigned int start = 0, end = context->length - 1, mid, ret = ~0u;
-
-    for (;;)
-    {
-        mid = (start + end) / 2;
-
-        if (context->u.buffer.clustermap[mid] <= idx)
-        {
-            if (mid == end) break;
-            start = mid + 1;
-        }
-        else
-        {
-            ret = mid;
-            if (mid == start) break;
-            end = mid - 1;
-        }
-    }
-
-    return ret;
-}
-
 static BOOL opentype_layout_apply_gsub_mult_substitution(struct scriptshaping_context *context, const struct lookup *lookup,
         unsigned int subtable_offset)
 {
@@ -5053,20 +5029,13 @@ static BOOL opentype_layout_apply_gsub_mult_substitution(struct scriptshaping_co
                 {
                     context->u.subst.glyph_props[idx + i].isClusterStart = 0;
                     context->u.buffer.glyph_props[idx + i].components = 0;
+                    context->glyph_infos[idx + i].start_text_idx = 0;
                 }
                 opentype_set_subst_glyph_props(context, idx + i);
                 /* Inherit feature mask from original matched glyph. */
                 context->glyph_infos[idx + i].mask = mask;
             }
 
-            /* Update following clusters. */
-            idx = opentype_layout_get_next_char_index(context, context->cur);
-            if (idx != ~0u)
-            {
-                for (i = idx; i < context->length; ++i)
-                    context->u.subst.clustermap[i] += glyph_count;
-            }
-
             context->cur += glyph_count + 1;
             context->glyph_count += glyph_count;
         }
@@ -5889,6 +5858,7 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c
         if (!g || !opentype_is_diacritic(codepoint))
         {
             context->u.buffer.glyph_props[g].isClusterStart = 1;
+            context->glyph_infos[g].start_text_idx = i;
             cluster_start_idx = g;
         }
 
@@ -5932,7 +5902,7 @@ void opentype_layout_apply_gsub_features(struct scriptshaping_context *context,
         unsigned int language_index, const struct shaping_features *features)
 {
     struct lookups lookups = { 0 };
-    unsigned int i;
+    unsigned int i, j, start_idx;
     BOOL ret;
 
     context->nesting_level_left = SHAPE_MAX_NESTING_LEVEL;
@@ -5981,6 +5951,29 @@ void opentype_layout_apply_gsub_features(struct scriptshaping_context *context,
         }
     }
 
+    /* For every glyph range of [<last>.isClusterStart, <next>.isClusterStart) set corresponding
+       text span to start_idx. */
+    start_idx = 0;
+    for (i = 1; i < context->glyph_count; ++i)
+    {
+        if (context->u.buffer.glyph_props[i].isClusterStart)
+        {
+            unsigned int start_text, end_text;
+
+            start_text = context->glyph_infos[start_idx].start_text_idx;
+            end_text = context->glyph_infos[i].start_text_idx;
+
+            for (j = start_text; j < end_text; ++j)
+                context->u.buffer.clustermap[j] = start_idx;
+
+            start_idx = i;
+        }
+    }
+
+    /* Fill the tail. */
+    for (j = context->glyph_infos[start_idx].start_text_idx; j < context->length; ++j)
+        context->u.buffer.clustermap[j] = start_idx;
+
     heap_free(lookups.lookups);
 }
 
-- 
2.26.2




More information about the wine-devel mailing list