[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