| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
| 3 * Copyright © 2010,2012,2013 Google, Inc. | 3 * Copyright © 2010,2012,2013 Google, Inc. |
| 4 * | 4 * |
| 5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
| 6 * | 6 * |
| 7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
| 8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
| 9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
| 10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH | 29 #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH |
| 30 #define HB_OT_LAYOUT_GPOS_TABLE_HH | 30 #define HB_OT_LAYOUT_GPOS_TABLE_HH |
| 31 | 31 |
| 32 #include "hb-ot-layout-gsubgpos-private.hh" | 32 #include "hb-ot-layout-gsubgpos-private.hh" |
| 33 | 33 |
| 34 | 34 |
| 35 namespace OT { | 35 namespace OT { |
| 36 | 36 |
| 37 | 37 |
| 38 /* buffer **position** var allocations */ | 38 /* buffer **position** var allocations */ |
| 39 #define attach_lookback() var.u16[0] /* number of glyphs to go back to attach th
is glyph to its base */ | 39 #define attach_chain() var.i16[0] /* glyph to which this attaches to, relative t
o current glyphs; negative for going back, positive for forward. */ |
| 40 #define cursive_chain() var.i16[1] /* character to which this connects, may be p
ositive or negative */ | 40 #define attach_type() var.u8[2] /* attachment type */ |
| 41 /* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */ |
| 42 |
| 43 enum attach_type_t { |
| 44 ATTACH_TYPE_NONE» = 0X00, |
| 45 |
| 46 /* Each attachment should be either a mark or a cursive; can't be both. */ |
| 47 ATTACH_TYPE_MARK» = 0X01, |
| 48 ATTACH_TYPE_CURSIVE» = 0X02, |
| 49 }; |
| 41 | 50 |
| 42 | 51 |
| 43 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ | 52 /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ |
| 44 | 53 |
| 45 typedef USHORT Value; | 54 typedef USHORT Value; |
| 46 | 55 |
| 47 typedef Value ValueRecord[VAR]; | 56 typedef Value ValueRecord[VAR]; |
| 48 | 57 |
| 49 struct ValueFormat : USHORT | 58 struct ValueFormat : USHORT |
| 50 { | 59 { |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 if (unlikely (!found)) return_trace (false); | 427 if (unlikely (!found)) return_trace (false); |
| 419 | 428 |
| 420 hb_position_t mark_x, mark_y, base_x, base_y; | 429 hb_position_t mark_x, mark_y, base_x, base_y; |
| 421 | 430 |
| 422 mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); | 431 mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); |
| 423 glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x
, &base_y); | 432 glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x
, &base_y); |
| 424 | 433 |
| 425 hb_glyph_position_t &o = buffer->cur_pos(); | 434 hb_glyph_position_t &o = buffer->cur_pos(); |
| 426 o.x_offset = base_x - mark_x; | 435 o.x_offset = base_x - mark_x; |
| 427 o.y_offset = base_y - mark_y; | 436 o.y_offset = base_y - mark_y; |
| 428 o.attach_lookback() = buffer->idx - glyph_pos; | 437 o.attach_type() = ATTACH_TYPE_MARK; |
| 438 o.attach_chain() = (int) glyph_pos - (int) buffer->idx; |
| 429 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; | 439 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; |
| 430 | 440 |
| 431 buffer->idx++; | 441 buffer->idx++; |
| 432 return_trace (true); | 442 return_trace (true); |
| 433 } | 443 } |
| 434 | 444 |
| 435 inline bool sanitize (hb_sanitize_context_t *c) const | 445 inline bool sanitize (hb_sanitize_context_t *c) const |
| 436 { | 446 { |
| 437 TRACE_SANITIZE (this); | 447 TRACE_SANITIZE (this); |
| 438 return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); | 448 return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 inline const Coverage &get_coverage (void) const | 910 inline const Coverage &get_coverage (void) const |
| 901 { | 911 { |
| 902 return this+coverage; | 912 return this+coverage; |
| 903 } | 913 } |
| 904 | 914 |
| 905 inline bool apply (hb_apply_context_t *c) const | 915 inline bool apply (hb_apply_context_t *c) const |
| 906 { | 916 { |
| 907 TRACE_APPLY (this); | 917 TRACE_APPLY (this); |
| 908 hb_buffer_t *buffer = c->buffer; | 918 hb_buffer_t *buffer = c->buffer; |
| 909 | 919 |
| 910 /* We don't handle mark glyphs here. */ | |
| 911 if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false)
; | |
| 912 | |
| 913 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->cur().codepoint)]; | 920 const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->cur().codepoint)]; |
| 914 if (!this_record.exitAnchor) return_trace (false); | 921 if (!this_record.exitAnchor) return_trace (false); |
| 915 | 922 |
| 916 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; | 923 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 917 skippy_iter.reset (buffer->idx, 1); | 924 skippy_iter.reset (buffer->idx, 1); |
| 918 if (!skippy_iter.next ()) return_trace (false); | 925 if (!skippy_iter.next ()) return_trace (false); |
| 919 | 926 |
| 920 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; | 927 const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_cov
erage (buffer->info[skippy_iter.idx].codepoint)]; |
| 921 if (!next_record.entryAnchor) return_trace (false); | 928 if (!next_record.entryAnchor) return_trace (false); |
| 922 | 929 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 y_offset = -y_offset; | 993 y_offset = -y_offset; |
| 987 } | 994 } |
| 988 | 995 |
| 989 /* If child was already connected to someone else, walk through its old | 996 /* If child was already connected to someone else, walk through its old |
| 990 * chain and reverse the link direction, such that the whole tree of its | 997 * chain and reverse the link direction, such that the whole tree of its |
| 991 * previous connection now attaches to new parent. Watch out for case | 998 * previous connection now attaches to new parent. Watch out for case |
| 992 * where new parent is on the path from old chain... | 999 * where new parent is on the path from old chain... |
| 993 */ | 1000 */ |
| 994 reverse_cursive_minor_offset (pos, child, c->direction, parent); | 1001 reverse_cursive_minor_offset (pos, child, c->direction, parent); |
| 995 | 1002 |
| 996 pos[child].cursive_chain() = parent - child; | 1003 pos[child].attach_type() = ATTACH_TYPE_CURSIVE; |
| 997 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE; | 1004 pos[child].attach_chain() = (int) parent - (int) child; |
| 1005 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; |
| 998 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) | 1006 if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) |
| 999 pos[child].y_offset = y_offset; | 1007 pos[child].y_offset = y_offset; |
| 1000 else | 1008 else |
| 1001 pos[child].x_offset = x_offset; | 1009 pos[child].x_offset = x_offset; |
| 1002 | 1010 |
| 1003 buffer->idx = j; | 1011 buffer->idx = j; |
| 1004 return_trace (true); | 1012 return_trace (true); |
| 1005 } | 1013 } |
| 1006 | 1014 |
| 1007 inline bool sanitize (hb_sanitize_context_t *c) const | 1015 inline bool sanitize (hb_sanitize_context_t *c) const |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 return this+markCoverage; | 1070 return this+markCoverage; |
| 1063 } | 1071 } |
| 1064 | 1072 |
| 1065 inline bool apply (hb_apply_context_t *c) const | 1073 inline bool apply (hb_apply_context_t *c) const |
| 1066 { | 1074 { |
| 1067 TRACE_APPLY (this); | 1075 TRACE_APPLY (this); |
| 1068 hb_buffer_t *buffer = c->buffer; | 1076 hb_buffer_t *buffer = c->buffer; |
| 1069 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); | 1077 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); |
| 1070 if (likely (mark_index == NOT_COVERED)) return_trace (false); | 1078 if (likely (mark_index == NOT_COVERED)) return_trace (false); |
| 1071 | 1079 |
| 1072 /* now we search backwards for a non-mark glyph */ | 1080 /* Now we search backwards for a non-mark glyph */ |
| 1073 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; | 1081 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 1074 skippy_iter.reset (buffer->idx, 1); | 1082 skippy_iter.reset (buffer->idx, 1); |
| 1075 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); | 1083 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
| 1076 do { | 1084 do { |
| 1077 if (!skippy_iter.prev ()) return_trace (false); | 1085 if (!skippy_iter.prev ()) return_trace (false); |
| 1078 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ | 1086 /* We only want to attach to the first of a MultipleSubst sequence. Rejec
t others. */ |
| 1079 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre
ak; | 1087 if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) bre
ak; |
| 1080 skippy_iter.reject (); | 1088 skippy_iter.reject (); |
| 1081 } while (1); | 1089 } while (1); |
| 1082 | 1090 |
| 1083 /* Checking that matched glyph is actually a base glyph by GDEF is too stron
g; disabled */ | 1091 /* Checking that matched glyph is actually a base glyph by GDEF is too stron
g; disabled */ |
| 1084 if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*retu
rn_trace (false);*/ } | 1092 //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { retu
rn_trace (false); } |
| 1085 | 1093 |
| 1086 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk
ippy_iter.idx].codepoint); | 1094 unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[sk
ippy_iter.idx].codepoint); |
| 1087 if (base_index == NOT_COVERED) return_trace (false); | 1095 if (base_index == NOT_COVERED) return_trace (false); |
| 1088 | 1096 |
| 1089 return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseAr
ray, classCount, skippy_iter.idx)); | 1097 return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseAr
ray, classCount, skippy_iter.idx)); |
| 1090 } | 1098 } |
| 1091 | 1099 |
| 1092 inline bool sanitize (hb_sanitize_context_t *c) const | 1100 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1093 { | 1101 { |
| 1094 TRACE_SANITIZE (this); | 1102 TRACE_SANITIZE (this); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 return this+markCoverage; | 1171 return this+markCoverage; |
| 1164 } | 1172 } |
| 1165 | 1173 |
| 1166 inline bool apply (hb_apply_context_t *c) const | 1174 inline bool apply (hb_apply_context_t *c) const |
| 1167 { | 1175 { |
| 1168 TRACE_APPLY (this); | 1176 TRACE_APPLY (this); |
| 1169 hb_buffer_t *buffer = c->buffer; | 1177 hb_buffer_t *buffer = c->buffer; |
| 1170 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); | 1178 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().c
odepoint); |
| 1171 if (likely (mark_index == NOT_COVERED)) return_trace (false); | 1179 if (likely (mark_index == NOT_COVERED)) return_trace (false); |
| 1172 | 1180 |
| 1173 /* now we search backwards for a non-mark glyph */ | 1181 /* Now we search backwards for a non-mark glyph */ |
| 1174 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; | 1182 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 1175 skippy_iter.reset (buffer->idx, 1); | 1183 skippy_iter.reset (buffer->idx, 1); |
| 1176 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); | 1184 skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); |
| 1177 if (!skippy_iter.prev ()) return_trace (false); | 1185 if (!skippy_iter.prev ()) return_trace (false); |
| 1178 | 1186 |
| 1179 /* Checking that matched glyph is actually a ligature by GDEF is too strong;
disabled */ | 1187 /* Checking that matched glyph is actually a ligature by GDEF is too strong;
disabled */ |
| 1180 if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return
_trace (false);*/ } | 1188 //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return
_trace (false); } |
| 1181 | 1189 |
| 1182 unsigned int j = skippy_iter.idx; | 1190 unsigned int j = skippy_iter.idx; |
| 1183 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info
[j].codepoint); | 1191 unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info
[j].codepoint); |
| 1184 if (lig_index == NOT_COVERED) return_trace (false); | 1192 if (lig_index == NOT_COVERED) return_trace (false); |
| 1185 | 1193 |
| 1186 const LigatureArray& lig_array = this+ligatureArray; | 1194 const LigatureArray& lig_array = this+ligatureArray; |
| 1187 const LigatureAttach& lig_attach = lig_array[lig_index]; | 1195 const LigatureAttach& lig_attach = lig_array[lig_index]; |
| 1188 | 1196 |
| 1189 /* Find component to attach to */ | 1197 /* Find component to attach to */ |
| 1190 unsigned int comp_count = lig_attach.rows; | 1198 unsigned int comp_count = lig_attach.rows; |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 */ | 1502 */ |
| 1495 | 1503 |
| 1496 struct GPOS : GSUBGPOS | 1504 struct GPOS : GSUBGPOS |
| 1497 { | 1505 { |
| 1498 static const hb_tag_t tableTag = HB_OT_TAG_GPOS; | 1506 static const hb_tag_t tableTag = HB_OT_TAG_GPOS; |
| 1499 | 1507 |
| 1500 inline const PosLookup& get_lookup (unsigned int i) const | 1508 inline const PosLookup& get_lookup (unsigned int i) const |
| 1501 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } | 1509 { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); } |
| 1502 | 1510 |
| 1503 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); | 1511 static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); |
| 1504 static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); | 1512 static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buf
fer); |
| 1513 static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buff
er); |
| 1505 | 1514 |
| 1506 inline bool sanitize (hb_sanitize_context_t *c) const | 1515 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1507 { | 1516 { |
| 1508 TRACE_SANITIZE (this); | 1517 TRACE_SANITIZE (this); |
| 1509 if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); | 1518 if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); |
| 1510 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku
pList); | 1519 const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (looku
pList); |
| 1511 return_trace (list.sanitize (c, this)); | 1520 return_trace (list.sanitize (c, this)); |
| 1512 } | 1521 } |
| 1513 public: | 1522 public: |
| 1514 DEFINE_SIZE_STATIC (10); | 1523 DEFINE_SIZE_STATIC (10); |
| 1515 }; | 1524 }; |
| 1516 | 1525 |
| 1517 | 1526 |
| 1518 static void | 1527 static void |
| 1519 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc
tion_t direction, unsigned int new_parent) | 1528 reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc
tion_t direction, unsigned int new_parent) |
| 1520 { | 1529 { |
| 1521 unsigned int j = pos[i].cursive_chain(); | 1530 int chain = pos[i].attach_chain(), type = pos[i].attach_type(); |
| 1522 if (likely (!j)) | 1531 if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) |
| 1523 return; | 1532 return; |
| 1524 | 1533 |
| 1525 j += i; | 1534 pos[i].attach_chain() = 0; |
| 1526 | 1535 |
| 1527 pos[i].cursive_chain() = 0; | 1536 unsigned int j = (int) i + chain; |
| 1528 | 1537 |
| 1529 /* Stop if we see new parent in the chain. */ | 1538 /* Stop if we see new parent in the chain. */ |
| 1530 if (j == new_parent) | 1539 if (j == new_parent) |
| 1531 return; | 1540 return; |
| 1532 | 1541 |
| 1533 reverse_cursive_minor_offset (pos, j, direction, new_parent); | 1542 reverse_cursive_minor_offset (pos, j, direction, new_parent); |
| 1534 | 1543 |
| 1535 if (HB_DIRECTION_IS_HORIZONTAL (direction)) | 1544 if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
| 1536 pos[j].y_offset = -pos[i].y_offset; | 1545 pos[j].y_offset = -pos[i].y_offset; |
| 1537 else | 1546 else |
| 1538 pos[j].x_offset = -pos[i].x_offset; | 1547 pos[j].x_offset = -pos[i].x_offset; |
| 1539 | 1548 |
| 1540 pos[j].cursive_chain() = i - j; | 1549 pos[j].attach_chain() = -chain; |
| 1550 pos[j].attach_type() = type; |
| 1541 } | 1551 } |
| 1542 static void | 1552 static void |
| 1543 fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
_t direction) | 1553 propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direc
tion_t direction) |
| 1544 { | 1554 { |
| 1545 unsigned int j = pos[i].cursive_chain(); | 1555 /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate |
| 1546 if (likely (!j)) | 1556 * offset of glyph they are attached to. */ |
| 1557 int chain = pos[i].attach_chain(), type = pos[i].attach_type(); |
| 1558 if (likely (!chain)) |
| 1547 return; | 1559 return; |
| 1548 | 1560 |
| 1549 j += i; | 1561 unsigned int j = (int) i + chain; |
| 1550 | 1562 |
| 1551 pos[i].cursive_chain() = 0; | 1563 pos[i].attach_chain() = 0; |
| 1552 | 1564 |
| 1553 fix_cursive_minor_offset (pos, j, direction); | 1565 propagate_attachment_offsets (pos, j, direction); |
| 1554 | 1566 |
| 1555 if (HB_DIRECTION_IS_HORIZONTAL (direction)) | 1567 assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); |
| 1568 |
| 1569 if (type & ATTACH_TYPE_CURSIVE) |
| 1570 { |
| 1571 if (HB_DIRECTION_IS_HORIZONTAL (direction)) |
| 1572 pos[i].y_offset += pos[j].y_offset; |
| 1573 else |
| 1574 pos[i].x_offset += pos[j].x_offset; |
| 1575 } |
| 1576 else /*if (type & ATTACH_TYPE_MARK)*/ |
| 1577 { |
| 1578 pos[i].x_offset += pos[j].x_offset; |
| 1556 pos[i].y_offset += pos[j].y_offset; | 1579 pos[i].y_offset += pos[j].y_offset; |
| 1557 else | |
| 1558 pos[i].x_offset += pos[j].x_offset; | |
| 1559 } | |
| 1560 | 1580 |
| 1561 static void | 1581 assert (j < i); |
| 1562 fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t di
rection) | 1582 if (HB_DIRECTION_IS_FORWARD (direction)) |
| 1563 { | 1583 for (unsigned int k = j; k < i; k++) { |
| 1564 if (likely (!(pos[i].attach_lookback()))) | 1584 » pos[i].x_offset -= pos[k].x_advance; |
| 1565 return; | 1585 » pos[i].y_offset -= pos[k].y_advance; |
| 1566 | 1586 } |
| 1567 unsigned int j = i - pos[i].attach_lookback(); | 1587 else |
| 1568 | 1588 for (unsigned int k = j + 1; k < i + 1; k++) { |
| 1569 pos[i].x_offset += pos[j].x_offset; | 1589 » pos[i].x_offset += pos[k].x_advance; |
| 1570 pos[i].y_offset += pos[j].y_offset; | 1590 » pos[i].y_offset += pos[k].y_advance; |
| 1571 | 1591 } |
| 1572 if (HB_DIRECTION_IS_FORWARD (direction)) | 1592 } |
| 1573 for (unsigned int k = j; k < i; k++) { | |
| 1574 pos[i].x_offset -= pos[k].x_advance; | |
| 1575 pos[i].y_offset -= pos[k].y_advance; | |
| 1576 } | |
| 1577 else | |
| 1578 for (unsigned int k = j + 1; k < i + 1; k++) { | |
| 1579 pos[i].x_offset += pos[k].x_advance; | |
| 1580 pos[i].y_offset += pos[k].y_advance; | |
| 1581 } | |
| 1582 } | 1593 } |
| 1583 | 1594 |
| 1584 void | 1595 void |
| 1585 GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) | 1596 GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
| 1586 { | 1597 { |
| 1587 buffer->clear_positions (); | |
| 1588 | |
| 1589 unsigned int count = buffer->len; | 1598 unsigned int count = buffer->len; |
| 1590 for (unsigned int i = 0; i < count; i++) | 1599 for (unsigned int i = 0; i < count; i++) |
| 1591 buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; | 1600 buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; |
| 1592 } | 1601 } |
| 1593 | 1602 |
| 1594 void | 1603 void |
| 1595 GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) | 1604 GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
| 1605 { |
| 1606 //_hb_buffer_assert_gsubgpos_vars (buffer); |
| 1607 } |
| 1608 |
| 1609 void |
| 1610 GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) |
| 1596 { | 1611 { |
| 1597 _hb_buffer_assert_gsubgpos_vars (buffer); | 1612 _hb_buffer_assert_gsubgpos_vars (buffer); |
| 1598 | 1613 |
| 1599 unsigned int len; | 1614 unsigned int len; |
| 1600 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); | 1615 hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); |
| 1601 hb_direction_t direction = buffer->props.direction; | 1616 hb_direction_t direction = buffer->props.direction; |
| 1602 | 1617 |
| 1603 /* Handle cursive connections */ | |
| 1604 if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE) | |
| 1605 for (unsigned int i = 0; i < len; i++) | |
| 1606 fix_cursive_minor_offset (pos, i, direction); | |
| 1607 | |
| 1608 /* Handle attachments */ | 1618 /* Handle attachments */ |
| 1609 if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) | 1619 if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) |
| 1610 for (unsigned int i = 0; i < len; i++) | 1620 for (unsigned int i = 0; i < len; i++) |
| 1611 fix_mark_attachment (pos, i, direction); | 1621 propagate_attachment_offsets (pos, i, direction); |
| 1612 } | 1622 } |
| 1613 | 1623 |
| 1614 | 1624 |
| 1615 /* Out-of-class implementation for methods recursing */ | 1625 /* Out-of-class implementation for methods recursing */ |
| 1616 | 1626 |
| 1617 template <typename context_t> | 1627 template <typename context_t> |
| 1618 /*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func
(context_t *c, unsigned int lookup_index) | 1628 /*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func
(context_t *c, unsigned int lookup_index) |
| 1619 { | 1629 { |
| 1620 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); | 1630 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
| 1621 const PosLookup &l = gpos.get_lookup (lookup_index); | 1631 const PosLookup &l = gpos.get_lookup (lookup_index); |
| 1622 return l.dispatch (c); | 1632 return l.dispatch (c); |
| 1623 } | 1633 } |
| 1624 | 1634 |
| 1625 /*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, uns
igned int lookup_index) | 1635 /*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, uns
igned int lookup_index) |
| 1626 { | 1636 { |
| 1627 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); | 1637 const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); |
| 1628 const PosLookup &l = gpos.get_lookup (lookup_index); | 1638 const PosLookup &l = gpos.get_lookup (lookup_index); |
| 1629 unsigned int saved_lookup_props = c->lookup_props; | 1639 unsigned int saved_lookup_props = c->lookup_props; |
| 1630 unsigned int saved_lookup_index = c->lookup_index; | 1640 unsigned int saved_lookup_index = c->lookup_index; |
| 1631 c->set_lookup_index (lookup_index); | 1641 c->set_lookup_index (lookup_index); |
| 1632 c->set_lookup_props (l.get_props ()); | 1642 c->set_lookup_props (l.get_props ()); |
| 1633 bool ret = l.dispatch (c); | 1643 bool ret = l.dispatch (c); |
| 1634 c->set_lookup_index (saved_lookup_index); | 1644 c->set_lookup_index (saved_lookup_index); |
| 1635 c->set_lookup_props (saved_lookup_props); | 1645 c->set_lookup_props (saved_lookup_props); |
| 1636 return ret; | 1646 return ret; |
| 1637 } | 1647 } |
| 1638 | 1648 |
| 1639 | 1649 |
| 1640 #undef attach_lookback | 1650 #undef attach_chain |
| 1641 #undef cursive_chain | 1651 #undef attach_type |
| 1642 | 1652 |
| 1643 | 1653 |
| 1644 } /* namespace OT */ | 1654 } /* namespace OT */ |
| 1645 | 1655 |
| 1646 | 1656 |
| 1647 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ | 1657 #endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */ |
| OLD | NEW |