[gsubgpos] Combine input/backtrack/lookahead unsafe-to-concat

I feel like this is correct logic. Still have to prove.

Errors unchanged at 10.
This commit is contained in:
Behdad Esfahbod 2021-11-21 16:50:34 -07:00
parent 596bc7e939
commit 78481b32c0
3 changed files with 62 additions and 48 deletions

View File

@ -826,14 +826,14 @@ struct Ligature
unsigned int total_component_count = 0; unsigned int total_component_count = 0;
unsigned int match_length = 0; unsigned int match_end = 0;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
if (likely (!match_input (c, count, if (likely (!match_input (c, count,
&component[1], &component[1],
match_glyph, match_glyph,
nullptr, nullptr,
&match_length, &match_end,
match_positions, match_positions,
&total_component_count))) &total_component_count)))
return_trace (false); return_trace (false);
@ -841,7 +841,7 @@ struct Ligature
ligate_input (c, ligate_input (c,
count, count,
match_positions, match_positions,
match_length, match_end,
ligGlyph, ligGlyph,
total_component_count); total_component_count);
@ -1296,7 +1296,7 @@ struct ReverseChainSingleSubstFormat1
match_lookahead (c, match_lookahead (c,
lookahead.len, (HBUINT16 *) lookahead.arrayZ, lookahead.len, (HBUINT16 *) lookahead.arrayZ,
match_coverage, this, match_coverage, this,
1, &end_index)) c->buffer->idx + 1, &end_index))
{ {
c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index); c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
c->replace_glyph_inplace (substitute[index]); c->replace_glyph_inplace (substitute[index]);
@ -1305,9 +1305,12 @@ struct ReverseChainSingleSubstFormat1
* calls us through a Context lookup. */ * calls us through a Context lookup. */
return_trace (true); return_trace (true);
} }
else
{
c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
return_trace (false); return_trace (false);
} }
}
template<typename Iterator, template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))> hb_requires (hb_is_iterator (Iterator))>

View File

@ -967,7 +967,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
const HBUINT16 input[], /* Array of input values--start with second glyph */ const HBUINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func, match_func_t match_func,
const void *match_data, const void *match_data,
unsigned int *end_offset, unsigned int *end_position,
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
unsigned int *p_total_component_count = nullptr) unsigned int *p_total_component_count = nullptr)
{ {
@ -1023,7 +1023,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
unsigned unsafe_to; unsigned unsafe_to;
if (!skippy_iter.next (&unsafe_to)) if (!skippy_iter.next (&unsafe_to))
{ {
c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to); *end_position = unsafe_to;
return_trace (false); return_trace (false);
} }
@ -1079,7 +1079,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]); total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
} }
*end_offset = skippy_iter.idx - buffer->idx + 1; *end_position = skippy_iter.idx + 1;
if (p_total_component_count) if (p_total_component_count)
*p_total_component_count = total_component_count; *p_total_component_count = total_component_count;
@ -1089,7 +1089,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
static inline bool ligate_input (hb_ot_apply_context_t *c, static inline bool ligate_input (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */ unsigned int count, /* Including the first glyph */
const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int match_length, unsigned int match_end,
hb_codepoint_t lig_glyph, hb_codepoint_t lig_glyph,
unsigned int total_component_count) unsigned int total_component_count)
{ {
@ -1097,7 +1097,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
buffer->merge_clusters (buffer->idx, buffer->idx + match_length); buffer->merge_clusters (buffer->idx, match_end);
/* - If a base and one or more marks ligate, consider that as a base, NOT /* - If a base and one or more marks ligate, consider that as a base, NOT
* ligature, such that all following marks can still attach to it. * ligature, such that all following marks can still attach to it.
@ -1218,13 +1218,12 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c,
unsigned unsafe_from; unsigned unsafe_from;
if (!skippy_iter.prev (&unsafe_from)) if (!skippy_iter.prev (&unsafe_from))
{ {
c->buffer->unsafe_to_concat_from_outbuffer (unsafe_from, c->buffer->idx); *match_start = unsafe_from;
return_trace (false); return_trace (false);
} }
} }
*match_start = skippy_iter.idx; *match_start = skippy_iter.idx;
return_trace (true); return_trace (true);
} }
@ -1233,13 +1232,13 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
const HBUINT16 lookahead[], const HBUINT16 lookahead[],
match_func_t match_func, match_func_t match_func,
const void *match_data, const void *match_data,
unsigned int offset, unsigned int start_index,
unsigned int *end_index) unsigned int *end_index)
{ {
TRACE_APPLY (nullptr); TRACE_APPLY (nullptr);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
skippy_iter.reset (c->buffer->idx + offset - 1, count); skippy_iter.reset (start_index - 1, count);
skippy_iter.set_match_func (match_func, match_data, lookahead); skippy_iter.set_match_func (match_func, match_data, lookahead);
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
@ -1247,13 +1246,12 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
unsigned unsafe_to; unsigned unsafe_to;
if (!skippy_iter.next (&unsafe_to)) if (!skippy_iter.next (&unsafe_to))
{ {
c->buffer->unsafe_to_concat (c->buffer->idx + offset, unsafe_to); *end_index = unsafe_to;
return_trace (false); return_trace (false);
} }
} }
*end_index = skippy_iter.idx + 1; *end_index = skippy_iter.idx + 1;
return_trace (true); return_trace (true);
} }
@ -1379,15 +1377,13 @@ static inline void recurse_lookups (context_t *c,
c->recurse (lookupRecord[i].lookupListIndex); c->recurse (lookupRecord[i].lookupListIndex);
} }
static inline bool apply_lookup (hb_ot_apply_context_t *c, static inline void apply_lookup (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */ unsigned int count, /* Including the first glyph */
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int lookupCount, unsigned int lookupCount,
const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
unsigned int match_length) unsigned int match_end)
{ {
TRACE_APPLY (nullptr);
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
int end; int end;
@ -1395,7 +1391,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
* Adjust. */ * Adjust. */
{ {
unsigned int bl = buffer->backtrack_len (); unsigned int bl = buffer->backtrack_len ();
end = bl + match_length; end = bl + match_end - buffer->idx;
int delta = bl - buffer->idx; int delta = bl - buffer->idx;
/* Convert positions to new indexing. */ /* Convert positions to new indexing. */
@ -1497,8 +1493,6 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
} }
(void) buffer->move_to (end); (void) buffer->move_to (end);
return_trace (true);
} }
@ -1586,17 +1580,25 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
const LookupRecord lookupRecord[], const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context) ContextApplyLookupContext &lookup_context)
{ {
unsigned int match_length = 0; unsigned match_end = 0;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
return match_input (c, if (match_input (c,
inputCount, input, inputCount, input,
lookup_context.funcs.match, lookup_context.match_data, lookup_context.funcs.match, lookup_context.match_data,
&match_length, match_positions) &match_end, match_positions))
&& (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length), {
c->buffer->unsafe_to_break (c->buffer->idx, match_end);
apply_lookup (c, apply_lookup (c,
inputCount, match_positions, inputCount, match_positions,
lookupCount, lookupRecord, lookupCount, lookupRecord,
match_length)); match_end);
return true;
}
else
{
c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
return false;
}
} }
struct Rule struct Rule
@ -2488,12 +2490,13 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
const LookupRecord lookupRecord[], const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context) ChainContextApplyLookupContext &lookup_context)
{ {
unsigned int start_index = 0, match_length = 0, end_index = 0; unsigned start_index = c->buffer->out_len, end_index = c->buffer->idx;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; unsigned match_end = 0;
return match_input (c, unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
if (match_input (c,
inputCount, input, inputCount, input,
lookup_context.funcs.match, lookup_context.match_data[1], lookup_context.funcs.match, lookup_context.match_data[1],
&match_length, match_positions) &match_end, match_positions) && (end_index = match_end)
&& match_backtrack (c, && match_backtrack (c,
backtrackCount, backtrack, backtrackCount, backtrack,
lookup_context.funcs.match, lookup_context.match_data[0], lookup_context.funcs.match, lookup_context.match_data[0],
@ -2501,12 +2504,20 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
&& match_lookahead (c, && match_lookahead (c,
lookaheadCount, lookahead, lookaheadCount, lookahead,
lookup_context.funcs.match, lookup_context.match_data[2], lookup_context.funcs.match, lookup_context.match_data[2],
match_length, &end_index) match_end, &end_index))
&& (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index), {
c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
apply_lookup (c, apply_lookup (c,
inputCount, match_positions, inputCount, match_positions,
lookupCount, lookupRecord, lookupCount, lookupRecord,
match_length)); match_end);
return true;
}
else
{
c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
return false;
}
} }
struct ChainRule struct ChainRule