forked from Mirrors/wine-wine
dwrite: Keep user features values.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
bd0abb5968
commit
c8f409ed93
|
@ -523,6 +523,8 @@ struct shaping_feature
|
||||||
unsigned int tag;
|
unsigned int tag;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
unsigned int max_value;
|
||||||
|
unsigned int default_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct shaping_features
|
struct shaping_features
|
||||||
|
|
|
@ -4169,33 +4169,40 @@ static void opentype_layout_collect_lookups(struct scriptshaping_context *contex
|
||||||
/* Collect lookups for all given features. */
|
/* Collect lookups for all given features. */
|
||||||
for (i = 0; i < features->count; ++i)
|
for (i = 0; i < features->count; ++i)
|
||||||
{
|
{
|
||||||
feature_index = features->features[i].index;
|
UINT16 feature_offset, lookup_count;
|
||||||
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 +
|
feature_index = features->features[i].index;
|
||||||
FIELD_OFFSET(struct ot_feature, lookup_count));
|
|
||||||
if (!lookup_count)
|
/* Feature wasn't found */
|
||||||
|
if (feature_index == 0xffff)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* FIXME: skip non-global ones for now. */
|
||||||
|
if (!(features->features[i].flags & FEATURE_GLOBAL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
feature_offset = GET_BE_WORD(feature_list->features[feature_index].offset);
|
||||||
|
|
||||||
|
lookup_count = table_read_be_word(&table->table, table->feature_list + feature_offset +
|
||||||
|
FIELD_OFFSET(struct ot_feature, lookup_count));
|
||||||
|
if (!lookup_count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
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;
|
continue;
|
||||||
|
|
||||||
if (!dwrite_array_reserve((void **)&lookups->indexes, &lookups->capacity, lookups->count + lookup_count,
|
lookups->indexes[lookups->count++] = lookup_index;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,20 +201,24 @@ static DWORD shape_select_language(const struct scriptshaping_cache *cache, DWOR
|
||||||
return 0;
|
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,
|
if (!dwrite_array_reserve((void **)&features->features, &features->capacity, features->count + 1,
|
||||||
sizeof(*features->features)))
|
sizeof(*features->features)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
features->features[features->count].tag = tag;
|
features->features[i].tag = tag;
|
||||||
features->features[features->count].flags = flags;
|
features->features[i].flags = flags;
|
||||||
|
features->features[i].max_value = value;
|
||||||
|
features->features[i].default_value = flags & FEATURE_GLOBAL ? value : 0;
|
||||||
features->count++;
|
features->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shape_add_feature(struct shaping_features *features, unsigned int tag)
|
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)
|
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;
|
unsigned int j = 0, i;
|
||||||
|
|
||||||
/* For now only consider global, enabled user features. */
|
/* 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)
|
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)
|
for (j = 0; j < user_features[i]->featureCount; ++j)
|
||||||
{
|
shape_add_feature_full(features, user_features[i]->features[j].nameTag, flags,
|
||||||
if (user_features[i]->features[j].parameter == 1)
|
user_features[i]->features[j].parameter);
|
||||||
shape_add_feature(features, user_features[i]->features[j].nameTag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +253,21 @@ static void shape_merge_features(struct scriptshaping_context *context, struct s
|
||||||
{
|
{
|
||||||
if (features->features[i].tag != features->features[j].tag)
|
if (features->features[i].tag != features->features[j].tag)
|
||||||
features->features[++j] = features->features[i];
|
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;
|
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]);
|
shape_add_feature(&features, horizontal_features[i]);
|
||||||
}
|
}
|
||||||
else
|
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);
|
shape_merge_features(context, &features);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue