From f064acbdd9fac8a417067a244d008e4177e265f7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 22 Jan 2021 15:25:17 +0300 Subject: [PATCH] dwrite/arabic: Mark some features for fallback. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/dwrite/dwrite_private.h | 3 +++ dlls/dwrite/opentype.c | 2 +- dlls/dwrite/shape.c | 3 ++- dlls/dwrite/shapers/arabic.c | 25 +++++++++++++++++++++++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 76d49ae5104..4a4229e1dc0 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -543,6 +543,7 @@ enum shaping_feature_flags FEATURE_MANUAL_ZWNJ = 0x4, FEATURE_MANUAL_ZWJ = 0x8, FEATURE_MANUAL_JOINERS = FEATURE_MANUAL_ZWNJ | FEATURE_MANUAL_ZWJ, + FEATURE_HAS_FALLBACK = 0x10, }; struct shaping_feature @@ -575,6 +576,8 @@ extern const struct shaper arabic_shaper DECLSPEC_HIDDEN; extern void shape_enable_feature(struct shaping_features *features, unsigned int tag, unsigned int flags) DECLSPEC_HIDDEN; +extern void shape_add_feature_full(struct shaping_features *features, unsigned int tag, unsigned int flags, + unsigned int value) DECLSPEC_HIDDEN; extern void shape_start_next_stage(struct shaping_features *features) DECLSPEC_HIDDEN; struct scriptshaping_context diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 20534460d09..256218663fb 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -4553,7 +4553,7 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex } } - if (!found) + if (!found && !(features->features[i].flags & FEATURE_HAS_FALLBACK)) continue; if (feature->flags & FEATURE_GLOBAL && feature->max_value == 1) diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c index 53b392c88e2..2dbea825216 100644 --- a/dlls/dwrite/shape.c +++ b/dlls/dwrite/shape.c @@ -115,7 +115,7 @@ static DWORD shape_select_language(const struct scriptshaping_cache *cache, DWOR return 0; } -static void shape_add_feature_full(struct shaping_features *features, unsigned int tag, unsigned int flags, unsigned int value) +void shape_add_feature_full(struct shaping_features *features, unsigned int tag, unsigned int flags, unsigned int value) { unsigned int i = features->count; @@ -193,6 +193,7 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s features->features[j].flags ^= FEATURE_GLOBAL; features->features[j].max_value = max(features->features[j].max_value, features->features[i].max_value); } + features->features[j].flags |= features->features[i].flags & FEATURE_HAS_FALLBACK; features->features[j].stage = min(features->features[j].stage, features->features[i].stage); } } diff --git a/dlls/dwrite/shapers/arabic.c b/dlls/dwrite/shapers/arabic.c index d8c6c9495c0..32588b9c796 100644 --- a/dlls/dwrite/shapers/arabic.c +++ b/dlls/dwrite/shapers/arabic.c @@ -18,6 +18,7 @@ */ #include "dwrite_private.h" +#include "scripts.h" static const unsigned int arabic_features[] = { @@ -30,6 +31,24 @@ static const unsigned int arabic_features[] = DWRITE_MAKE_OPENTYPE_TAG('i','n','i','t'), }; +enum arabic_shaping_action +{ + ISOL, + FINA, + FIN2, + FIN3, + MEDI, + MED2, + INIT, + NONE, +}; + +static BOOL feature_is_syriac(unsigned int tag) +{ + return tag == arabic_features[FIN2] || tag == arabic_features[FIN3] || + tag == arabic_features[MED2]; +} + static void arabic_collect_features(struct scriptshaping_context *context, struct shaping_features *features) { @@ -41,11 +60,13 @@ static void arabic_collect_features(struct scriptshaping_context *context, for (i = 0; i < ARRAY_SIZE(arabic_features); ++i) { - shape_enable_feature(features, arabic_features[i], 0); + unsigned int flags = context->script == Script_Arabic && !feature_is_syriac(arabic_features[i]) ? + FEATURE_HAS_FALLBACK : 0; + shape_add_feature_full(features, arabic_features[i], flags, 1); shape_start_next_stage(features); } - shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('r','l','i','g'), FEATURE_MANUAL_ZWJ); + shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('r','l','i','g'), FEATURE_MANUAL_ZWJ | FEATURE_HAS_FALLBACK); shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('r','c','l','t'), FEATURE_MANUAL_ZWJ); shape_enable_feature(features, DWRITE_MAKE_OPENTYPE_TAG('c','a','l','t'), FEATURE_MANUAL_ZWJ);