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:
parent
102272a4a9
commit
8a52d3e7d9
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue