Signed-off-by: Nikolay Sivov nsivov@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; } } }