dwrite: Implement contextual positional lookups.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-06-08 16:29:47 +03:00 committed by Alexandre Julliard
parent 102272a4a9
commit 8a52d3e7d9
1 changed files with 22 additions and 30 deletions

View File

@ -610,7 +610,7 @@ struct ot_gsub_lig
UINT16 components[1]; UINT16 components[1];
}; };
struct ot_gsub_context_subst_format1 struct ot_gsubgpos_context_format1
{ {
UINT16 format; UINT16 format;
UINT16 coverage; UINT16 coverage;
@ -618,7 +618,7 @@ struct ot_gsub_context_subst_format1
UINT16 rulesets[1]; UINT16 rulesets[1];
}; };
struct ot_gsub_ruleset struct ot_gsubgpos_ruleset
{ {
UINT16 count; UINT16 count;
UINT16 offsets[1]; UINT16 offsets[1];
@ -4197,18 +4197,6 @@ static BOOL opentype_layout_apply_gpos_mark_to_mark_attachment(struct scriptshap
return TRUE; return TRUE;
} }
static BOOL opentype_layout_apply_gpos_contextual_positioning(const struct scriptshaping_context *context,
const struct lookup *lookup, unsigned int subtable_offset)
{
return FALSE;
}
static BOOL opentype_layout_apply_gpos_chaining_contextual_positioning(const struct scriptshaping_context *context,
const struct lookup *lookup, unsigned int subtable_offset)
{
return FALSE;
}
static unsigned int opentype_layout_adjust_extension_subtable(struct scriptshaping_context *context, static unsigned int opentype_layout_adjust_extension_subtable(struct scriptshaping_context *context,
unsigned int *subtable_offset) unsigned int *subtable_offset)
{ {
@ -4228,6 +4216,11 @@ static unsigned int opentype_layout_adjust_extension_subtable(struct scriptshapi
return GET_BE_WORD(format1->lookup_type); return GET_BE_WORD(format1->lookup_type);
} }
static BOOL opentype_layout_apply_context(struct scriptshaping_context *context, const struct lookup *lookup,
unsigned int subtable_offset);
static BOOL opentype_layout_apply_chain_context(struct scriptshaping_context *context, const struct lookup *lookup,
unsigned int subtable_offset);
static BOOL opentype_layout_apply_gpos_lookup(struct scriptshaping_context *context, const struct lookup *lookup) static BOOL opentype_layout_apply_gpos_lookup(struct scriptshaping_context *context, const struct lookup *lookup)
{ {
unsigned int i, lookup_type; unsigned int i, lookup_type;
@ -4267,10 +4260,10 @@ static BOOL opentype_layout_apply_gpos_lookup(struct scriptshaping_context *cont
ret = opentype_layout_apply_gpos_mark_to_mark_attachment(context, lookup, subtable_offset); ret = opentype_layout_apply_gpos_mark_to_mark_attachment(context, lookup, subtable_offset);
break; break;
case GPOS_LOOKUP_CONTEXTUAL_POSITION: case GPOS_LOOKUP_CONTEXTUAL_POSITION:
ret = opentype_layout_apply_gpos_contextual_positioning(context, lookup, subtable_offset); ret = opentype_layout_apply_context(context, lookup, subtable_offset);
break; break;
case GPOS_LOOKUP_CONTEXTUAL_CHAINING_POSITION: case GPOS_LOOKUP_CONTEXTUAL_CHAINING_POSITION:
ret = opentype_layout_apply_gpos_chaining_contextual_positioning(context, lookup, subtable_offset); ret = opentype_layout_apply_chain_context(context, lookup, subtable_offset);
break; break;
case GPOS_LOOKUP_EXTENSION_POSITION: case GPOS_LOOKUP_EXTENSION_POSITION:
WARN("Recursive extension lookup.\n"); WARN("Recursive extension lookup.\n");
@ -5165,7 +5158,7 @@ static BOOL opentype_layout_apply_chain_rule_set(const struct match_context *mc,
unsigned int backtrack_count, input_count, lookahead_count, lookup_count; unsigned int backtrack_count, input_count, lookahead_count, lookup_count;
const struct dwrite_fonttable *table = &mc->context->table->table; const struct dwrite_fonttable *table = &mc->context->table->table;
const UINT16 *backtrack, *lookahead, *input, *lookup_records; const UINT16 *backtrack, *lookahead, *input, *lookup_records;
const struct ot_gsub_ruleset *ruleset; const struct ot_gsubgpos_ruleset *ruleset;
unsigned int i, count; unsigned int i, count;
count = table_read_be_word(table, offset); count = table_read_be_word(table, offset);
@ -5223,7 +5216,7 @@ static BOOL opentype_layout_apply_rule_set(const struct match_context *mc, unsig
unsigned int input_count, lookup_count; unsigned int input_count, lookup_count;
const struct dwrite_fonttable *table = &mc->context->table->table; const struct dwrite_fonttable *table = &mc->context->table->table;
const UINT16 *input, *lookup_records; const UINT16 *input, *lookup_records;
const struct ot_gsub_ruleset *ruleset; const struct ot_gsubgpos_ruleset *ruleset;
unsigned int i, count; unsigned int i, count;
count = table_read_be_word(table, offset); count = table_read_be_word(table, offset);
@ -5256,7 +5249,7 @@ static BOOL opentype_layout_apply_rule_set(const struct match_context *mc, unsig
return FALSE; return FALSE;
} }
static BOOL opentype_layout_apply_gsub_context_substitution(struct scriptshaping_context *context, const struct lookup *lookup, static BOOL opentype_layout_apply_context(struct scriptshaping_context *context, const struct lookup *lookup,
unsigned int subtable_offset) unsigned int subtable_offset)
{ {
struct match_context mc = { .context = context, .lookup = lookup }; struct match_context mc = { .context = context, .lookup = lookup };
@ -5271,18 +5264,17 @@ static BOOL opentype_layout_apply_gsub_context_substitution(struct scriptshaping
if (format == 1) if (format == 1)
{ {
coverage = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, coverage)); coverage = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1, coverage));
coverage_index = opentype_layout_is_glyph_covered(table, subtable_offset + coverage, glyph); coverage_index = opentype_layout_is_glyph_covered(table, subtable_offset + coverage, glyph);
if (coverage_index == GLYPH_NOT_COVERED) if (coverage_index == GLYPH_NOT_COVERED)
return FALSE; return FALSE;
count = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, count = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1, ruleset_count));
ruleset_count));
if (coverage_index >= count) if (coverage_index >= count)
return FALSE; return FALSE;
offset = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, offset = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1,
rulesets[coverage_index])); rulesets[coverage_index]));
offset += subtable_offset; offset += subtable_offset;
@ -5358,8 +5350,8 @@ static BOOL opentype_layout_apply_gsub_context_substitution(struct scriptshaping
return ret; return ret;
} }
static BOOL opentype_layout_apply_gsub_chain_context_substitution(struct scriptshaping_context *context, static BOOL opentype_layout_apply_chain_context(struct scriptshaping_context *context, const struct lookup *lookup,
const struct lookup *lookup, unsigned int subtable_offset) unsigned int subtable_offset)
{ {
struct match_context mc = { .context = context, .lookup = lookup }; struct match_context mc = { .context = context, .lookup = lookup };
const struct dwrite_fonttable *table = &context->table->table; const struct dwrite_fonttable *table = &context->table->table;
@ -5373,17 +5365,17 @@ static BOOL opentype_layout_apply_gsub_chain_context_substitution(struct scripts
if (format == 1) if (format == 1)
{ {
coverage = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, coverage)); coverage = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1, coverage));
coverage_index = opentype_layout_is_glyph_covered(table, subtable_offset + coverage, glyph); coverage_index = opentype_layout_is_glyph_covered(table, subtable_offset + coverage, glyph);
if (coverage_index == GLYPH_NOT_COVERED) if (coverage_index == GLYPH_NOT_COVERED)
return FALSE; return FALSE;
count = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, ruleset_count)); count = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1, ruleset_count));
if (coverage_index >= count) if (coverage_index >= count)
return FALSE; return FALSE;
offset = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsub_context_subst_format1, offset = table_read_be_word(table, subtable_offset + FIELD_OFFSET(struct ot_gsubgpos_context_format1,
rulesets[coverage_index])); rulesets[coverage_index]));
offset += subtable_offset; offset += subtable_offset;
@ -5571,10 +5563,10 @@ static BOOL opentype_layout_apply_gsub_lookup(struct scriptshaping_context *cont
ret = opentype_layout_apply_gsub_lig_substitution(context, lookup, subtable_offset); ret = opentype_layout_apply_gsub_lig_substitution(context, lookup, subtable_offset);
break; break;
case GSUB_LOOKUP_CONTEXTUAL_SUBST: case GSUB_LOOKUP_CONTEXTUAL_SUBST:
ret = opentype_layout_apply_gsub_context_substitution(context, lookup, subtable_offset); ret = opentype_layout_apply_context(context, lookup, subtable_offset);
break; break;
case GSUB_LOOKUP_CHAINING_CONTEXTUAL_SUBST: case GSUB_LOOKUP_CHAINING_CONTEXTUAL_SUBST:
ret = opentype_layout_apply_gsub_chain_context_substitution(context, lookup, subtable_offset); ret = opentype_layout_apply_chain_context(context, lookup, subtable_offset);
break; break;
case GSUB_LOOKUP_REVERSE_CHAINING_CONTEXTUAL_SUBST: case GSUB_LOOKUP_REVERSE_CHAINING_CONTEXTUAL_SUBST:
ret = opentype_layout_apply_gsub_reverse_chain_context_substitution(context, lookup, subtable_offset); ret = opentype_layout_apply_gsub_reverse_chain_context_substitution(context, lookup, subtable_offset);