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 71c13a2e06f562354d5cadc2a07e41e3fe79d37c..41cb93d02492354a866089c5ac42a051b0137873 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 |
@@ -32,6 +32,8 @@ |
#include "hb-ot-layout-gsubgpos-private.hh" |
+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 */ |
@@ -225,7 +227,7 @@ struct AnchorFormat1 |
return TRACE_RETURN (c->check_struct (this)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
SHORT xCoordinate; /* Horizontal value--in design units */ |
SHORT yCoordinate; /* Vertical value--in design units */ |
@@ -247,7 +249,7 @@ struct AnchorFormat2 |
hb_bool_t ret = false; |
if (x_ppem || y_ppem) |
- ret = hb_font_get_glyph_contour_point_for_origin (font, glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); |
+ ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); |
*x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate); |
*y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate); |
} |
@@ -257,7 +259,7 @@ struct AnchorFormat2 |
return TRACE_RETURN (c->check_struct (this)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 2 */ |
SHORT xCoordinate; /* Horizontal value--in design units */ |
SHORT yCoordinate; /* Vertical value--in design units */ |
@@ -288,7 +290,7 @@ struct AnchorFormat3 |
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 3 */ |
SHORT xCoordinate; /* Horizontal value--in design units */ |
SHORT yCoordinate; /* Vertical value--in design units */ |
@@ -329,7 +331,7 @@ struct Anchor |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
AnchorFormat1 format1; |
@@ -360,7 +362,7 @@ struct AnchorMatrix |
} |
USHORT rows; /* Number of rows */ |
- private: |
+ protected: |
OffsetTo<Anchor> |
matrix[VAR]; /* Matrix of offsets to Anchor tables-- |
* from beginning of AnchorMatrix table */ |
@@ -378,7 +380,7 @@ struct MarkRecord |
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); |
} |
- private: |
+ protected: |
USHORT klass; /* Class defined for this mark */ |
OffsetTo<Anchor> |
markAnchor; /* Offset to Anchor table--from |
@@ -429,6 +431,12 @@ struct SinglePosFormat1 |
friend struct SinglePos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -447,7 +455,7 @@ struct SinglePosFormat1 |
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
coverage; /* Offset to Coverage table--from |
@@ -466,6 +474,12 @@ struct SinglePosFormat2 |
friend struct SinglePos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -487,7 +501,7 @@ struct SinglePosFormat2 |
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 2 */ |
OffsetTo<Coverage> |
coverage; /* Offset to Coverage table--from |
@@ -506,6 +520,16 @@ struct SinglePos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ case 2: return u.format2.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -526,7 +550,7 @@ struct SinglePos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
SinglePosFormat1 format1; |
@@ -539,7 +563,7 @@ struct PairValueRecord |
{ |
friend struct PairSet; |
- private: |
+ protected: |
GlyphID secondGlyph; /* GlyphID of second glyph in the |
* pair--first glyph is listed in the |
* Coverage table */ |
@@ -601,7 +625,7 @@ struct PairSet |
&& closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); |
} |
- private: |
+ protected: |
USHORT len; /* Number of PairValueRecords */ |
USHORT array[VAR]; /* Array of PairValueRecords--ordered |
* by GlyphID of the second glyph */ |
@@ -614,6 +638,12 @@ struct PairPosFormat1 |
friend struct PairPos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -643,7 +673,7 @@ struct PairPosFormat1 |
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
coverage; /* Offset to Coverage table--from |
@@ -666,6 +696,12 @@ struct PairPosFormat2 |
friend struct PairPos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -715,7 +751,7 @@ struct PairPosFormat2 |
valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 2 */ |
OffsetTo<Coverage> |
coverage; /* Offset to Coverage table--from |
@@ -750,6 +786,16 @@ struct PairPos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ case 2: return u.format2.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -770,7 +816,7 @@ struct PairPos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
PairPosFormat1 format1; |
@@ -788,7 +834,7 @@ struct EntryExitRecord |
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); |
} |
- private: |
+ protected: |
OffsetTo<Anchor> |
entryAnchor; /* Offset to EntryAnchor table--from |
* beginning of CursivePos |
@@ -806,6 +852,12 @@ struct CursivePosFormat1 |
friend struct CursivePos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -893,7 +945,7 @@ struct CursivePosFormat1 |
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
coverage; /* Offset to Coverage table--from |
@@ -910,6 +962,15 @@ struct CursivePos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -928,7 +989,7 @@ struct CursivePos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
CursivePosFormat1 format1; |
@@ -946,6 +1007,12 @@ struct MarkBasePosFormat1 |
friend struct MarkBasePos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+markCoverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -955,7 +1022,12 @@ struct MarkBasePosFormat1 |
/* now we search backwards for a non-mark glyph */ |
unsigned int property; |
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1); |
- if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false); |
+ do { |
+ if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false); |
+ /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ |
+ if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break; |
+ skippy_iter.reject (); |
+ } while (1); |
/* The following assertion is too strong, so we've disabled it. */ |
if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/} |
@@ -972,7 +1044,7 @@ struct MarkBasePosFormat1 |
markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
markCoverage; /* Offset to MarkCoverage table--from |
@@ -996,6 +1068,15 @@ struct MarkBasePos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1014,7 +1095,7 @@ struct MarkBasePos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
MarkBasePosFormat1 format1; |
@@ -1037,6 +1118,12 @@ struct MarkLigPosFormat1 |
friend struct MarkLigPos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+markCoverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1062,19 +1149,16 @@ struct MarkLigPosFormat1 |
unsigned int comp_count = lig_attach.rows; |
if (unlikely (!comp_count)) return TRACE_RETURN (false); |
- unsigned int comp_index; |
/* 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 |
* can directly use the component index. If not, we attach the mark |
* glyph to the last component of the ligature. */ |
- if (get_lig_id (c->buffer->info[j]) && |
- get_lig_id (c->buffer->cur()) && |
- get_lig_comp (c->buffer->cur()) > 0) |
- { |
- comp_index = get_lig_comp (c->buffer->cur()) - 1; |
- if (comp_index >= comp_count) |
- comp_index = comp_count - 1; |
- } |
+ unsigned int comp_index; |
+ unsigned int lig_id = get_lig_id (c->buffer->info[j]); |
+ unsigned int mark_id = get_lig_id (c->buffer->cur()); |
+ unsigned int mark_comp = get_lig_comp (c->buffer->cur()); |
+ if (lig_id && lig_id == mark_id && mark_comp > 0) |
+ comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1; |
else |
comp_index = comp_count - 1; |
@@ -1087,7 +1171,7 @@ struct MarkLigPosFormat1 |
markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
markCoverage; /* Offset to Mark Coverage table--from |
@@ -1112,6 +1196,15 @@ struct MarkLigPos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1130,7 +1223,7 @@ struct MarkLigPos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
MarkLigPosFormat1 format1; |
@@ -1148,6 +1241,12 @@ struct MarkMarkPosFormat1 |
friend struct MarkMarkPos; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ return this+mark1Coverage; |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1163,14 +1262,27 @@ struct MarkMarkPosFormat1 |
unsigned int j = skippy_iter.idx; |
- /* 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 |
- * if those are non-zero, the ligid number should also match. */ |
- if ((get_lig_comp (c->buffer->cur())) || |
- (get_lig_comp (c->buffer->info[j]) > 0 && |
- get_lig_id (c->buffer->cur()))) |
- return TRACE_RETURN (false); |
+ unsigned int id1 = get_lig_id (c->buffer->cur()); |
+ unsigned int id2 = get_lig_id (c->buffer->info[j]); |
+ unsigned int comp1 = get_lig_comp (c->buffer->cur()); |
+ unsigned int comp2 = get_lig_comp (c->buffer->info[j]); |
+ |
+ if (likely (id1 == id2)) { |
+ if (id1 == 0) /* Marks belonging to the same base. */ |
+ goto good; |
+ else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ |
+ goto good; |
+ } else { |
+ /* If ligature ids don't match, it may be the case that one of the marks |
+ * itself is a ligature. In which case match. */ |
+ if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) |
+ goto good; |
+ } |
+ |
+ /* Didn't match. */ |
+ return TRACE_RETURN (false); |
+ good: |
unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoint); |
if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); |
@@ -1184,7 +1296,7 @@ struct MarkMarkPosFormat1 |
&& mark2Array.sanitize (c, this, (unsigned int) classCount)); |
} |
- private: |
+ protected: |
USHORT format; /* Format identifier--format = 1 */ |
OffsetTo<Coverage> |
mark1Coverage; /* Offset to Combining Mark1 Coverage |
@@ -1210,6 +1322,15 @@ struct MarkMarkPos |
friend struct PosLookupSubTable; |
private: |
+ |
+ inline const Coverage &get_coverage (void) const |
+ { |
+ switch (u.format) { |
+ case 1: return u.format1.get_coverage (); |
+ default:return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1228,7 +1349,7 @@ struct MarkMarkPos |
} |
} |
- private: |
+ protected: |
union { |
USHORT format; /* Format identifier */ |
MarkMarkPosFormat1 format1; |
@@ -1275,6 +1396,8 @@ struct ExtensionPos : Extension |
return StructAtOffset<PosLookupSubTable> (this, offset); |
} |
+ inline const Coverage &get_coverage (void) const; |
+ |
inline bool apply (hb_apply_context_t *c) const; |
inline bool sanitize (hb_sanitize_context_t *c); |
@@ -1303,6 +1426,22 @@ struct PosLookupSubTable |
Extension = 9 |
}; |
+ inline const Coverage &get_coverage (unsigned int lookup_type) const |
+ { |
+ switch (lookup_type) { |
+ case Single: return u.single.get_coverage (); |
+ case Pair: return u.pair.get_coverage (); |
+ case Cursive: return u.cursive.get_coverage (); |
+ case MarkBase: return u.markBase.get_coverage (); |
+ case MarkLig: return u.markLig.get_coverage (); |
+ case MarkMark: return u.markMark.get_coverage (); |
+ case Context: return u.context.get_coverage (); |
+ case ChainContext: return u.chainContext.get_coverage (); |
+ case Extension: return u.extension.get_coverage (); |
+ default: return Null(Coverage); |
+ } |
+ } |
+ |
inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const |
{ |
TRACE_APPLY (); |
@@ -1313,7 +1452,7 @@ struct PosLookupSubTable |
case MarkBase: return TRACE_RETURN (u.markBase.apply (c)); |
case MarkLig: return TRACE_RETURN (u.markLig.apply (c)); |
case MarkMark: return TRACE_RETURN (u.markMark.apply (c)); |
- case Context: return TRACE_RETURN (u.c.apply (c)); |
+ case Context: return TRACE_RETURN (u.context.apply (c)); |
case ChainContext: return TRACE_RETURN (u.chainContext.apply (c)); |
case Extension: return TRACE_RETURN (u.extension.apply (c)); |
default: return TRACE_RETURN (false); |
@@ -1322,6 +1461,8 @@ struct PosLookupSubTable |
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { |
TRACE_SANITIZE (); |
+ if (!u.header.sub_format.sanitize (c)) |
+ return TRACE_RETURN (false); |
switch (lookup_type) { |
case Single: return TRACE_RETURN (u.single.sanitize (c)); |
case Pair: return TRACE_RETURN (u.pair.sanitize (c)); |
@@ -1329,28 +1470,30 @@ struct PosLookupSubTable |
case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); |
case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); |
case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); |
- case Context: return TRACE_RETURN (u.c.sanitize (c)); |
+ case Context: return TRACE_RETURN (u.context.sanitize (c)); |
case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); |
case Extension: return TRACE_RETURN (u.extension.sanitize (c)); |
default: return TRACE_RETURN (true); |
} |
} |
- private: |
+ protected: |
union { |
- USHORT sub_format; |
+ struct { |
+ USHORT sub_format; |
+ } header; |
SinglePos single; |
PairPos pair; |
CursivePos cursive; |
MarkBasePos markBase; |
MarkLigPos markLig; |
MarkMarkPos markMark; |
- ContextPos c; |
+ ContextPos context; |
ChainContextPos chainContext; |
ExtensionPos extension; |
} u; |
public: |
- DEFINE_SIZE_UNION (2, sub_format); |
+ DEFINE_SIZE_UNION (2, header.sub_format); |
}; |
@@ -1359,33 +1502,51 @@ struct PosLookup : Lookup |
inline const PosLookupSubTable& get_subtable (unsigned int i) const |
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } |
+ template <typename set_t> |
+ inline void add_coverage (set_t *glyphs) const |
+ { |
+ const Coverage *last = NULL; |
+ unsigned int count = get_subtable_count (); |
+ for (unsigned int i = 0; i < count; i++) { |
+ const Coverage *c = &get_subtable (i).get_coverage (get_type ()); |
+ if (c != last) { |
+ c->add_coverage (glyphs); |
+ last = c; |
+ } |
+ } |
+ } |
+ |
inline bool apply_once (hb_apply_context_t *c) const |
{ |
unsigned int lookup_type = get_type (); |
- if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), c->lookup_props, &c->property)) |
+ if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property)) |
return false; |
- for (unsigned int i = 0; i < get_subtable_count (); i++) |
+ unsigned int count = get_subtable_count (); |
+ for (unsigned int i = 0; i < count; i++) |
if (get_subtable (i).apply (c, lookup_type)) |
return true; |
return false; |
} |
- inline bool apply_string (hb_apply_context_t *c) const |
+ inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const |
{ |
bool ret = false; |
- if (unlikely (!c->buffer->len)) |
+ if (unlikely (!c->buffer->len || !c->lookup_mask)) |
return false; |
c->set_lookup (*this); |
c->buffer->idx = 0; |
+ |
while (c->buffer->idx < c->buffer->len) |
{ |
- if ((c->buffer->cur().mask & c->lookup_mask) && apply_once (c)) |
+ if ((c->buffer->cur().mask & c->lookup_mask) && |
+ digest->may_have (c->buffer->cur().codepoint) && |
+ apply_once (c)) |
ret = true; |
else |
c->buffer->idx++; |
@@ -1415,11 +1576,12 @@ struct GPOS : GSUBGPOS |
inline const PosLookup& get_lookup (unsigned int i) const |
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
- inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const |
- { return get_lookup (lookup_index).apply_string (c); } |
+ template <typename set_t> |
+ inline void add_coverage (set_t *glyphs, unsigned int lookup_index) const |
+ { get_lookup (lookup_index).add_coverage (glyphs); } |
- static inline void position_start (hb_buffer_t *buffer); |
- static inline void position_finish (hb_buffer_t *buffer); |
+ 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, hb_bool_t zero_width_attahced_marks); |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
@@ -1435,32 +1597,34 @@ struct GPOS : GSUBGPOS |
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(); |
- if (likely (!j)) |
- return; |
+ unsigned int j = pos[i].cursive_chain(); |
+ if (likely (!j)) |
+ return; |
- j += i; |
+ j += i; |
- pos[i].cursive_chain() = 0; |
+ pos[i].cursive_chain() = 0; |
- fix_cursive_minor_offset (pos, j, direction); |
+ 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; |
+ if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
+ pos[i].y_offset += pos[j].y_offset; |
+ else |
+ pos[i].x_offset += pos[j].x_offset; |
} |
static void |
-fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) |
+fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, hb_bool_t zero_width_attached_marks) |
{ |
if (likely (!(pos[i].attach_lookback()))) |
return; |
unsigned int j = i - pos[i].attach_lookback(); |
- pos[i].x_advance = 0; |
- pos[i].y_advance = 0; |
+ if (zero_width_attached_marks) { |
+ pos[i].x_advance = 0; |
+ pos[i].y_advance = 0; |
+ } |
pos[i].x_offset += pos[j].x_offset; |
pos[i].y_offset += pos[j].y_offset; |
@@ -1477,7 +1641,7 @@ fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di |
} |
void |
-GPOS::position_start (hb_buffer_t *buffer) |
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
{ |
buffer->clear_positions (); |
@@ -1487,7 +1651,7 @@ GPOS::position_start (hb_buffer_t *buffer) |
} |
void |
-GPOS::position_finish (hb_buffer_t *buffer) |
+GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks) |
{ |
unsigned int len; |
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); |
@@ -1499,16 +1663,21 @@ GPOS::position_finish (hb_buffer_t *buffer) |
/* Handle attachments */ |
for (unsigned int i = 0; i < len; i++) |
- fix_mark_attachment (pos, i, direction); |
+ fix_mark_attachment (pos, i, direction, zero_width_attached_marks); |
HB_BUFFER_DEALLOCATE_VAR (buffer, syllable); |
HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props); |
- HB_BUFFER_DEALLOCATE_VAR (buffer, props_cache); |
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props); |
} |
/* Out-of-class implementation for methods recursing */ |
+inline const Coverage & ExtensionPos::get_coverage (void) const |
+{ |
+ return get_subtable ().get_coverage (get_type ()); |
+} |
+ |
inline bool ExtensionPos::apply (hb_apply_context_t *c) const |
{ |
TRACE_APPLY (); |
@@ -1526,7 +1695,7 @@ inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c) |
static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) |
{ |
- const GPOS &gpos = *(c->face->ot_layout->gpos); |
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
const PosLookup &l = gpos.get_lookup (lookup_index); |
if (unlikely (c->nesting_level_left == 0)) |
@@ -1543,5 +1712,7 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i |
#undef cursive_chain |
+} // namespace OT |
+ |
#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |