Refactor mark skipping
This commit is contained in:
parent
370f03e9c6
commit
4ab9731154
|
@ -629,23 +629,18 @@ struct PairPosFormat1
|
||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY ();
|
TRACE_APPLY ();
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
if (skippy_iter.has_no_chance ())
|
||||||
if (unlikely (j >= end))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
|
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepoint);
|
||||||
if (likely (index == NOT_COVERED))
|
if (likely (index == NOT_COVERED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
do
|
if (!skippy_iter.next ())
|
||||||
{
|
|
||||||
j++;
|
|
||||||
if (unlikely (j == end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
return (this+pairSet[index]).apply (c, &valueFormat1, j);
|
return (this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
@ -691,28 +686,23 @@ struct PairPosFormat2
|
||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY ();
|
TRACE_APPLY ();
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
if (skippy_iter.has_no_chance ())
|
||||||
if (unlikely (j >= end))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int index = (this+coverage) (c->buffer->info[j].codepoint);
|
unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepoint);
|
||||||
if (likely (index == NOT_COVERED))
|
if (likely (index == NOT_COVERED))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
do
|
if (!skippy_iter.next ())
|
||||||
{
|
|
||||||
j++;
|
|
||||||
if (unlikely (j == end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
unsigned int len1 = valueFormat1.get_len ();
|
unsigned int len1 = valueFormat1.get_len ();
|
||||||
unsigned int len2 = valueFormat2.get_len ();
|
unsigned int len2 = valueFormat2.get_len ();
|
||||||
unsigned int record_len = len1 + len2;
|
unsigned int record_len = len1 + len2;
|
||||||
|
|
||||||
unsigned int klass1 = (this+classDef1) (c->buffer->info[c->buffer->idx].codepoint);
|
unsigned int klass1 = (this+classDef1) (c->buffer->info[c->buffer->idx].codepoint);
|
||||||
unsigned int klass2 = (this+classDef2) (c->buffer->info[j].codepoint);
|
unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].codepoint);
|
||||||
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
|
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -720,11 +710,11 @@ struct PairPosFormat2
|
||||||
valueFormat1.apply_value (c->font, c->direction, this,
|
valueFormat1.apply_value (c->font, c->direction, this,
|
||||||
v, c->buffer->pos[c->buffer->idx]);
|
v, c->buffer->pos[c->buffer->idx]);
|
||||||
valueFormat2.apply_value (c->font, c->direction, this,
|
valueFormat2.apply_value (c->font, c->direction, this,
|
||||||
v + len1, c->buffer->pos[j]);
|
v + len1, c->buffer->pos[skippy_iter.idx]);
|
||||||
|
|
||||||
|
c->buffer->idx = skippy_iter.idx;
|
||||||
if (len2)
|
if (len2)
|
||||||
j++;
|
c->buffer->idx++;
|
||||||
c->buffer->idx = j;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -846,27 +836,23 @@ struct CursivePosFormat1
|
||||||
if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
|
if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
if (skippy_iter.has_no_chance ())
|
||||||
if (unlikely (j >= end))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
|
const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[c->buffer->idx].codepoint)];
|
||||||
if (!this_record.exitAnchor)
|
if (!this_record.exitAnchor)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
do
|
if (!skippy_iter.next ())
|
||||||
{
|
|
||||||
j++;
|
|
||||||
if (unlikely (j == end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)];
|
const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[skippy_iter.idx].codepoint)];
|
||||||
if (!next_record.entryAnchor)
|
if (!next_record.entryAnchor)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int i = c->buffer->idx;
|
unsigned int i = c->buffer->idx;
|
||||||
|
unsigned int j = skippy_iter.idx;
|
||||||
|
|
||||||
hb_position_t entry_x, entry_y, exit_x, exit_y;
|
hb_position_t entry_x, entry_y, exit_x, exit_y;
|
||||||
(this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
|
(this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
|
||||||
|
@ -997,23 +983,19 @@ struct MarkBasePosFormat1
|
||||||
|
|
||||||
/* now we search backwards for a non-mark glyph */
|
/* now we search backwards for a non-mark glyph */
|
||||||
unsigned int property;
|
unsigned int property;
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
do
|
if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks))
|
||||||
{
|
|
||||||
if (unlikely (!j))
|
|
||||||
return false;
|
return false;
|
||||||
j--;
|
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], LookupFlag::IgnoreMarks, &property));
|
|
||||||
|
|
||||||
/* The following assertion is too strong, so we've disabled it. */
|
/* The following assertion is too strong, so we've disabled it. */
|
||||||
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH))
|
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH))
|
||||||
{/*return false;*/}
|
{/*return false;*/}
|
||||||
|
|
||||||
unsigned int base_index = (this+baseCoverage) (c->buffer->info[j].codepoint);
|
unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.idx].codepoint);
|
||||||
if (base_index == NOT_COVERED)
|
if (base_index == NOT_COVERED)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, j);
|
return (this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||||
|
@ -1099,18 +1081,15 @@ struct MarkLigPosFormat1
|
||||||
|
|
||||||
/* now we search backwards for a non-mark glyph */
|
/* now we search backwards for a non-mark glyph */
|
||||||
unsigned int property;
|
unsigned int property;
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
do
|
if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks))
|
||||||
{
|
|
||||||
if (unlikely (!j))
|
|
||||||
return false;
|
return false;
|
||||||
j--;
|
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], LookupFlag::IgnoreMarks, &property));
|
|
||||||
|
|
||||||
/* The following assertion is too strong, so we've disabled it. */
|
/* The following assertion is too strong, so we've disabled it. */
|
||||||
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE))
|
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE))
|
||||||
{/*return false;*/}
|
{/*return false;*/}
|
||||||
|
|
||||||
|
unsigned int j = skippy_iter.idx;
|
||||||
unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoint);
|
unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoint);
|
||||||
if (lig_index == NOT_COVERED)
|
if (lig_index == NOT_COVERED)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1218,17 +1197,15 @@ struct MarkMarkPosFormat1
|
||||||
|
|
||||||
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
||||||
unsigned int property;
|
unsigned int property;
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
|
||||||
do
|
if (!skippy_iter.prev (&property))
|
||||||
{
|
|
||||||
if (unlikely (!j))
|
|
||||||
return false;
|
return false;
|
||||||
j--;
|
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, &property));
|
|
||||||
|
|
||||||
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
unsigned int j = skippy_iter.idx;
|
||||||
|
|
||||||
/* Two marks match only if they belong to the same base, or same component
|
/* Two marks match only if they belong to the same base, or same component
|
||||||
* of the same ligature. That is, the component numbers must match, and
|
* of the same ligature. That is, the component numbers must match, and
|
||||||
* if those are non-zero, the ligid number should also match. */
|
* if those are non-zero, the ligid number should also match. */
|
||||||
|
|
|
@ -343,10 +343,12 @@ struct Ligature
|
||||||
inline bool apply (hb_apply_context_t *c) const
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY ();
|
TRACE_APPLY ();
|
||||||
unsigned int j = c->buffer->idx;
|
|
||||||
unsigned int count = component.len;
|
unsigned int count = component.len;
|
||||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
if (unlikely (count < 2))
|
||||||
if (unlikely (count < 2 || j >= end))
|
return false;
|
||||||
|
|
||||||
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
|
||||||
|
if (skippy_iter.has_no_chance ())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
bool first_was_mark = (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
||||||
|
@ -355,16 +357,13 @@ struct Ligature
|
||||||
for (unsigned int i = 1; i < count; i++)
|
for (unsigned int i = 1; i < count; i++)
|
||||||
{
|
{
|
||||||
unsigned int property;
|
unsigned int property;
|
||||||
do
|
|
||||||
{
|
if (!skippy_iter.next (&property))
|
||||||
j++;
|
|
||||||
if (unlikely (j == end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, &property));
|
|
||||||
|
|
||||||
found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
found_non_mark |= !(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
|
||||||
|
|
||||||
if (likely (c->buffer->info[j].codepoint != component[i]))
|
if (likely (c->buffer->info[skippy_iter.idx].codepoint != component[i]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +375,7 @@ struct Ligature
|
||||||
c->buffer->info[c->buffer->idx].lig_comp() = 0;
|
c->buffer->info[c->buffer->idx].lig_comp() = 0;
|
||||||
c->buffer->info[c->buffer->idx].lig_id() = lig_id;
|
c->buffer->info[c->buffer->idx].lig_id() = lig_id;
|
||||||
|
|
||||||
if (j < c->buffer->idx + count) /* No input glyphs skipped */
|
if (skippy_iter.idx < c->buffer->idx + count) /* No input glyphs skipped */
|
||||||
{
|
{
|
||||||
c->replace_glyphs_be16 (count, 1, (const uint16_t *) &ligGlyph);
|
c->replace_glyphs_be16 (count, 1, (const uint16_t *) &ligGlyph);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,85 @@ struct hb_apply_context_t
|
||||||
unsigned int property; /* propety of first glyph */
|
unsigned int property; /* propety of first glyph */
|
||||||
|
|
||||||
|
|
||||||
|
struct mark_skipping_forward_iterator_t
|
||||||
|
{
|
||||||
|
inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_,
|
||||||
|
unsigned int start_index_,
|
||||||
|
unsigned int num_items_)
|
||||||
|
{
|
||||||
|
c = c_;
|
||||||
|
idx = start_index_;
|
||||||
|
num_items = num_items_;
|
||||||
|
end = MIN (c->buffer->len, c->buffer->idx + c->context_length);
|
||||||
|
}
|
||||||
|
inline bool has_no_chance (void) const
|
||||||
|
{
|
||||||
|
return unlikely (num_items && idx + num_items >= end);
|
||||||
|
}
|
||||||
|
inline bool next (unsigned int *property_out,
|
||||||
|
unsigned int lookup_props)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
idx++;
|
||||||
|
if (has_no_chance ())
|
||||||
|
return false;
|
||||||
|
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[idx], lookup_props, property_out));
|
||||||
|
num_items--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
inline bool next (unsigned int *property_out = NULL)
|
||||||
|
{
|
||||||
|
return next (property_out, c->lookup_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int idx;
|
||||||
|
private:
|
||||||
|
hb_apply_context_t *c;
|
||||||
|
unsigned int num_items;
|
||||||
|
unsigned int end;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mark_skipping_backward_iterator_t
|
||||||
|
{
|
||||||
|
inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_,
|
||||||
|
unsigned int start_index_,
|
||||||
|
unsigned int num_items_)
|
||||||
|
{
|
||||||
|
c = c_;
|
||||||
|
idx = start_index_;
|
||||||
|
num_items = num_items_;
|
||||||
|
}
|
||||||
|
inline bool has_no_chance (void) const
|
||||||
|
{
|
||||||
|
return unlikely (num_items && num_items >= idx);
|
||||||
|
}
|
||||||
|
inline bool prev (unsigned int *property_out,
|
||||||
|
unsigned int lookup_props)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (has_no_chance ())
|
||||||
|
return false;
|
||||||
|
idx--;
|
||||||
|
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[idx], lookup_props, property_out));
|
||||||
|
num_items--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
inline bool prev (unsigned int *property_out = NULL)
|
||||||
|
{
|
||||||
|
return prev (property_out, c->lookup_props);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int idx;
|
||||||
|
private:
|
||||||
|
hb_apply_context_t *c;
|
||||||
|
unsigned int num_items;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline void replace_glyph (hb_codepoint_t glyph_index) const
|
inline void replace_glyph (hb_codepoint_t glyph_index) const
|
||||||
{
|
{
|
||||||
clear_property ();
|
clear_property ();
|
||||||
|
@ -132,25 +211,20 @@ static inline bool match_input (hb_apply_context_t *c,
|
||||||
const void *match_data,
|
const void *match_data,
|
||||||
unsigned int *context_length_out)
|
unsigned int *context_length_out)
|
||||||
{
|
{
|
||||||
unsigned int j = c->buffer->idx;
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
|
||||||
unsigned int end = MIN (c->buffer->len, j + c->context_length);
|
if (skippy_iter.has_no_chance ())
|
||||||
if (unlikely (j + count > end))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (unsigned int i = 1; i < count; i++)
|
for (unsigned int i = 1; i < count; i++)
|
||||||
{
|
{
|
||||||
do
|
if (!skippy_iter.next ())
|
||||||
{
|
|
||||||
j++;
|
|
||||||
if (unlikely (j >= end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
if (likely (!match_func (c->buffer->info[j].codepoint, input[i - 1], match_data)))
|
if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i - 1], match_data)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*context_length_out = j - c->buffer->idx + 1;
|
*context_length_out = skippy_iter.idx - c->buffer->idx + 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -161,18 +235,16 @@ static inline bool match_backtrack (hb_apply_context_t *c,
|
||||||
match_func_t match_func,
|
match_func_t match_func,
|
||||||
const void *match_data)
|
const void *match_data)
|
||||||
{
|
{
|
||||||
unsigned int j = c->buffer->backtrack_len ();
|
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count);
|
||||||
|
if (skippy_iter.has_no_chance ())
|
||||||
|
return false;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
do
|
if (!skippy_iter.prev ())
|
||||||
{
|
|
||||||
if (unlikely (!j))
|
|
||||||
return false;
|
return false;
|
||||||
j--;
|
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
if (likely (!match_func (c->buffer->out_info[j].codepoint, backtrack[i], match_data)))
|
if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, backtrack[i], match_data)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,19 +258,16 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
||||||
const void *match_data,
|
const void *match_data,
|
||||||
unsigned int offset)
|
unsigned int offset)
|
||||||
{
|
{
|
||||||
unsigned int j = c->buffer->idx + offset - 1;
|
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count);
|
||||||
unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length);
|
if (skippy_iter.has_no_chance ())
|
||||||
|
return false;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
do
|
if (!skippy_iter.next ())
|
||||||
{
|
|
||||||
j++;
|
|
||||||
if (unlikely (j >= end))
|
|
||||||
return false;
|
return false;
|
||||||
} while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL));
|
|
||||||
|
|
||||||
if (likely (!match_func (c->buffer->info[j].codepoint, lookahead[i], match_data)))
|
if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahead[i], match_data)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue