[PATCH 5/5] dwrite: Keep user features values.

Nikolay Sivov nsivov at codeweavers.com
Thu May 21 07:28:49 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  2 ++
 dlls/dwrite/opentype.c       | 49 ++++++++++++++++++++----------------
 dlls/dwrite/shape.c          | 43 +++++++++++++++++++++----------
 3 files changed, 60 insertions(+), 34 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index cad74d9e947..8b5fefc66bd 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -523,6 +523,8 @@ struct shaping_feature
     unsigned int tag;
     unsigned int index;
     unsigned int flags;
+    unsigned int max_value;
+    unsigned int default_value;
 };
 
 struct shaping_features
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 713a5002f35..8904dc546e9 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -4169,33 +4169,40 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
     /* Collect lookups for all given features. */
     for (i = 0; i < features->count; ++i)
     {
+        UINT16 feature_offset, lookup_count;
+
         feature_index = features->features[i].index;
-        if (feature_index != 0xffff)
-        {
-            UINT16 feature_offset = GET_BE_WORD(feature_list->features[feature_index].offset);
-            UINT16 lookup_count;
 
-            lookup_count = table_read_be_word(&table->table, table->feature_list + feature_offset +
-                    FIELD_OFFSET(struct ot_feature, lookup_count));
-            if (!lookup_count)
-                continue;
+        /* Feature wasn't found */
+        if (feature_index == 0xffff)
+            continue;
 
-            if (!dwrite_array_reserve((void **)&lookups->indexes, &lookups->capacity, lookups->count + lookup_count,
-                    sizeof(*lookups->indexes)))
-            {
-                return;
-            }
+        /* FIXME: skip non-global ones for now. */
+        if (!(features->features[i].flags & FEATURE_GLOBAL))
+            continue;
 
-            for (l = 0; l < lookup_count; ++l)
-            {
-                UINT16 lookup_index = table_read_be_word(&table->table, table->feature_list + feature_offset +
-                        FIELD_OFFSET(struct ot_feature, lookuplist_index[l]));
+        feature_offset = GET_BE_WORD(feature_list->features[feature_index].offset);
 
-                if (lookup_index >= total_lookup_count)
-                    continue;
+        lookup_count = table_read_be_word(&table->table, table->feature_list + feature_offset +
+                FIELD_OFFSET(struct ot_feature, lookup_count));
+        if (!lookup_count)
+            continue;
 
-                lookups->indexes[lookups->count++] = lookup_index;
-            }
+        if (!dwrite_array_reserve((void **)&lookups->indexes, &lookups->capacity, lookups->count + lookup_count,
+                sizeof(*lookups->indexes)))
+        {
+            return;
+        }
+
+        for (l = 0; l < lookup_count; ++l)
+        {
+            UINT16 lookup_index = table_read_be_word(&table->table, table->feature_list + feature_offset +
+                    FIELD_OFFSET(struct ot_feature, lookuplist_index[l]));
+
+            if (lookup_index >= total_lookup_count)
+                continue;
+
+            lookups->indexes[lookups->count++] = lookup_index;
         }
     }
 
diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c
index 57c06f62e84..df680373a24 100644
--- a/dlls/dwrite/shape.c
+++ b/dlls/dwrite/shape.c
@@ -201,20 +201,24 @@ static DWORD shape_select_language(const struct scriptshaping_cache *cache, DWOR
     return 0;
 }
 
-static void shape_add_feature_flags(struct shaping_features *features, unsigned int tag, unsigned int flags)
+static void shape_add_feature_full(struct shaping_features *features, unsigned int tag, unsigned int flags, unsigned int value)
 {
+    unsigned int i = features->count;
+
     if (!dwrite_array_reserve((void **)&features->features, &features->capacity, features->count + 1,
             sizeof(*features->features)))
         return;
 
-    features->features[features->count].tag = tag;
-    features->features[features->count].flags = flags;
+    features->features[i].tag = tag;
+    features->features[i].flags = flags;
+    features->features[i].max_value = value;
+    features->features[i].default_value = flags & FEATURE_GLOBAL ? value : 0;
     features->count++;
 }
 
 static void shape_add_feature(struct shaping_features *features, unsigned int tag)
 {
-    shape_add_feature_flags(features, tag, FEATURE_GLOBAL);
+    shape_add_feature_full(features, tag, FEATURE_GLOBAL, 1);
 }
 
 static int features_sorting_compare(const void *a, const void *b)
@@ -229,18 +233,16 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s
     unsigned int j = 0, i;
 
     /* For now only consider global, enabled user features. */
-    if (user_features && context->user_features.range_lengths && context->user_features.range_count == 1)
+    if (user_features && context->user_features.range_lengths)
     {
+        unsigned int flags = context->user_features.range_count == 1 &&
+                context->user_features.range_lengths[0] == context->length ? FEATURE_GLOBAL : 0;
+
         for (i = 0; i < context->user_features.range_count; ++i)
         {
-            if (context->user_features.range_lengths[i] != context->length)
-                break;
-
             for (j = 0; j < user_features[i]->featureCount; ++j)
-            {
-                if (user_features[i]->features[j].parameter == 1)
-                    shape_add_feature(features, user_features[i]->features[j].nameTag);
-            }
+                shape_add_feature_full(features, user_features[i]->features[j].nameTag, flags,
+                        user_features[i]->features[j].parameter);
         }
     }
 
@@ -251,6 +253,21 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s
     {
         if (features->features[i].tag != features->features[j].tag)
             features->features[++j] = features->features[i];
+        else
+        {
+            if (features->features[i].flags & FEATURE_GLOBAL)
+            {
+                features->features[j].flags |= FEATURE_GLOBAL;
+                features->features[j].max_value = features->features[i].max_value;
+                features->features[j].default_value = features->features[i].default_value;
+            }
+            else
+            {
+                if (features->features[j].flags & FEATURE_GLOBAL)
+                    features->features[j].flags ^= FEATURE_GLOBAL;
+                features->features[j].max_value = max(features->features[j].max_value, features->features[i].max_value);
+            }
+        }
     }
     features->count = j + 1;
 }
@@ -369,7 +386,7 @@ HRESULT shape_get_glyphs(struct scriptshaping_context *context, const unsigned i
             shape_add_feature(&features, horizontal_features[i]);
     }
     else
-        shape_add_feature_flags(&features, DWRITE_MAKE_OPENTYPE_TAG('v','e','r','t'), FEATURE_GLOBAL_SEARCH);
+        shape_add_feature_full(&features, DWRITE_MAKE_OPENTYPE_TAG('v','e','r','t'), FEATURE_GLOBAL | FEATURE_GLOBAL_SEARCH, 1);
 
     shape_merge_features(context, &features);
 
-- 
2.26.2




More information about the wine-devel mailing list