Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/shape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c index 3d25898cf7a..77c5ba1f8a2 100644 --- a/dlls/dwrite/shape.c +++ b/dlls/dwrite/shape.c @@ -231,7 +231,7 @@ static int features_sorting_compare(const void *a, const void *b) static void shape_merge_features(struct scriptshaping_context *context, struct shaping_features *features) { const DWRITE_TYPOGRAPHIC_FEATURES **user_features = context->user_features.features; - unsigned int j = 0, i; + unsigned int i, j;
/* For now only consider global, enabled user features. */ if (user_features && context->user_features.range_lengths) @@ -250,7 +250,7 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s /* Sort and merge duplicates. */ qsort(features->features, features->count, sizeof(*features->features), features_sorting_compare);
- for (i = 1; i < features->count; ++i) + for (i = 1, j = 0; i < features->count; ++i) { if (features->features[i].tag != features->features[j].tag) features->features[++j] = features->features[i];
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/opentype.c | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 4cf1523f470..dd25c619c11 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -465,6 +465,7 @@ struct scriptshaping_cache struct shaping_glyph_info { unsigned int mask; + unsigned int props; };
struct scriptshaping_context diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 77ae1e84473..814e65b6cca 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -494,6 +494,13 @@ enum gsub_gpos_lookup_flags LOOKUP_FLAG_IGNORE_MASK = 0xe, };
+enum glyph_prop_flags +{ + GLYPH_PROP_BASE = LOOKUP_FLAG_IGNORE_BASE, + GLYPH_PROP_LIGATURE = LOOKUP_FLAG_IGNORE_LIGATURES, + GLYPH_PROP_MARK = LOOKUP_FLAG_IGNORE_MARKS, +}; + enum gpos_lookup_type { GPOS_LOOKUP_SINGLE_ADJUSTMENT = 1, @@ -4684,6 +4691,36 @@ static unsigned int unicode_get_mirrored_char(unsigned int codepoint) return mirror ? mirror : codepoint; }
+static void opentype_subst_set_glyph_props(struct scriptshaping_context *context, unsigned int g) +{ + struct scriptshaping_cache *cache = context->cache; + unsigned int glyph_class = 0, props; + + if (cache->gdef.classdef) + { + glyph_class = opentype_layout_get_glyph_class(&cache->gdef.table, cache->gdef.classdef, context->u.subst.glyphs[g]); + } + + switch (glyph_class) + { + case GDEF_CLASS_BASE: + props = GLYPH_PROP_BASE; + break; + case GDEF_CLASS_LIGATURE: + props = GLYPH_PROP_LIGATURE; + break; + case GDEF_CLASS_MARK: + props = GLYPH_PROP_MARK; + context->u.subst.glyph_props[g].isDiacritic = 1; + context->u.subst.glyph_props[g].isZeroWidthSpace = 1; + break; + default: + props = 0; + } + + context->glyph_infos[g].props = props; +} + static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, const struct shaping_features *features) { unsigned int rtlm_mask = shaping_features_get_mask(features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), NULL); @@ -4724,6 +4761,7 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c context->u.subst.glyphs[g] = font->get_glyph(context->cache->context, codepoint); context->u.subst.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER; context->u.subst.glyph_props[g].isClusterStart = 1; + opentype_subst_set_glyph_props(context, g); context->glyph_count++;
clustermap[i] = i;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 68 +++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 814e65b6cca..0b9c6067b59 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -3130,6 +3130,36 @@ static unsigned int opentype_layout_get_glyph_class(const struct dwrite_fonttabl return glyph_class; }
+static unsigned int opentype_set_glyph_props(struct scriptshaping_context *context, unsigned int g, UINT16 glyph) +{ + struct scriptshaping_cache *cache = context->cache; + unsigned int glyph_class = 0, props; + + if (cache->gdef.classdef) + { + glyph_class = opentype_layout_get_glyph_class(&cache->gdef.table, cache->gdef.classdef, context->u.subst.glyphs[g]); + } + + switch (glyph_class) + { + case GDEF_CLASS_BASE: + props = GLYPH_PROP_BASE; + break; + case GDEF_CLASS_LIGATURE: + props = GLYPH_PROP_LIGATURE; + break; + case GDEF_CLASS_MARK: + props = GLYPH_PROP_MARK; + break; + default: + props = 0; + } + + context->glyph_infos[g].props = props; + + return props; +} + struct coverage_compare_format1_context { UINT16 glyph; @@ -4377,6 +4407,8 @@ void opentype_layout_apply_gpos_features(struct scriptshaping_context *context,
opentype_layout_collect_lookups(context, script_index, language_index, features, &context->cache->gpos, &lookups);
+ for (i = 0; i < context->glyph_count; ++i) + opentype_set_glyph_props(context, i, context->u.pos.glyphs[i]); opentype_layout_set_glyph_masks(context, features);
for (i = 0; i < lookups.count; ++i) @@ -4691,36 +4723,6 @@ static unsigned int unicode_get_mirrored_char(unsigned int codepoint) return mirror ? mirror : codepoint; }
-static void opentype_subst_set_glyph_props(struct scriptshaping_context *context, unsigned int g) -{ - struct scriptshaping_cache *cache = context->cache; - unsigned int glyph_class = 0, props; - - if (cache->gdef.classdef) - { - glyph_class = opentype_layout_get_glyph_class(&cache->gdef.table, cache->gdef.classdef, context->u.subst.glyphs[g]); - } - - switch (glyph_class) - { - case GDEF_CLASS_BASE: - props = GLYPH_PROP_BASE; - break; - case GDEF_CLASS_LIGATURE: - props = GLYPH_PROP_LIGATURE; - break; - case GDEF_CLASS_MARK: - props = GLYPH_PROP_MARK; - context->u.subst.glyph_props[g].isDiacritic = 1; - context->u.subst.glyph_props[g].isZeroWidthSpace = 1; - break; - default: - props = 0; - } - - context->glyph_infos[g].props = props; -} - static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, const struct shaping_features *features) { unsigned int rtlm_mask = shaping_features_get_mask(features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), NULL); @@ -4761,7 +4763,11 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c context->u.subst.glyphs[g] = font->get_glyph(context->cache->context, codepoint); context->u.subst.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER; context->u.subst.glyph_props[g].isClusterStart = 1; - opentype_subst_set_glyph_props(context, g); + if (opentype_set_glyph_props(context, g, context->u.subst.glyphs[g]) == GLYPH_PROP_MARK) + { + context->u.subst.glyph_props[g].isDiacritic = 1; + context->u.subst.glyph_props[g].isZeroWidthSpace = 1; + } context->glyph_count++;
clustermap[i] = i;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 0b9c6067b59..bb62488330e 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -3425,21 +3425,21 @@ static void glyph_iterator_init(struct scriptshaping_context *context, unsigned iter->len = len; }
-static BOOL glyph_iterator_match(const struct glyph_iterator *iter) +static BOOL lookup_is_glyph_match(unsigned int glyph_props, unsigned int lookup_flags) { - struct scriptshaping_cache *cache = iter->context->cache; + if (glyph_props & lookup_flags & LOOKUP_FLAG_IGNORE_MASK) + return FALSE;
- if (cache->gdef.classdef) - { - unsigned int glyph_class = opentype_layout_get_glyph_class(&cache->gdef.table, cache->gdef.classdef, - iter->context->u.pos.glyphs[iter->pos]); - if ((1 << glyph_class) & iter->flags & LOOKUP_FLAG_IGNORE_MASK) - return FALSE; - } + /* FIXME: match mark properties */
return TRUE; }
+static BOOL glyph_iterator_match(const struct glyph_iterator *iter) +{ + return lookup_is_glyph_match(iter->context->glyph_infos[iter->pos].props, iter->flags); +} + static BOOL glyph_iterator_next(struct glyph_iterator *iter) { while (iter->pos + iter->len < iter->context->glyph_count)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/opentype.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index bb62488330e..abf9cba105d 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -4420,6 +4420,7 @@ void opentype_layout_apply_gpos_features(struct scriptshaping_context *context, static BOOL opentype_layout_apply_gsub_single_substitution(struct glyph_iterator *iter, const struct ot_lookup *lookup) { struct scriptshaping_cache *cache = iter->context->cache; + const struct dwrite_fonttable *gsub = &cache->gsub.table; UINT16 format, coverage; unsigned int i;
@@ -4436,10 +4437,9 @@ static BOOL opentype_layout_apply_gsub_single_substitution(struct glyph_iterator
if (format == 1) { - const struct ot_gsub_singlesubst_format1 *format1 = table_read_ensure(&cache->gsub.table, subtable_offset, - sizeof(*format1)); + const struct ot_gsub_singlesubst_format1 *format1 = table_read_ensure(gsub, subtable_offset, sizeof(*format1));
- coverage_index = opentype_layout_is_glyph_covered(&cache->gsub.table, subtable_offset + coverage, glyph); + coverage_index = opentype_layout_is_glyph_covered(gsub, subtable_offset + coverage, glyph); if (coverage_index == GLYPH_NOT_COVERED) continue;
@@ -4448,12 +4448,11 @@ static BOOL opentype_layout_apply_gsub_single_substitution(struct glyph_iterator } else if (format == 2) { - UINT16 count = table_read_be_word(&cache->gsub.table, subtable_offset + - FIELD_OFFSET(struct ot_gsub_singlesubst_format2, count)); - const struct ot_gsub_singlesubst_format2 *format2 = table_read_ensure(&cache->gsub.table, subtable_offset, + UINT16 count = table_read_be_word(gsub, subtable_offset + FIELD_OFFSET(struct ot_gsub_singlesubst_format2, count)); + const struct ot_gsub_singlesubst_format2 *format2 = table_read_ensure(gsub, subtable_offset, FIELD_OFFSET(struct ot_gsub_singlesubst_format2, count) + count * sizeof(UINT16));
- coverage_index = opentype_layout_is_glyph_covered(&cache->gsub.table, subtable_offset + coverage, glyph); + coverage_index = opentype_layout_is_glyph_covered(gsub, subtable_offset + coverage, glyph); if (coverage_index == GLYPH_NOT_COVERED || coverage_index >= count) continue;