diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh | 331 |
1 files changed, 194 insertions, 137 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index d88f7876e0..568b5f63a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -181,7 +181,7 @@ struct ValueFormat : USHORT inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); + return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); } inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const @@ -189,17 +189,17 @@ struct ValueFormat : USHORT TRACE_SANITIZE (this); unsigned int len = get_len (); - if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false); + if (!c->check_array (values, get_size (), count)) return_trace (false); - if (!has_device ()) return TRACE_RETURN (true); + if (!has_device ()) return_trace (true); for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return TRACE_RETURN (false); + return_trace (false); values += len; } - return TRACE_RETURN (true); + return_trace (true); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ @@ -207,15 +207,15 @@ struct ValueFormat : USHORT { TRACE_SANITIZE (this); - if (!has_device ()) return TRACE_RETURN (true); + if (!has_device ()) return_trace (true); for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return TRACE_RETURN (false); + return_trace (false); values += stride; } - return TRACE_RETURN (true); + return_trace (true); } }; @@ -232,7 +232,7 @@ struct AnchorFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -262,7 +262,7 @@ struct AnchorFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -291,7 +291,7 @@ struct AnchorFormat3 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); + return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); } protected: @@ -327,12 +327,12 @@ struct Anchor inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (true); } } @@ -360,13 +360,13 @@ struct AnchorMatrix inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const { TRACE_SANITIZE (this); - if (!c->check_struct (this)) return TRACE_RETURN (false); - if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); + if (!c->check_struct (this)) return_trace (false); + if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false); unsigned int count = rows * cols; - if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_RETURN (false); + if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (!matrixZ[i].sanitize (c, this)) return_trace (false); + return_trace (true); } USHORT rows; /* Number of rows */ @@ -386,7 +386,7 @@ struct MarkRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); + return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } protected: @@ -415,7 +415,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); /* If this subtable doesn't have an anchor for this base and this class, * return false such that the subsequent subtables have a chance at it. */ - if (unlikely (!found)) return TRACE_RETURN (false); + if (unlikely (!found)) return_trace (false); hb_position_t mark_x, mark_y, base_x, base_y; @@ -428,13 +428,13 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde o.attach_lookback() = buffer->idx - glyph_pos; buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); + return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); } }; @@ -459,21 +459,21 @@ struct SinglePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); valueFormat.apply_value (c->font, c->direction, this, values, buffer->cur_pos()); buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) - && coverage.sanitize (c, this) - && valueFormat.sanitize_value (c, this, values)); + return_trace (c->check_struct (this) && + coverage.sanitize (c, this) && + valueFormat.sanitize_value (c, this, values)); } protected: @@ -508,24 +508,24 @@ struct SinglePosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); - if (likely (index >= valueCount)) return TRACE_RETURN (false); + if (likely (index >= valueCount)) return_trace (false); valueFormat.apply_value (c->font, c->direction, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) - && coverage.sanitize (c, this) - && valueFormat.sanitize_values (c, this, values, valueCount)); + return_trace (c->check_struct (this) && + coverage.sanitize (c, this) && + valueFormat.sanitize_values (c, this, values, valueCount)); } protected: @@ -548,11 +548,11 @@ struct SinglePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + default:return_trace (c->default_return_value ()); } } @@ -615,7 +615,7 @@ struct PairSet /* Hand-coded bsearch. */ if (unlikely (!count)) - return TRACE_RETURN (false); + return_trace (false); hb_codepoint_t x = buffer->info[pos].codepoint; int min = 0, max = (int) count - 1; while (min <= max) @@ -636,11 +636,11 @@ struct PairSet if (len2) pos++; buffer->idx = pos; - return TRACE_RETURN (true); + return_trace (true); } } - return TRACE_RETURN (false); + return_trace (false); } struct sanitize_closure_t { @@ -654,12 +654,12 @@ struct PairSet { TRACE_SANITIZE (this); if (!(c->check_struct (this) - && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); + && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false); unsigned int count = len; const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); - return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) - && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); + return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); } protected: @@ -691,19 +691,21 @@ struct PairPosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); - return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); + return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + if (!c->check_struct (this)) return_trace (false); + unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); PairSet::sanitize_closure_t closure = { @@ -713,7 +715,7 @@ struct PairPosFormat1 1 + len1 + len2 }; - return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); + return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); } protected: @@ -762,11 +764,11 @@ struct PairPosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); @@ -774,7 +776,7 @@ struct PairPosFormat2 unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); - if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false); + if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; valueFormat1.apply_value (c->font, c->direction, this, @@ -786,7 +788,7 @@ struct PairPosFormat2 if (len2) buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -795,16 +797,16 @@ struct PairPosFormat2 if (!(c->check_struct (this) && coverage.sanitize (c, this) && classDef1.sanitize (c, this) - && classDef2.sanitize (c, this))) return TRACE_RETURN (false); + && classDef2.sanitize (c, this))) return_trace (false); unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); unsigned int stride = len1 + len2; unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; - return TRACE_RETURN (c->check_array (values, record_size, count) && - valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && - valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); + return_trace (c->check_array (values, record_size, count) && + valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && + valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); } protected: @@ -843,11 +845,11 @@ struct PairPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + default:return_trace (c->default_return_value ()); } } @@ -867,7 +869,7 @@ struct EntryExitRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); + return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } protected: @@ -883,6 +885,9 @@ struct EntryExitRecord DEFINE_SIZE_STATIC (4); }; +static void +reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent); + struct CursivePosFormat1 { inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -902,17 +907,17 @@ struct CursivePosFormat1 hb_buffer_t *buffer = c->buffer; /* We don't handle mark glyphs here. */ - if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); + 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_RETURN (false); + if (!this_record.exitAnchor) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; - if (!next_record.entryAnchor) return TRACE_RETURN (false); + if (!next_record.entryAnchor) return_trace (false); unsigned int i = buffer->idx; unsigned int j = skippy_iter.idx; @@ -960,28 +965,47 @@ struct CursivePosFormat1 } /* Cross-direction adjustment */ - if (c->lookup_props & LookupFlag::RightToLeft) { - pos[i].cursive_chain() = j - i; - if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) - pos[i].y_offset = entry_y - exit_y; - else - pos[i].x_offset = entry_x - exit_x; - } else { - pos[j].cursive_chain() = i - j; - if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) - pos[j].y_offset = exit_y - entry_y; - else - pos[j].x_offset = exit_x - entry_x; + + /* We attach child to parent (think graph theory and rooted trees whereas + * the root stays on baseline and each node aligns itself against its + * parent. + * + * Optimize things for the case of RightToLeft, as that's most common in + * Arabinc. */ + unsigned int child = i; + unsigned int parent = j; + hb_position_t x_offset = entry_x - exit_x; + hb_position_t y_offset = entry_y - exit_y; + if (!(c->lookup_props & LookupFlag::RightToLeft)) + { + unsigned int k = child; + child = parent; + parent = k; + x_offset = -x_offset; + y_offset = -y_offset; } + /* If child was already connected to someone else, walk through its old + * chain and reverse the link direction, such that the whole tree of its + * previous connection now attaches to new parent. Watch out for case + * where new parent is on the path from old chain... + */ + reverse_cursive_minor_offset (pos, child, c->direction, parent); + + pos[child].cursive_chain() = parent - child; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[child].y_offset = y_offset; + else + pos[child].x_offset = x_offset; + buffer->idx = j; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); } protected: @@ -1002,10 +1026,10 @@ struct CursivePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1041,33 +1065,36 @@ struct MarkBasePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); - if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (mark_index == NOT_COVERED)) return_trace (false); /* 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); do { - if (!skippy_iter.prev ()) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return_trace (false); /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; skippy_iter.reject (); } 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_RETURN (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_RETURN (false); + if (base_index == NOT_COVERED) return_trace (false); - return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); + return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && - markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + markCoverage.sanitize (c, this) && + baseCoverage.sanitize (c, this) && + markArray.sanitize (c, this) && + baseArray.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1095,10 +1122,10 @@ struct MarkBasePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1139,27 +1166,27 @@ struct MarkLigPosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); - if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (mark_index == NOT_COVERED)) return_trace (false); /* 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_RETURN (false); + 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_RETURN (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); - if (lig_index == NOT_COVERED) return TRACE_RETURN (false); + if (lig_index == NOT_COVERED) return_trace (false); const LigatureArray& lig_array = this+ligatureArray; const LigatureAttach& lig_attach = lig_array[lig_index]; /* Find component to attach to */ unsigned int comp_count = lig_attach.rows; - if (unlikely (!comp_count)) return TRACE_RETURN (false); + if (unlikely (!comp_count)) return_trace (false); /* We must now check whether the ligature ID of the current mark glyph * is identical to the ligature ID of the found ligature. If yes, we @@ -1174,14 +1201,17 @@ struct MarkLigPosFormat1 else comp_index = comp_count - 1; - return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); + return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && - markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + markCoverage.sanitize (c, this) && + ligatureCoverage.sanitize (c, this) && + markArray.sanitize (c, this) && + ligatureArray.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1210,10 +1240,10 @@ struct MarkLigPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1249,15 +1279,15 @@ struct MarkMarkPosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); - if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until 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 (c->lookup_props & ~LookupFlag::IgnoreFlags); - if (!skippy_iter.prev ()) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return_trace (false); - if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } + if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int j = skippy_iter.idx; @@ -1279,21 +1309,23 @@ struct MarkMarkPosFormat1 } /* Didn't match. */ - return TRACE_RETURN (false); + return_trace (false); good: unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); - if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); + if (mark2_index == NOT_COVERED) return_trace (false); - return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); + return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && - mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) - && mark2Array.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + mark1Coverage.sanitize (c, this) && + mark2Coverage.sanitize (c, this) && + mark1Array.sanitize (c, this) && + mark2Array.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1323,10 +1355,10 @@ struct MarkMarkPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1374,19 +1406,18 @@ struct PosLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); - /* The sub_format passed to may_dispatch is unnecessary but harmless. */ - if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ()); switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.dispatch (c)); - case Pair: return TRACE_RETURN (u.pair.dispatch (c)); - case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); - case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); - case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); - case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); - case Context: return TRACE_RETURN (u.context.dispatch (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); - case Extension: return TRACE_RETURN (u.extension.dispatch (c)); - default: return TRACE_RETURN (c->default_return_value ()); + case Single: return_trace (u.single.dispatch (c)); + case Pair: return_trace (u.pair.dispatch (c)); + case Cursive: return_trace (u.cursive.dispatch (c)); + case MarkBase: return_trace (u.markBase.dispatch (c)); + case MarkLig: return_trace (u.markLig.dispatch (c)); + case MarkMark: return_trace (u.markMark.dispatch (c)); + case Context: return_trace (u.context.dispatch (c)); + case ChainContext: return_trace (u.chainContext.dispatch (c)); + case Extension: return_trace (u.extension.dispatch (c)); + default: return_trace (c->default_return_value ()); } } @@ -1421,13 +1452,13 @@ struct PosLookup : Lookup inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } template <typename set_t> @@ -1449,9 +1480,8 @@ struct PosLookup : Lookup inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTable> (); - return TRACE_RETURN (dispatch (c)); + if (unlikely (!Lookup::sanitize (c))) return_trace (false); + return_trace (dispatch (c)); } }; @@ -1474,9 +1504,9 @@ struct GPOS : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); - return TRACE_RETURN (list.sanitize (c, this)); + return_trace (list.sanitize (c, this)); } public: DEFINE_SIZE_STATIC (10); @@ -1484,6 +1514,30 @@ 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)) + return; + + j += i; + + pos[i].cursive_chain() = 0; + + /* Stop if we see new parent in the chain. */ + if (j == new_parent) + return; + + reverse_cursive_minor_offset (pos, j, direction, new_parent); + + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + pos[j].y_offset = -pos[i].y_offset; + else + pos[j].x_offset = -pos[i].x_offset; + + pos[j].cursive_chain() = i - j; +} +static void fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) { unsigned int j = pos[i].cursive_chain(); @@ -1569,8 +1623,11 @@ template <typename context_t> const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); const PosLookup &l = gpos.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; - c->set_lookup (l); + unsigned int saved_lookup_index = c->lookup_index; + c->set_lookup_index (lookup_index); + c->set_lookup_props (l.get_props ()); bool ret = l.dispatch (c); + c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); return ret; } |