Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1060)

Unified Diff: third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh

Issue 70193010: Update harfbuzz-ng to 0.9.24 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index f46b3782ec71218709eb73aee3eebbff02427f0b..bdd773e36b9030ff0425c9956722ed225370446f 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -43,7 +43,6 @@ namespace OT {
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"");
-
#ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif
@@ -158,7 +157,13 @@ struct hb_collect_glyphs_context_t
/* Note that GPOS sets recurse_func to NULL already, so it doesn't get
* past the previous check. For GSUB, we only want to collect the output
- * glyphs in the recursion. If output is not requested, we can go home now. */
+ * glyphs in the recursion. If output is not requested, we can go home now.
+ *
+ * Note further, that the above is not exactly correct. A recursed lookup
+ * is allowed to match input that is not matched in the context, but that's
+ * not how most fonts are built. It's possible to relax that and recurse
+ * with all sets here if it proves to be an issue.
+ */
if (output == hb_set_get_empty ())
return HB_VOID;
@@ -272,14 +277,12 @@ struct hb_apply_context_t
hb_apply_context_t (unsigned int table_index_,
hb_font_t *font_,
- hb_buffer_t *buffer_,
- hb_mask_t lookup_mask_,
- bool auto_zwj_) :
+ hb_buffer_t *buffer_) :
table_index (table_index_),
font (font_), face (font->face), buffer (buffer_),
direction (buffer_->props.direction),
- lookup_mask (lookup_mask_),
- auto_zwj (auto_zwj_),
+ lookup_mask (1),
+ auto_zwj (true),
recurse_func (NULL),
nesting_level_left (MAX_NESTING_LEVEL),
lookup_props (0),
@@ -287,6 +290,8 @@ struct hb_apply_context_t
has_glyph_classes (gdef.has_glyph_classes ()),
debug_depth (0) {}
+ inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
+ inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
@@ -346,7 +351,7 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info.glyph_props();
+ property = _hb_glyph_info_get_glyph_props (&info);
if (!c->match_properties (info.codepoint, property, lookup_props))
return SKIP_YES;
@@ -354,7 +359,7 @@ struct hb_apply_context_t
if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
(ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
(ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
- !is_a_ligature (info)))
+ !_hb_glyph_info_ligated (&info)))
return SKIP_MAYBE;
return SKIP_NO;
@@ -555,36 +560,47 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info->glyph_props();
+ property = _hb_glyph_info_get_glyph_props (info);
return match_properties (info->codepoint, property, lookup_props);
}
- inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
+ inline void _set_glyph_props (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0,
+ bool ligature = false) const
{
+ unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+ if (ligature)
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
if (likely (has_glyph_classes))
- buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
else if (class_guess)
- buffer->cur().glyph_props() = class_guess;
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
}
- inline void output_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
- buffer->output_glyph (glyph_index);
+ _set_glyph_props (glyph_index);
+ buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
+ _set_glyph_props (glyph_index);
+ buffer->cur().codepoint = glyph_index;
+ }
+ inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
+ {
+ _set_glyph_props (glyph_index, class_guess, true);
buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void output_glyph (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
{
- set_class (glyph_index, class_guess);
- buffer->cur().codepoint = glyph_index;
+ _set_glyph_props (glyph_index, class_guess);
+ buffer->output_glyph (glyph_index);
}
};
@@ -697,13 +713,18 @@ static inline bool match_input (hb_apply_context_t *c,
const USHORT input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
- unsigned int *end_offset = NULL,
+ unsigned int *end_offset,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH],
bool *p_is_mark_ligature = NULL,
unsigned int *p_total_component_count = NULL)
{
TRACE_APPLY (NULL);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -725,20 +746,23 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
unsigned int total_component_count = 0;
- total_component_count += get_lig_num_comps (c->buffer->cur());
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
- unsigned int first_lig_id = get_lig_id (c->buffer->cur());
- unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
+ unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
- unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
+ match_positions[i] = skippy_iter.idx;
+
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
if (first_lig_id && first_lig_comp) {
/* If first component was attached to a previous ligature component,
@@ -754,12 +778,11 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
- total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
+ is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
}
- if (end_offset)
- *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+ *end_offset = skippy_iter.idx - buffer->idx + 1;
if (p_is_mark_ligature)
*p_is_mark_ligature = is_mark_ligature;
@@ -770,17 +793,18 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (true);
}
static inline void ligate_input (hb_apply_context_t *c,
- unsigned int count, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int match_length,
hb_codepoint_t lig_glyph,
bool is_mark_ligature,
unsigned int total_component_count)
{
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- if (skippy_iter.has_no_chance ()) return;
+ TRACE_APPLY (NULL);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
@@ -811,44 +835,49 @@ static inline void ligate_input (hb_apply_context_t *c,
*/
unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
- unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer);
- unsigned int last_lig_id = get_lig_id (c->buffer->cur());
- unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
+ unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+ unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
unsigned int components_so_far = last_num_components;
if (!is_mark_ligature)
- set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
- c->replace_glyph (lig_glyph, klass);
+ {
+ _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
+ }
+ }
+ c->replace_glyph_with_ligature (lig_glyph, klass);
for (unsigned int i = 1; i < count; i++)
{
- if (!skippy_iter.next ()) return;
-
- while (c->buffer->idx < skippy_iter.idx)
+ while (buffer->idx < match_positions[i])
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
}
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
- last_lig_id = get_lig_id (c->buffer->cur());
- last_num_components = get_lig_num_comps (c->buffer->cur());
+ last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
components_so_far += last_num_components;
/* Skip the base glyph */
- c->buffer->idx++;
+ buffer->idx++;
}
if (!is_mark_ligature && last_lig_id) {
/* Re-adjust components for any marks following. */
- for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) {
- if (last_lig_id == get_lig_id (c->buffer->info[i])) {
+ for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+ if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
} else
break;
}
@@ -918,102 +947,87 @@ static inline void recurse_lookups (context_t *c,
const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
{
for (unsigned int i = 0; i < lookupCount; i++)
- c->recurse (lookupRecord->lookupListIndex);
+ c->recurse (lookupRecord[i].lookupListIndex);
}
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
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)
{
TRACE_APPLY (NULL);
- unsigned int end = c->buffer->len;
- if (unlikely (count == 0 || c->buffer->idx + count > end))
- return TRACE_RETURN (false);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int end;
- /* TODO We don't support lookupRecord arrays that are not increasing:
- * Should be easy for in_place ones at least. */
-
- /* Note: If sublookup is reverse, it will underflow after the first loop
- * and we jump out of it. Not entirely disastrous. So we don't check
- * for reverse lookup here.
- */
+ /* All positions are distance from beginning of *output* buffer.
+ * Adjust. */
+ {
+ unsigned int bl = buffer->backtrack_len ();
+ end = bl + match_length;
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- uint8_t syllable = c->buffer->cur().syllable();
+ int delta = bl - buffer->idx;
+ /* Convert positions to new indexing. */
+ for (unsigned int j = 0; j < count; j++)
+ match_positions[j] += delta;
+ }
- unsigned int i = 0;
- if (lookupCount && 0 == lookupRecord->sequenceIndex)
+ for (unsigned int i = 0; i < lookupCount; i++)
{
- unsigned int old_pos = c->buffer->idx;
+ unsigned int idx = lookupRecord[i].sequenceIndex;
+ if (idx >= count)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ buffer->move_to (match_positions[idx]);
- lookupRecord++;
- lookupCount--;
- /* Err, this is wrong if the lookup jumped over some glyphs */
- i += c->buffer->idx - old_pos;
+ unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ if (!c->recurse (lookupRecord[i].lookupListIndex))
+ continue;
- if (!done)
- goto not_applied;
- else
- {
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
- }
- else
- {
- not_applied:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
- }
- while (i < count)
- {
- if (!skippy_iter.next ()) return TRACE_RETURN (true);
- while (c->buffer->idx < skippy_iter.idx)
- c->buffer->next_glyph ();
+ unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ int delta = new_len - orig_len;
- if (lookupCount && i == lookupRecord->sequenceIndex)
- {
- unsigned int old_pos = c->buffer->idx;
+ if (!delta)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ /* Recursed lookup changed buffer len. Adjust. */
- lookupRecord++;
- lookupCount--;
- /* Err, this is wrong if the lookup jumped over some glyphs */
- i += c->buffer->idx - old_pos;
+ /* end can't go back past the current match position. */
+ end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
- if (!done)
- goto not_applied2;
- else
- {
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
+ unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
+
+ if (delta > 0)
+ {
+ if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
+ break;
}
else
{
- not_applied2:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
+ /* NOTE: delta is negative. */
+ delta = MAX (delta, (int) next - (int) count);
+ next -= delta;
}
+
+ /* Shift! */
+ memmove (match_positions + next + delta, match_positions + next,
+ (count - next) * sizeof (match_positions[0]));
+ next += delta;
+ count += delta;
+
+ /* Fill in new entries. */
+ for (unsigned int j = idx + 1; j < next; j++)
+ match_positions[j] = match_positions[j - 1] + 1;
+
+ /* And fixup the rest. */
+ for (; next < count; next++)
+ match_positions[next] += delta;
}
+ buffer->move_to (end);
+
return TRACE_RETURN (true);
}
@@ -1085,13 +1099,16 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
{
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data)
+ lookup_context.funcs.match, lookup_context.match_data,
+ &match_length, match_positions)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data,
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct Rule
@@ -1554,7 +1571,7 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
&& intersects_array (c,
inputCount ? inputCount - 1 : 0, input,
lookup_context.funcs.intersects, lookup_context.intersects_data[1])
- && intersects_array (c,
+ && intersects_array (c,
lookaheadCount, lookahead,
lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
recurse_lookups (c,
@@ -1613,22 +1630,23 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int lookahead_offset = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data[1],
- &lookahead_offset)
+ &match_length, match_positions)
&& match_backtrack (c,
backtrackCount, backtrack,
lookup_context.funcs.match, lookup_context.match_data[0])
&& match_lookahead (c,
lookaheadCount, lookahead,
lookup_context.funcs.match, lookup_context.match_data[2],
- lookahead_offset)
+ match_length)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1],
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct ChainRule
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh ('k') | third_party/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698