Refactor mark skipping
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 24bc315..f22306f 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -68,6 +68,85 @@ 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 { clear_property (); @@ -132,25 +211,20 @@ const void *match_data, unsigned int *context_length_out) { - unsigned int j = c->buffer->idx; - unsigned int end = MIN (c->buffer->len, j + c->context_length); - if (unlikely (j + count > end)) + 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; for (unsigned int i = 1; i < count; i++) { - do - { - j++; - if (unlikely (j >= end)) - return false; - } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL)); + if (!skippy_iter.next ()) + return false; - 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; } - *context_length_out = j - c->buffer->idx + 1; + *context_length_out = skippy_iter.idx - c->buffer->idx + 1; return true; } @@ -161,18 +235,16 @@ match_func_t match_func, 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++) { - do - { - if (unlikely (!j)) - return false; - j--; - } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[j], c->lookup_props, NULL)); + if (!skippy_iter.prev ()) + return false; - 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; } @@ -186,19 +258,16 @@ const void *match_data, unsigned int offset) { - unsigned int j = c->buffer->idx + offset - 1; - unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); + hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count); + if (skippy_iter.has_no_chance ()) + return false; for (unsigned int i = 0; i < count; i++) { - do - { - j++; - if (unlikely (j >= end)) - return false; - } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[j], c->lookup_props, NULL)); + if (!skippy_iter.next ()) + return false; - 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; }