[PATCH 4/5] dwrite: Use cluster map to apply use feature ranges.

Nikolay Sivov nsivov at codeweavers.com
Wed May 27 02:14:24 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/analyzer.c       |  2 ++
 dlls/dwrite/dwrite_private.h |  7 +++++++
 dlls/dwrite/opentype.c       | 32 +++++++++++++++++++++++++++-----
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index a7186a68156..556191a13d7 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -1251,6 +1251,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphPlacements(IDWriteTextAnalyzer2
     context.is_sideways = is_sideways;
     context.u.pos.glyphs = glyphs;
     context.u.pos.glyph_props = glyph_props;
+    context.u.pos.clustermap = clustermap;
     context.glyph_count = glyph_count;
     context.emsize = emSize;
     context.measuring_mode = DWRITE_MEASURING_MODE_NATURAL;
@@ -1320,6 +1321,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGdiCompatibleGlyphPlacements(IDWrite
     context.is_sideways = is_sideways;
     context.u.pos.glyphs = glyphs;
     context.u.pos.glyph_props = glyph_props;
+    context.u.pos.clustermap = clustermap;
     context.glyph_count = glyph_count;
     context.emsize = emSize * ppdip;
     context.measuring_mode = measuring_mode;
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index ad86422d50f..cf3e0f7c123 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -484,6 +484,7 @@ struct scriptshaping_context
         {
             const UINT16 *glyphs;
             const DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props;
+            const UINT16 *clustermap;
         } pos;
         struct
         {
@@ -494,6 +495,12 @@ struct scriptshaping_context
             unsigned int capacity;
             const WCHAR *digits;
         } subst;
+        struct
+        {
+            UINT16 *glyphs;
+            DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props;
+            UINT16 *clustermap;
+        } buffer;
     } u;
 
     const struct ot_gsubgpos_table *table; /* Either GSUB or GPOS. */
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index c815165505e..f687740fa47 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -4436,18 +4436,40 @@ static unsigned int shaping_features_get_mask(const struct shaping_features *fea
     return feature->mask;
 }
 
+static void opentype_layout_get_glyph_range_for_text(struct scriptshaping_context *context, unsigned int start_char,
+        unsigned int end_char, unsigned int *start_glyph, unsigned int *end_glyph)
+{
+    *start_glyph = context->u.buffer.clustermap[start_char];
+    if (end_char >= context->length - 1)
+        *end_glyph = context->glyph_count - 1;
+    else
+        *end_glyph = context->u.buffer.clustermap[end_char + 1] - 1;
+}
+
 static void opentype_layout_set_glyph_masks(struct scriptshaping_context *context, const struct shaping_features *features)
 {
    const DWRITE_TYPOGRAPHIC_FEATURES **user_features = context->user_features.features;
-   unsigned int f, r, g, start_glyph = 0, mask, shift, value;
+   unsigned int f, r, g, start_char, mask, shift, value;
 
    for (g = 0; g < context->glyph_count; ++g)
        context->glyph_infos[g].mask = context->global_mask;
 
    /* FIXME: set shaper masks */
 
-   for (r = 0; r < context->user_features.range_count; ++r)
+   for (r = 0, start_char = 0; r < context->user_features.range_count; ++r)
    {
+       unsigned int start_glyph, end_glyph;
+
+       if (start_char >= context->length)
+           break;
+
+       opentype_layout_get_glyph_range_for_text(context, start_char, start_char + context->user_features.range_lengths[r],
+               &start_glyph, &end_glyph);
+       start_char += context->user_features.range_lengths[r];
+
+       if (start_glyph > end_glyph || end_glyph >= context->glyph_count)
+           continue;
+
        for (f = 0; f < user_features[r]->featureCount; ++f)
        {
            mask = shaping_features_get_mask(features, user_features[r]->features[f].nameTag, &shift);
@@ -4455,9 +4477,9 @@ static void opentype_layout_set_glyph_masks(struct scriptshaping_context *contex
                continue;
 
            value = (user_features[r]->features[f].parameter << shift) & mask;
-           for (g = 0; g < context->user_features.range_lengths[r]; ++g)
-               context->glyph_infos[g + start_glyph].mask = (context->glyph_infos[g + start_glyph].mask & ~mask) | value;
-           start_glyph += context->user_features.range_lengths[r];
+
+           for (g = start_glyph; g <= end_glyph; ++g)
+               context->glyph_infos[g].mask = (context->glyph_infos[g].mask & ~mask) | value;
        }
    }
 }
-- 
2.26.2




More information about the wine-devel mailing list