/src/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
Line | Count | Source |
1 | | #ifndef OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH |
2 | | #define OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH |
3 | | |
4 | | #include "MarkMarkPosFormat1.hh" |
5 | | |
6 | | namespace OT { |
7 | | namespace Layout { |
8 | | namespace GPOS_impl { |
9 | | |
10 | | typedef AnchorMatrix Mark2Array; /* mark2-major-- |
11 | | * in order of Mark2Coverage Index--, |
12 | | * mark1-minor-- |
13 | | * ordered by class--zero-based. */ |
14 | | |
15 | | template <typename Types> |
16 | | struct MarkMarkPosFormat1_2 |
17 | | { |
18 | | protected: |
19 | | HBUINT16 format; /* Format identifier--format = 1 */ |
20 | | typename Types::template OffsetTo<Coverage> |
21 | | mark1Coverage; /* Offset to Combining Mark1 Coverage |
22 | | * table--from beginning of MarkMarkPos |
23 | | * subtable */ |
24 | | typename Types::template OffsetTo<Coverage> |
25 | | mark2Coverage; /* Offset to Combining Mark2 Coverage |
26 | | * table--from beginning of MarkMarkPos |
27 | | * subtable */ |
28 | | HBUINT16 classCount; /* Number of defined mark classes */ |
29 | | typename Types::template OffsetTo<MarkArray> |
30 | | mark1Array; /* Offset to Mark1Array table--from |
31 | | * beginning of MarkMarkPos subtable */ |
32 | | typename Types::template OffsetTo<Mark2Array> |
33 | | mark2Array; /* Offset to Mark2Array table--from |
34 | | * beginning of MarkMarkPos subtable */ |
35 | | public: |
36 | | DEFINE_SIZE_STATIC (4 + 4 * Types::size); |
37 | | |
38 | | bool sanitize (hb_sanitize_context_t *c) const |
39 | 10.5k | { |
40 | 10.5k | TRACE_SANITIZE (this); |
41 | 10.5k | return_trace (c->check_struct (this) && |
42 | 10.5k | mark1Coverage.sanitize (c, this) && |
43 | 10.5k | mark2Coverage.sanitize (c, this) && |
44 | 10.5k | mark1Array.sanitize (c, this) && |
45 | 10.5k | hb_barrier () && |
46 | 10.5k | mark2Array.sanitize (c, this, (unsigned int) classCount)); |
47 | 10.5k | } OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::sanitize(hb_sanitize_context_t*) const Line | Count | Source | 39 | 6.42k | { | 40 | 6.42k | TRACE_SANITIZE (this); | 41 | 6.42k | return_trace (c->check_struct (this) && | 42 | 6.42k | mark1Coverage.sanitize (c, this) && | 43 | 6.42k | mark2Coverage.sanitize (c, this) && | 44 | 6.42k | mark1Array.sanitize (c, this) && | 45 | 6.42k | hb_barrier () && | 46 | 6.42k | mark2Array.sanitize (c, this, (unsigned int) classCount)); | 47 | 6.42k | } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::sanitize(hb_sanitize_context_t*) const Line | Count | Source | 39 | 4.10k | { | 40 | 4.10k | TRACE_SANITIZE (this); | 41 | 4.10k | return_trace (c->check_struct (this) && | 42 | 4.10k | mark1Coverage.sanitize (c, this) && | 43 | 4.10k | mark2Coverage.sanitize (c, this) && | 44 | 4.10k | mark1Array.sanitize (c, this) && | 45 | 4.10k | hb_barrier () && | 46 | 4.10k | mark2Array.sanitize (c, this, (unsigned int) classCount)); | 47 | 4.10k | } |
|
48 | | |
49 | | bool intersects (const hb_set_t *glyphs) const |
50 | 2.84k | { |
51 | 2.84k | return (this+mark1Coverage).intersects (glyphs) && |
52 | 2.01k | (this+mark2Coverage).intersects (glyphs); |
53 | 2.84k | } OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::intersects(hb_set_t const*) const Line | Count | Source | 50 | 2.32k | { | 51 | 2.32k | return (this+mark1Coverage).intersects (glyphs) && | 52 | 1.58k | (this+mark2Coverage).intersects (glyphs); | 53 | 2.32k | } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::intersects(hb_set_t const*) const Line | Count | Source | 50 | 529 | { | 51 | 529 | return (this+mark1Coverage).intersects (glyphs) && | 52 | 430 | (this+mark2Coverage).intersects (glyphs); | 53 | 529 | } |
|
54 | | |
55 | 1.35k | void closure_lookups (hb_closure_lookups_context_t *c) const {}OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::closure_lookups(OT::hb_closure_lookups_context_t*) const Line | Count | Source | 55 | 1.04k | void closure_lookups (hb_closure_lookups_context_t *c) const {} |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::closure_lookups(OT::hb_closure_lookups_context_t*) const Line | Count | Source | 55 | 306 | void closure_lookups (hb_closure_lookups_context_t *c) const {} |
|
56 | | |
57 | | void collect_variation_indices (hb_collect_variation_indices_context_t *c) const |
58 | 1.07k | { |
59 | 1.07k | + hb_zip (this+mark1Coverage, this+mark1Array) |
60 | 1.07k | | hb_filter (c->glyph_set, hb_first) |
61 | 1.07k | | hb_map (hb_second) |
62 | 3.79k | | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const::{lambda(OT::Layout::GPOS_impl::MarkRecord const&)#1}::operator()(OT::Layout::GPOS_impl::MarkRecord const&) constLine | Count | Source | 62 | 3.79k | | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); }) |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const::{lambda(OT::Layout::GPOS_impl::MarkRecord const&)#1}::operator()(OT::Layout::GPOS_impl::MarkRecord const&) constLine | Count | Source | 62 | 5 | | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); }) |
|
63 | 1.07k | ; |
64 | | |
65 | 1.07k | hb_map_t klass_mapping; |
66 | 1.07k | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping); |
67 | | |
68 | 1.07k | unsigned mark2_count = (this+mark2Array).rows; |
69 | 1.07k | auto mark2_iter = |
70 | 1.07k | + hb_zip (this+mark2Coverage, hb_range (mark2_count)) |
71 | 1.07k | | hb_filter (c->glyph_set, hb_first) |
72 | 1.07k | | hb_map (hb_second) |
73 | 1.07k | ; |
74 | | |
75 | 1.07k | hb_sorted_vector_t<unsigned> mark2_indexes; |
76 | 1.07k | for (const unsigned row : mark2_iter) |
77 | 873 | { |
78 | 873 | + hb_range ((unsigned) classCount) |
79 | 873 | | hb_filter (klass_mapping) |
80 | 873 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const::{lambda(unsigned int)#1}::operator()(unsigned int) constLine | Count | Source | 80 | 838 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) |
Unexecuted instantiation: OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const::{lambda(unsigned int)#1}::operator()(unsigned int) const |
81 | 873 | | hb_sink (mark2_indexes) |
82 | 873 | ; |
83 | 873 | } |
84 | 1.07k | (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ()); |
85 | 1.07k | } OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const Line | Count | Source | 58 | 952 | { | 59 | 952 | + hb_zip (this+mark1Coverage, this+mark1Array) | 60 | 952 | | hb_filter (c->glyph_set, hb_first) | 61 | 952 | | hb_map (hb_second) | 62 | 952 | | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); }) | 63 | 952 | ; | 64 | | | 65 | 952 | hb_map_t klass_mapping; | 66 | 952 | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping); | 67 | | | 68 | 952 | unsigned mark2_count = (this+mark2Array).rows; | 69 | 952 | auto mark2_iter = | 70 | 952 | + hb_zip (this+mark2Coverage, hb_range (mark2_count)) | 71 | 952 | | hb_filter (c->glyph_set, hb_first) | 72 | 952 | | hb_map (hb_second) | 73 | 952 | ; | 74 | | | 75 | 952 | hb_sorted_vector_t<unsigned> mark2_indexes; | 76 | 952 | for (const unsigned row : mark2_iter) | 77 | 845 | { | 78 | 845 | + hb_range ((unsigned) classCount) | 79 | 845 | | hb_filter (klass_mapping) | 80 | 845 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) | 81 | 845 | | hb_sink (mark2_indexes) | 82 | 845 | ; | 83 | 845 | } | 84 | 952 | (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ()); | 85 | 952 | } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::collect_variation_indices(OT::hb_collect_variation_indices_context_t*) const Line | Count | Source | 58 | 121 | { | 59 | 121 | + hb_zip (this+mark1Coverage, this+mark1Array) | 60 | 121 | | hb_filter (c->glyph_set, hb_first) | 61 | 121 | | hb_map (hb_second) | 62 | 121 | | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); }) | 63 | 121 | ; | 64 | | | 65 | 121 | hb_map_t klass_mapping; | 66 | 121 | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping); | 67 | | | 68 | 121 | unsigned mark2_count = (this+mark2Array).rows; | 69 | 121 | auto mark2_iter = | 70 | 121 | + hb_zip (this+mark2Coverage, hb_range (mark2_count)) | 71 | 121 | | hb_filter (c->glyph_set, hb_first) | 72 | 121 | | hb_map (hb_second) | 73 | 121 | ; | 74 | | | 75 | 121 | hb_sorted_vector_t<unsigned> mark2_indexes; | 76 | 121 | for (const unsigned row : mark2_iter) | 77 | 28 | { | 78 | 28 | + hb_range ((unsigned) classCount) | 79 | 28 | | hb_filter (klass_mapping) | 80 | 28 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) | 81 | 28 | | hb_sink (mark2_indexes) | 82 | 28 | ; | 83 | 28 | } | 84 | 121 | (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ()); | 85 | 121 | } |
|
86 | | |
87 | | void collect_glyphs (hb_collect_glyphs_context_t *c) const |
88 | 0 | { |
89 | 0 | if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return; |
90 | 0 | if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return; |
91 | 0 | } Unexecuted instantiation: OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::collect_glyphs(OT::hb_collect_glyphs_context_t*) const Unexecuted instantiation: OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::collect_glyphs(OT::hb_collect_glyphs_context_t*) const |
92 | | |
93 | 2.87k | const Coverage &get_coverage () const { return this+mark1Coverage; }OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::get_coverage() const Line | Count | Source | 93 | 1.20k | const Coverage &get_coverage () const { return this+mark1Coverage; } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::get_coverage() const Line | Count | Source | 93 | 1.67k | const Coverage &get_coverage () const { return this+mark1Coverage; } |
|
94 | | |
95 | | bool apply (hb_ot_apply_context_t *c) const |
96 | 1.34M | { |
97 | 1.34M | TRACE_APPLY (this); |
98 | 1.34M | hb_buffer_t *buffer = c->buffer; |
99 | 1.34M | unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); |
100 | 1.34M | if (likely (mark1_index == NOT_COVERED)) return_trace (false); |
101 | | |
102 | | /* now we search backwards for a suitable mark glyph until a non-mark glyph */ |
103 | 1.29M | auto &skippy_iter = c->iter_input; |
104 | 1.29M | skippy_iter.reset_fast (buffer->idx); |
105 | 1.29M | skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); |
106 | 1.29M | unsigned unsafe_from; |
107 | 1.29M | if (unlikely (!skippy_iter.prev (&unsafe_from))) |
108 | 10.3k | { |
109 | 10.3k | buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1); |
110 | 10.3k | return_trace (false); |
111 | 10.3k | } |
112 | | |
113 | 1.28M | if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))) |
114 | 1.24M | { |
115 | 1.24M | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); |
116 | 1.24M | return_trace (false); |
117 | 1.24M | } |
118 | | |
119 | 47.3k | unsigned int j = skippy_iter.idx; |
120 | | |
121 | 47.3k | unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); |
122 | 47.3k | unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); |
123 | 47.3k | unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); |
124 | 47.3k | unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); |
125 | | |
126 | 47.3k | if (likely (id1 == id2)) |
127 | 44.8k | { |
128 | 44.8k | if (id1 == 0) /* Marks belonging to the same base. */ |
129 | 43.6k | goto good; |
130 | 1.14k | else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ |
131 | 611 | goto good; |
132 | 44.8k | } |
133 | 2.56k | else |
134 | 2.56k | { |
135 | | /* If ligature ids don't match, it may be the case that one of the marks |
136 | | * itself is a ligature. In which case match. */ |
137 | 2.56k | if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) |
138 | 1.22k | goto good; |
139 | 2.56k | } |
140 | | |
141 | | /* Didn't match. */ |
142 | 1.86k | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); |
143 | 1.86k | return_trace (false); |
144 | | |
145 | 45.5k | good: |
146 | 45.5k | unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); |
147 | 45.5k | if (mark2_index == NOT_COVERED) |
148 | 16.0k | { |
149 | 16.0k | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); |
150 | 16.0k | return_trace (false); |
151 | 16.0k | } |
152 | | |
153 | 45.5k | return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); |
154 | 45.5k | } OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::apply(OT::hb_ot_apply_context_t*) const Line | Count | Source | 96 | 1.32M | { | 97 | 1.32M | TRACE_APPLY (this); | 98 | 1.32M | hb_buffer_t *buffer = c->buffer; | 99 | 1.32M | unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); | 100 | 1.32M | if (likely (mark1_index == NOT_COVERED)) return_trace (false); | 101 | | | 102 | | /* now we search backwards for a suitable mark glyph until a non-mark glyph */ | 103 | 1.28M | auto &skippy_iter = c->iter_input; | 104 | 1.28M | skippy_iter.reset_fast (buffer->idx); | 105 | 1.28M | skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); | 106 | 1.28M | unsigned unsafe_from; | 107 | 1.28M | if (unlikely (!skippy_iter.prev (&unsafe_from))) | 108 | 8.79k | { | 109 | 8.79k | buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1); | 110 | 8.79k | return_trace (false); | 111 | 8.79k | } | 112 | | | 113 | 1.27M | if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))) | 114 | 1.22M | { | 115 | 1.22M | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 116 | 1.22M | return_trace (false); | 117 | 1.22M | } | 118 | | | 119 | 45.8k | unsigned int j = skippy_iter.idx; | 120 | | | 121 | 45.8k | unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); | 122 | 45.8k | unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); | 123 | 45.8k | unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); | 124 | 45.8k | unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); | 125 | | | 126 | 45.8k | if (likely (id1 == id2)) | 127 | 43.5k | { | 128 | 43.5k | if (id1 == 0) /* Marks belonging to the same base. */ | 129 | 42.6k | goto good; | 130 | 967 | else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ | 131 | 552 | goto good; | 132 | 43.5k | } | 133 | 2.31k | else | 134 | 2.31k | { | 135 | | /* If ligature ids don't match, it may be the case that one of the marks | 136 | | * itself is a ligature. In which case match. */ | 137 | 2.31k | if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) | 138 | 1.09k | goto good; | 139 | 2.31k | } | 140 | | | 141 | | /* Didn't match. */ | 142 | 1.63k | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 143 | 1.63k | return_trace (false); | 144 | | | 145 | 44.2k | good: | 146 | 44.2k | unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); | 147 | 44.2k | if (mark2_index == NOT_COVERED) | 148 | 15.2k | { | 149 | 15.2k | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 150 | 15.2k | return_trace (false); | 151 | 15.2k | } | 152 | | | 153 | 28.9k | return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); | 154 | 44.2k | } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::apply(OT::hb_ot_apply_context_t*) const Line | Count | Source | 96 | 19.5k | { | 97 | 19.5k | TRACE_APPLY (this); | 98 | 19.5k | hb_buffer_t *buffer = c->buffer; | 99 | 19.5k | unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); | 100 | 19.5k | if (likely (mark1_index == NOT_COVERED)) return_trace (false); | 101 | | | 102 | | /* now we search backwards for a suitable mark glyph until a non-mark glyph */ | 103 | 17.9k | auto &skippy_iter = c->iter_input; | 104 | 17.9k | skippy_iter.reset_fast (buffer->idx); | 105 | 17.9k | skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); | 106 | 17.9k | unsigned unsafe_from; | 107 | 17.9k | if (unlikely (!skippy_iter.prev (&unsafe_from))) | 108 | 1.53k | { | 109 | 1.53k | buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1); | 110 | 1.53k | return_trace (false); | 111 | 1.53k | } | 112 | | | 113 | 16.4k | if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))) | 114 | 14.9k | { | 115 | 14.9k | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 116 | 14.9k | return_trace (false); | 117 | 14.9k | } | 118 | | | 119 | 1.48k | unsigned int j = skippy_iter.idx; | 120 | | | 121 | 1.48k | unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur()); | 122 | 1.48k | unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]); | 123 | 1.48k | unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur()); | 124 | 1.48k | unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]); | 125 | | | 126 | 1.48k | if (likely (id1 == id2)) | 127 | 1.23k | { | 128 | 1.23k | if (id1 == 0) /* Marks belonging to the same base. */ | 129 | 1.05k | goto good; | 130 | 179 | else if (comp1 == comp2) /* Marks belonging to the same ligature component. */ | 131 | 59 | goto good; | 132 | 1.23k | } | 133 | 247 | else | 134 | 247 | { | 135 | | /* If ligature ids don't match, it may be the case that one of the marks | 136 | | * itself is a ligature. In which case match. */ | 137 | 247 | if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2)) | 138 | 135 | goto good; | 139 | 247 | } | 140 | | | 141 | | /* Didn't match. */ | 142 | 232 | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 143 | 232 | return_trace (false); | 144 | | | 145 | 1.25k | good: | 146 | 1.25k | unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); | 147 | 1.25k | if (mark2_index == NOT_COVERED) | 148 | 826 | { | 149 | 826 | buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1); | 150 | 826 | return_trace (false); | 151 | 826 | } | 152 | | | 153 | 424 | return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); | 154 | 1.25k | } |
|
155 | | |
156 | | bool subset (hb_subset_context_t *c) const |
157 | 912 | { |
158 | 912 | TRACE_SUBSET (this); |
159 | 912 | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); |
160 | 912 | const hb_map_t &glyph_map = *c->plan->glyph_map; |
161 | | |
162 | 912 | auto *out = c->serializer->start_embed (*this); |
163 | 912 | if (unlikely (!c->serializer->extend_min (out))) return_trace (false); |
164 | 912 | out->format = format; |
165 | | |
166 | 912 | hb_map_t klass_mapping; |
167 | 912 | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping); |
168 | | |
169 | 912 | if (!klass_mapping.get_population ()) return_trace (false); |
170 | 788 | out->classCount = klass_mapping.get_population (); |
171 | | |
172 | 788 | auto mark1_iter = |
173 | 788 | + hb_zip (this+mark1Coverage, this+mark1Array) |
174 | 788 | | hb_filter (glyphset, hb_first) |
175 | 788 | ; |
176 | | |
177 | 788 | hb_sorted_vector_t<hb_codepoint_t> new_coverage; |
178 | 788 | + mark1_iter |
179 | 788 | | hb_map (hb_first) |
180 | 788 | | hb_map (glyph_map) |
181 | 788 | | hb_sink (new_coverage) |
182 | 788 | ; |
183 | | |
184 | 788 | if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) |
185 | 17 | return_trace (false); |
186 | | |
187 | 771 | if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, |
188 | 771 | (this+mark1Coverage).iter (), |
189 | 771 | &klass_mapping))) |
190 | 90 | return_trace (false); |
191 | | |
192 | 681 | unsigned mark2count = (this+mark2Array).rows; |
193 | 681 | auto mark2_iter = |
194 | 681 | + hb_zip (this+mark2Coverage, hb_range (mark2count)) |
195 | 681 | | hb_filter (glyphset, hb_first) |
196 | 681 | ; |
197 | | |
198 | 681 | new_coverage.reset (); |
199 | 681 | hb_sorted_vector_t<unsigned> mark2_indexes; |
200 | 681 | auto &mark2_array = (this+mark2Array); |
201 | 681 | for (const auto _ : + mark2_iter) |
202 | 18.7k | { |
203 | 18.7k | unsigned row = _.second; |
204 | | |
205 | 18.7k | bool non_empty = + hb_range ((unsigned) classCount) |
206 | 18.7k | | hb_filter (klass_mapping) |
207 | 20.7k | | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); })OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::subset(hb_subset_context_t*) const::{lambda(unsigned int)#1}::operator()(unsigned int) constLine | Count | Source | 207 | 13.8k | | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::subset(hb_subset_context_t*) const::{lambda(unsigned int)#1}::operator()(unsigned int) constLine | Count | Source | 207 | 6.88k | | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) |
|
208 | 18.7k | | hb_any |
209 | 18.7k | ; |
210 | | |
211 | 18.7k | if (!non_empty) continue; |
212 | | |
213 | 5.13k | hb_codepoint_t new_g = glyph_map.get ( _.first); |
214 | 5.13k | new_coverage.push (new_g); |
215 | | |
216 | 5.13k | + hb_range ((unsigned) classCount) |
217 | 5.13k | | hb_filter (klass_mapping) |
218 | 11.4k | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::subset(hb_subset_context_t*) const::{lambda(unsigned int)#2}::operator()(unsigned int) constLine | Count | Source | 218 | 11.0k | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::subset(hb_subset_context_t*) const::{lambda(unsigned int)#2}::operator()(unsigned int) constLine | Count | Source | 218 | 418 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) |
|
219 | 5.13k | | hb_sink (mark2_indexes) |
220 | 5.13k | ; |
221 | 5.13k | } |
222 | | |
223 | 681 | if (!new_coverage) return_trace (false); |
224 | 394 | if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) |
225 | 1 | return_trace (false); |
226 | | |
227 | 394 | return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, |
228 | 394 | mark2_iter.len (), |
229 | 394 | mark2_indexes.iter ())); |
230 | | |
231 | 394 | } OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::SmallTypes>::subset(hb_subset_context_t*) const Line | Count | Source | 157 | 732 | { | 158 | 732 | TRACE_SUBSET (this); | 159 | 732 | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); | 160 | 732 | const hb_map_t &glyph_map = *c->plan->glyph_map; | 161 | | | 162 | 732 | auto *out = c->serializer->start_embed (*this); | 163 | 732 | if (unlikely (!c->serializer->extend_min (out))) return_trace (false); | 164 | 732 | out->format = format; | 165 | | | 166 | 732 | hb_map_t klass_mapping; | 167 | 732 | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping); | 168 | | | 169 | 732 | if (!klass_mapping.get_population ()) return_trace (false); | 170 | 616 | out->classCount = klass_mapping.get_population (); | 171 | | | 172 | 616 | auto mark1_iter = | 173 | 616 | + hb_zip (this+mark1Coverage, this+mark1Array) | 174 | 616 | | hb_filter (glyphset, hb_first) | 175 | 616 | ; | 176 | | | 177 | 616 | hb_sorted_vector_t<hb_codepoint_t> new_coverage; | 178 | 616 | + mark1_iter | 179 | 616 | | hb_map (hb_first) | 180 | 616 | | hb_map (glyph_map) | 181 | 616 | | hb_sink (new_coverage) | 182 | 616 | ; | 183 | | | 184 | 616 | if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) | 185 | 17 | return_trace (false); | 186 | | | 187 | 599 | if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, | 188 | 599 | (this+mark1Coverage).iter (), | 189 | 599 | &klass_mapping))) | 190 | 70 | return_trace (false); | 191 | | | 192 | 529 | unsigned mark2count = (this+mark2Array).rows; | 193 | 529 | auto mark2_iter = | 194 | 529 | + hb_zip (this+mark2Coverage, hb_range (mark2count)) | 195 | 529 | | hb_filter (glyphset, hb_first) | 196 | 529 | ; | 197 | | | 198 | 529 | new_coverage.reset (); | 199 | 529 | hb_sorted_vector_t<unsigned> mark2_indexes; | 200 | 529 | auto &mark2_array = (this+mark2Array); | 201 | 529 | for (const auto _ : + mark2_iter) | 202 | 7.14k | { | 203 | 7.14k | unsigned row = _.second; | 204 | | | 205 | 7.14k | bool non_empty = + hb_range ((unsigned) classCount) | 206 | 7.14k | | hb_filter (klass_mapping) | 207 | 7.14k | | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) | 208 | 7.14k | | hb_any | 209 | 7.14k | ; | 210 | | | 211 | 7.14k | if (!non_empty) continue; | 212 | | | 213 | 4.95k | hb_codepoint_t new_g = glyph_map.get ( _.first); | 214 | 4.95k | new_coverage.push (new_g); | 215 | | | 216 | 4.95k | + hb_range ((unsigned) classCount) | 217 | 4.95k | | hb_filter (klass_mapping) | 218 | 4.95k | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) | 219 | 4.95k | | hb_sink (mark2_indexes) | 220 | 4.95k | ; | 221 | 4.95k | } | 222 | | | 223 | 529 | if (!new_coverage) return_trace (false); | 224 | 331 | if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) | 225 | 1 | return_trace (false); | 226 | | | 227 | 331 | return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, | 228 | 331 | mark2_iter.len (), | 229 | 331 | mark2_indexes.iter ())); | 230 | | | 231 | 331 | } |
OT::Layout::GPOS_impl::MarkMarkPosFormat1_2<OT::Layout::MediumTypes>::subset(hb_subset_context_t*) const Line | Count | Source | 157 | 180 | { | 158 | 180 | TRACE_SUBSET (this); | 159 | 180 | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); | 160 | 180 | const hb_map_t &glyph_map = *c->plan->glyph_map; | 161 | | | 162 | 180 | auto *out = c->serializer->start_embed (*this); | 163 | 180 | if (unlikely (!c->serializer->extend_min (out))) return_trace (false); | 164 | 180 | out->format = format; | 165 | | | 166 | 180 | hb_map_t klass_mapping; | 167 | 180 | Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping); | 168 | | | 169 | 180 | if (!klass_mapping.get_population ()) return_trace (false); | 170 | 172 | out->classCount = klass_mapping.get_population (); | 171 | | | 172 | 172 | auto mark1_iter = | 173 | 172 | + hb_zip (this+mark1Coverage, this+mark1Array) | 174 | 172 | | hb_filter (glyphset, hb_first) | 175 | 172 | ; | 176 | | | 177 | 172 | hb_sorted_vector_t<hb_codepoint_t> new_coverage; | 178 | 172 | + mark1_iter | 179 | 172 | | hb_map (hb_first) | 180 | 172 | | hb_map (glyph_map) | 181 | 172 | | hb_sink (new_coverage) | 182 | 172 | ; | 183 | | | 184 | 172 | if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) | 185 | 0 | return_trace (false); | 186 | | | 187 | 172 | if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, | 188 | 172 | (this+mark1Coverage).iter (), | 189 | 172 | &klass_mapping))) | 190 | 20 | return_trace (false); | 191 | | | 192 | 152 | unsigned mark2count = (this+mark2Array).rows; | 193 | 152 | auto mark2_iter = | 194 | 152 | + hb_zip (this+mark2Coverage, hb_range (mark2count)) | 195 | 152 | | hb_filter (glyphset, hb_first) | 196 | 152 | ; | 197 | | | 198 | 152 | new_coverage.reset (); | 199 | 152 | hb_sorted_vector_t<unsigned> mark2_indexes; | 200 | 152 | auto &mark2_array = (this+mark2Array); | 201 | 152 | for (const auto _ : + mark2_iter) | 202 | 11.5k | { | 203 | 11.5k | unsigned row = _.second; | 204 | | | 205 | 11.5k | bool non_empty = + hb_range ((unsigned) classCount) | 206 | 11.5k | | hb_filter (klass_mapping) | 207 | 11.5k | | hb_map ([&] (const unsigned col) { return !mark2_array.offset_is_null (row, col, (unsigned) classCount); }) | 208 | 11.5k | | hb_any | 209 | 11.5k | ; | 210 | | | 211 | 11.5k | if (!non_empty) continue; | 212 | | | 213 | 186 | hb_codepoint_t new_g = glyph_map.get ( _.first); | 214 | 186 | new_coverage.push (new_g); | 215 | | | 216 | 186 | + hb_range ((unsigned) classCount) | 217 | 186 | | hb_filter (klass_mapping) | 218 | 186 | | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; }) | 219 | 186 | | hb_sink (mark2_indexes) | 220 | 186 | ; | 221 | 186 | } | 222 | | | 223 | 152 | if (!new_coverage) return_trace (false); | 224 | 63 | if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) | 225 | 0 | return_trace (false); | 226 | | | 227 | 63 | return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, | 228 | 63 | mark2_iter.len (), | 229 | 63 | mark2_indexes.iter ())); | 230 | | | 231 | 63 | } |
|
232 | | }; |
233 | | |
234 | | |
235 | | } |
236 | | } |
237 | | } |
238 | | |
239 | | #endif /* OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH */ |