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 |