Index: third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh |
index 5ea70fbbdec8658e01f3f2fc4c406ce4624112a4..bbe390cf7d2f10de4e66cc27cdf621a7ade61545 100644 |
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh |
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh |
@@ -36,8 +36,17 @@ namespace OT { |
/* buffer **position** var allocations */ |
-#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */ |
-#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */ |
+#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */ |
+#define attach_type() var.u8[2] /* attachment type */ |
+/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */ |
+ |
+enum attach_type_t { |
+ ATTACH_TYPE_NONE = 0X00, |
+ |
+ /* Each attachment should be either a mark or a cursive; can't be both. */ |
+ ATTACH_TYPE_MARK = 0X01, |
+ ATTACH_TYPE_CURSIVE = 0X02, |
+}; |
/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ |
@@ -425,7 +434,8 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde |
hb_glyph_position_t &o = buffer->cur_pos(); |
o.x_offset = base_x - mark_x; |
o.y_offset = base_y - mark_y; |
- o.attach_lookback() = buffer->idx - glyph_pos; |
+ o.attach_type() = ATTACH_TYPE_MARK; |
+ o.attach_chain() = (int) glyph_pos - (int) buffer->idx; |
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; |
buffer->idx++; |
@@ -907,9 +917,6 @@ struct CursivePosFormat1 |
TRACE_APPLY (this); |
hb_buffer_t *buffer = c->buffer; |
- /* We don't handle mark glyphs here. */ |
- if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false); |
- |
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; |
if (!this_record.exitAnchor) return_trace (false); |
@@ -993,8 +1000,9 @@ struct CursivePosFormat1 |
*/ |
reverse_cursive_minor_offset (pos, child, c->direction, parent); |
- pos[child].cursive_chain() = parent - child; |
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE; |
+ pos[child].attach_type() = ATTACH_TYPE_CURSIVE; |
+ pos[child].attach_chain() = (int) parent - (int) child; |
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; |
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) |
pos[child].y_offset = y_offset; |
else |
@@ -1069,7 +1077,7 @@ struct MarkBasePosFormat1 |
unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); |
if (likely (mark_index == NOT_COVERED)) return_trace (false); |
- /* now we search backwards for a non-mark glyph */ |
+ /* Now we search backwards for a non-mark glyph */ |
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
skippy_iter.reset (buffer->idx, 1); |
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
@@ -1081,7 +1089,7 @@ struct MarkBasePosFormat1 |
} while (1); |
/* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ |
- if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } |
+ //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); } |
unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); |
if (base_index == NOT_COVERED) return_trace (false); |
@@ -1170,14 +1178,14 @@ struct MarkLigPosFormat1 |
unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); |
if (likely (mark_index == NOT_COVERED)) return_trace (false); |
- /* now we search backwards for a non-mark glyph */ |
+ /* Now we search backwards for a non-mark glyph */ |
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
skippy_iter.reset (buffer->idx, 1); |
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
if (!skippy_iter.prev ()) return_trace (false); |
/* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ |
- if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } |
+ //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); } |
unsigned int j = skippy_iter.idx; |
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); |
@@ -1501,7 +1509,8 @@ struct GPOS : GSUBGPOS |
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); |
- static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); |
+ static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); |
+ static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); |
inline bool sanitize (hb_sanitize_context_t *c) const |
{ |
@@ -1518,13 +1527,13 @@ struct GPOS : GSUBGPOS |
static void |
reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) |
{ |
- unsigned int j = pos[i].cursive_chain(); |
- if (likely (!j)) |
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type(); |
+ if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) |
return; |
- j += i; |
+ pos[i].attach_chain() = 0; |
- pos[i].cursive_chain() = 0; |
+ unsigned int j = (int) i + chain; |
/* Stop if we see new parent in the chain. */ |
if (j == new_parent) |
@@ -1537,62 +1546,68 @@ reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc |
else |
pos[j].x_offset = -pos[i].x_offset; |
- pos[j].cursive_chain() = i - j; |
+ pos[j].attach_chain() = -chain; |
+ pos[j].attach_type() = type; |
} |
static void |
-fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) |
+propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) |
{ |
- unsigned int j = pos[i].cursive_chain(); |
- if (likely (!j)) |
+ /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate |
+ * offset of glyph they are attached to. */ |
+ int chain = pos[i].attach_chain(), type = pos[i].attach_type(); |
+ if (likely (!chain)) |
return; |
- j += i; |
+ unsigned int j = (int) i + chain; |
- pos[i].cursive_chain() = 0; |
- |
- fix_cursive_minor_offset (pos, j, direction); |
- |
- if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
- pos[i].y_offset += pos[j].y_offset; |
- else |
- pos[i].x_offset += pos[j].x_offset; |
-} |
+ pos[i].attach_chain() = 0; |
-static void |
-fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) |
-{ |
- if (likely (!(pos[i].attach_lookback()))) |
- return; |
+ propagate_attachment_offsets (pos, j, direction); |
- unsigned int j = i - pos[i].attach_lookback(); |
+ assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); |
- pos[i].x_offset += pos[j].x_offset; |
- pos[i].y_offset += pos[j].y_offset; |
+ if (type & ATTACH_TYPE_CURSIVE) |
+ { |
+ if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
+ pos[i].y_offset += pos[j].y_offset; |
+ else |
+ pos[i].x_offset += pos[j].x_offset; |
+ } |
+ else /*if (type & ATTACH_TYPE_MARK)*/ |
+ { |
+ pos[i].x_offset += pos[j].x_offset; |
+ pos[i].y_offset += pos[j].y_offset; |
- if (HB_DIRECTION_IS_FORWARD (direction)) |
- for (unsigned int k = j; k < i; k++) { |
- pos[i].x_offset -= pos[k].x_advance; |
- pos[i].y_offset -= pos[k].y_advance; |
- } |
- else |
- for (unsigned int k = j + 1; k < i + 1; k++) { |
- pos[i].x_offset += pos[k].x_advance; |
- pos[i].y_offset += pos[k].y_advance; |
- } |
+ assert (j < i); |
+ if (HB_DIRECTION_IS_FORWARD (direction)) |
+ for (unsigned int k = j; k < i; k++) { |
+ pos[i].x_offset -= pos[k].x_advance; |
+ pos[i].y_offset -= pos[k].y_advance; |
+ } |
+ else |
+ for (unsigned int k = j + 1; k < i + 1; k++) { |
+ pos[i].x_offset += pos[k].x_advance; |
+ pos[i].y_offset += pos[k].y_advance; |
+ } |
+ } |
} |
void |
GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
{ |
- buffer->clear_positions (); |
- |
unsigned int count = buffer->len; |
for (unsigned int i = 0; i < count; i++) |
- buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; |
+ buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; |
+} |
+ |
+void |
+GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
+{ |
+ //_hb_buffer_assert_gsubgpos_vars (buffer); |
} |
void |
-GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
+GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
{ |
_hb_buffer_assert_gsubgpos_vars (buffer); |
@@ -1600,15 +1615,10 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); |
hb_direction_t direction = buffer->props.direction; |
- /* Handle cursive connections */ |
- if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE) |
- for (unsigned int i = 0; i < len; i++) |
- fix_cursive_minor_offset (pos, i, direction); |
- |
/* Handle attachments */ |
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) |
for (unsigned int i = 0; i < len; i++) |
- fix_mark_attachment (pos, i, direction); |
+ propagate_attachment_offsets (pos, i, direction); |
} |
@@ -1637,8 +1647,8 @@ template <typename context_t> |
} |
-#undef attach_lookback |
-#undef cursive_chain |
+#undef attach_chain |
+#undef attach_type |
} /* namespace OT */ |