/src/harfbuzz/src/OT/Layout/GSUB/Sequence.hh
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef OT_LAYOUT_GSUB_SEQUENCE_HH |
2 | | #define OT_LAYOUT_GSUB_SEQUENCE_HH |
3 | | |
4 | | #include "Common.hh" |
5 | | |
6 | | namespace OT { |
7 | | namespace Layout { |
8 | | namespace GSUB_impl { |
9 | | |
10 | | template <typename Types> |
11 | | struct Sequence |
12 | | { |
13 | | protected: |
14 | | Array16Of<typename Types::HBGlyphID> |
15 | | substitute; /* String of GlyphIDs to substitute */ |
16 | | public: |
17 | | DEFINE_SIZE_ARRAY (2, substitute); |
18 | | |
19 | | bool sanitize (hb_sanitize_context_t *c) const |
20 | 645k | { |
21 | 645k | TRACE_SANITIZE (this); |
22 | 645k | return_trace (substitute.sanitize (c)); |
23 | 645k | } OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::sanitize(hb_sanitize_context_t*) const Line | Count | Source | 20 | 607k | { | 21 | 607k | TRACE_SANITIZE (this); | 22 | 607k | return_trace (substitute.sanitize (c)); | 23 | 607k | } |
OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::sanitize(hb_sanitize_context_t*) const Line | Count | Source | 20 | 38.1k | { | 21 | 38.1k | TRACE_SANITIZE (this); | 22 | 38.1k | return_trace (substitute.sanitize (c)); | 23 | 38.1k | } |
|
24 | | |
25 | | bool intersects (const hb_set_t *glyphs) const |
26 | 42.0k | { return hb_all (substitute, glyphs); }OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::intersects(hb_set_t const*) const Line | Count | Source | 26 | 39.3k | { return hb_all (substitute, glyphs); } |
OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::intersects(hb_set_t const*) const Line | Count | Source | 26 | 2.67k | { return hb_all (substitute, glyphs); } |
|
27 | | |
28 | | void closure (hb_closure_context_t *c) const |
29 | 402k | { c->output->add_array (substitute.arrayZ, substitute.len); }OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::closure(OT::hb_closure_context_t*) const Line | Count | Source | 29 | 393k | { c->output->add_array (substitute.arrayZ, substitute.len); } |
OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::closure(OT::hb_closure_context_t*) const Line | Count | Source | 29 | 8.65k | { c->output->add_array (substitute.arrayZ, substitute.len); } |
|
30 | | |
31 | | void collect_glyphs (hb_collect_glyphs_context_t *c) const |
32 | 0 | { c->output->add_array (substitute.arrayZ, substitute.len); }Unexecuted instantiation: OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::collect_glyphs(OT::hb_collect_glyphs_context_t*) const Unexecuted instantiation: OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::collect_glyphs(OT::hb_collect_glyphs_context_t*) const |
33 | | |
34 | | bool apply (hb_ot_apply_context_t *c) const |
35 | 2.51M | { |
36 | 2.51M | TRACE_APPLY (this); |
37 | 2.51M | unsigned int count = substitute.len; |
38 | | |
39 | | /* Special-case to make it in-place and not consider this |
40 | | * as a "multiplied" substitution. */ |
41 | 2.51M | if (unlikely (count == 1)) |
42 | 11.7k | { |
43 | 11.7k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
44 | 0 | { |
45 | 0 | c->buffer->sync_so_far (); |
46 | 0 | c->buffer->message (c->font, |
47 | 0 | "replacing glyph at %u (multiple substitution)", |
48 | 0 | c->buffer->idx); |
49 | 0 | } |
50 | | |
51 | 11.7k | c->replace_glyph (substitute.arrayZ[0]); |
52 | | |
53 | 11.7k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
54 | 0 | { |
55 | 0 | c->buffer->message (c->font, |
56 | 0 | "replaced glyph at %u (multiple substitution)", |
57 | 0 | c->buffer->idx - 1u); |
58 | 0 | } |
59 | | |
60 | 11.7k | return_trace (true); |
61 | 11.7k | } |
62 | | /* Spec disallows this, but Uniscribe allows it. |
63 | | * https://github.com/harfbuzz/harfbuzz/issues/253 */ |
64 | 2.50M | else if (unlikely (count == 0)) |
65 | 1.05M | { |
66 | 1.05M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
67 | 0 | { |
68 | 0 | c->buffer->sync_so_far (); |
69 | 0 | c->buffer->message (c->font, |
70 | 0 | "deleting glyph at %u (multiple substitution)", |
71 | 0 | c->buffer->idx); |
72 | 0 | } |
73 | | |
74 | 1.05M | c->buffer->delete_glyph (); |
75 | | |
76 | 1.05M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
77 | 0 | { |
78 | 0 | c->buffer->sync_so_far (); |
79 | 0 | c->buffer->message (c->font, |
80 | 0 | "deleted glyph at %u (multiple substitution)", |
81 | 0 | c->buffer->idx); |
82 | 0 | } |
83 | | |
84 | 1.05M | return_trace (true); |
85 | 1.05M | } |
86 | | |
87 | 1.44M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
88 | 0 | { |
89 | 0 | c->buffer->sync_so_far (); |
90 | 0 | c->buffer->message (c->font, |
91 | 0 | "multiplying glyph at %u", |
92 | 0 | c->buffer->idx); |
93 | 0 | } |
94 | | |
95 | 1.44M | unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
96 | 1.37M | HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
97 | 1.44M | unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); |
98 | | |
99 | 54.0M | for (unsigned int i = 0; i < count; i++) |
100 | 52.5M | { |
101 | | /* If is attached to a ligature, don't disturb that. |
102 | | * https://github.com/harfbuzz/harfbuzz/issues/3069 */ |
103 | 52.5M | if (!lig_id) |
104 | 49.6M | _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
105 | 52.5M | c->output_glyph_for_component (substitute.arrayZ[i], klass); |
106 | 52.5M | } |
107 | 1.44M | c->buffer->skip_glyph (); |
108 | | |
109 | 1.44M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) |
110 | 0 | { |
111 | 0 | c->buffer->sync_so_far (); |
112 | |
|
113 | 0 | char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; |
114 | 0 | char *p = buf; |
115 | |
|
116 | 0 | for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) |
117 | 0 | { |
118 | 0 | if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) |
119 | 0 | *p++ = ','; |
120 | 0 | snprintf (p, sizeof(buf) - (p - buf), "%u", i); |
121 | 0 | p += strlen(p); |
122 | 0 | } |
123 | |
|
124 | 0 | c->buffer->message (c->font, |
125 | 0 | "multiplied glyphs at %s", |
126 | 0 | buf); |
127 | 0 | } |
128 | | |
129 | 1.44M | return_trace (true); |
130 | 2.51M | } OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::apply(OT::hb_ot_apply_context_t*) const Line | Count | Source | 35 | 2.50M | { | 36 | 2.50M | TRACE_APPLY (this); | 37 | 2.50M | unsigned int count = substitute.len; | 38 | | | 39 | | /* Special-case to make it in-place and not consider this | 40 | | * as a "multiplied" substitution. */ | 41 | 2.50M | if (unlikely (count == 1)) | 42 | 6.58k | { | 43 | 6.58k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 44 | 0 | { | 45 | 0 | c->buffer->sync_so_far (); | 46 | 0 | c->buffer->message (c->font, | 47 | 0 | "replacing glyph at %u (multiple substitution)", | 48 | 0 | c->buffer->idx); | 49 | 0 | } | 50 | | | 51 | 6.58k | c->replace_glyph (substitute.arrayZ[0]); | 52 | | | 53 | 6.58k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 54 | 0 | { | 55 | 0 | c->buffer->message (c->font, | 56 | 0 | "replaced glyph at %u (multiple substitution)", | 57 | 0 | c->buffer->idx - 1u); | 58 | 0 | } | 59 | | | 60 | 6.58k | return_trace (true); | 61 | 6.58k | } | 62 | | /* Spec disallows this, but Uniscribe allows it. | 63 | | * https://github.com/harfbuzz/harfbuzz/issues/253 */ | 64 | 2.49M | else if (unlikely (count == 0)) | 65 | 1.05M | { | 66 | 1.05M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 67 | 0 | { | 68 | 0 | c->buffer->sync_so_far (); | 69 | 0 | c->buffer->message (c->font, | 70 | 0 | "deleting glyph at %u (multiple substitution)", | 71 | 0 | c->buffer->idx); | 72 | 0 | } | 73 | | | 74 | 1.05M | c->buffer->delete_glyph (); | 75 | | | 76 | 1.05M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 77 | 0 | { | 78 | 0 | c->buffer->sync_so_far (); | 79 | 0 | c->buffer->message (c->font, | 80 | 0 | "deleted glyph at %u (multiple substitution)", | 81 | 0 | c->buffer->idx); | 82 | 0 | } | 83 | | | 84 | 1.05M | return_trace (true); | 85 | 1.05M | } | 86 | | | 87 | 1.44M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 88 | 0 | { | 89 | 0 | c->buffer->sync_so_far (); | 90 | 0 | c->buffer->message (c->font, | 91 | 0 | "multiplying glyph at %u", | 92 | 0 | c->buffer->idx); | 93 | 0 | } | 94 | | | 95 | 1.44M | unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? | 96 | 1.37M | HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; | 97 | 1.44M | unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); | 98 | | | 99 | 53.2M | for (unsigned int i = 0; i < count; i++) | 100 | 51.7M | { | 101 | | /* If is attached to a ligature, don't disturb that. | 102 | | * https://github.com/harfbuzz/harfbuzz/issues/3069 */ | 103 | 51.7M | if (!lig_id) | 104 | 48.8M | _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); | 105 | 51.7M | c->output_glyph_for_component (substitute.arrayZ[i], klass); | 106 | 51.7M | } | 107 | 1.44M | c->buffer->skip_glyph (); | 108 | | | 109 | 1.44M | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 110 | 0 | { | 111 | 0 | c->buffer->sync_so_far (); | 112 | |
| 113 | 0 | char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; | 114 | 0 | char *p = buf; | 115 | |
| 116 | 0 | for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) | 117 | 0 | { | 118 | 0 | if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) | 119 | 0 | *p++ = ','; | 120 | 0 | snprintf (p, sizeof(buf) - (p - buf), "%u", i); | 121 | 0 | p += strlen(p); | 122 | 0 | } | 123 | |
| 124 | 0 | c->buffer->message (c->font, | 125 | 0 | "multiplied glyphs at %s", | 126 | 0 | buf); | 127 | 0 | } | 128 | | | 129 | 1.44M | return_trace (true); | 130 | 2.50M | } |
OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::apply(OT::hb_ot_apply_context_t*) const Line | Count | Source | 35 | 12.2k | { | 36 | 12.2k | TRACE_APPLY (this); | 37 | 12.2k | unsigned int count = substitute.len; | 38 | | | 39 | | /* Special-case to make it in-place and not consider this | 40 | | * as a "multiplied" substitution. */ | 41 | 12.2k | if (unlikely (count == 1)) | 42 | 5.19k | { | 43 | 5.19k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 44 | 0 | { | 45 | 0 | c->buffer->sync_so_far (); | 46 | 0 | c->buffer->message (c->font, | 47 | 0 | "replacing glyph at %u (multiple substitution)", | 48 | 0 | c->buffer->idx); | 49 | 0 | } | 50 | | | 51 | 5.19k | c->replace_glyph (substitute.arrayZ[0]); | 52 | | | 53 | 5.19k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 54 | 0 | { | 55 | 0 | c->buffer->message (c->font, | 56 | 0 | "replaced glyph at %u (multiple substitution)", | 57 | 0 | c->buffer->idx - 1u); | 58 | 0 | } | 59 | | | 60 | 5.19k | return_trace (true); | 61 | 5.19k | } | 62 | | /* Spec disallows this, but Uniscribe allows it. | 63 | | * https://github.com/harfbuzz/harfbuzz/issues/253 */ | 64 | 7.03k | else if (unlikely (count == 0)) | 65 | 3.61k | { | 66 | 3.61k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 67 | 0 | { | 68 | 0 | c->buffer->sync_so_far (); | 69 | 0 | c->buffer->message (c->font, | 70 | 0 | "deleting glyph at %u (multiple substitution)", | 71 | 0 | c->buffer->idx); | 72 | 0 | } | 73 | | | 74 | 3.61k | c->buffer->delete_glyph (); | 75 | | | 76 | 3.61k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 77 | 0 | { | 78 | 0 | c->buffer->sync_so_far (); | 79 | 0 | c->buffer->message (c->font, | 80 | 0 | "deleted glyph at %u (multiple substitution)", | 81 | 0 | c->buffer->idx); | 82 | 0 | } | 83 | | | 84 | 3.61k | return_trace (true); | 85 | 3.61k | } | 86 | | | 87 | 3.42k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 88 | 0 | { | 89 | 0 | c->buffer->sync_so_far (); | 90 | 0 | c->buffer->message (c->font, | 91 | 0 | "multiplying glyph at %u", | 92 | 0 | c->buffer->idx); | 93 | 0 | } | 94 | | | 95 | 3.42k | unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? | 96 | 3.23k | HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; | 97 | 3.42k | unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur()); | 98 | | | 99 | 801k | for (unsigned int i = 0; i < count; i++) | 100 | 797k | { | 101 | | /* If is attached to a ligature, don't disturb that. | 102 | | * https://github.com/harfbuzz/harfbuzz/issues/3069 */ | 103 | 797k | if (!lig_id) | 104 | 775k | _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); | 105 | 797k | c->output_glyph_for_component (substitute.arrayZ[i], klass); | 106 | 797k | } | 107 | 3.42k | c->buffer->skip_glyph (); | 108 | | | 109 | 3.42k | if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ()) | 110 | 0 | { | 111 | 0 | c->buffer->sync_so_far (); | 112 | |
| 113 | 0 | char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0}; | 114 | 0 | char *p = buf; | 115 | |
| 116 | 0 | for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++) | 117 | 0 | { | 118 | 0 | if (buf < p && sizeof(buf) - 1u > unsigned (p - buf)) | 119 | 0 | *p++ = ','; | 120 | 0 | snprintf (p, sizeof(buf) - (p - buf), "%u", i); | 121 | 0 | p += strlen(p); | 122 | 0 | } | 123 | |
| 124 | 0 | c->buffer->message (c->font, | 125 | 0 | "multiplied glyphs at %s", | 126 | 0 | buf); | 127 | 0 | } | 128 | | | 129 | 3.42k | return_trace (true); | 130 | 12.2k | } |
|
131 | | |
132 | | template <typename Iterator, |
133 | | hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))> |
134 | | bool serialize (hb_serialize_context_t *c, |
135 | | Iterator subst) |
136 | 21.4k | { |
137 | 21.4k | TRACE_SERIALIZE (this); |
138 | 21.4k | return_trace (substitute.serialize (c, subst)); |
139 | 21.4k | } _ZN2OT6Layout9GSUB_impl8SequenceINS0_10SmallTypesEE9serializeI13hb_map_iter_tI10hb_array_tIKNS_11HBGlyphID16EERK8hb_map_tL24hb_function_sortedness_t0ELPv0EETnPN12hb_enable_ifIXsr15hb_is_source_ofIT_jEE5valueEvE4typeELSF_0EEEbP22hb_serialize_context_tSI_ Line | Count | Source | 136 | 19.4k | { | 137 | 19.4k | TRACE_SERIALIZE (this); | 138 | 19.4k | return_trace (substitute.serialize (c, subst)); | 139 | 19.4k | } |
_ZN2OT6Layout9GSUB_impl8SequenceINS0_11MediumTypesEE9serializeI13hb_map_iter_tI10hb_array_tIKNS_11HBGlyphID24EERK8hb_map_tL24hb_function_sortedness_t0ELPv0EETnPN12hb_enable_ifIXsr15hb_is_source_ofIT_jEE5valueEvE4typeELSF_0EEEbP22hb_serialize_context_tSI_ Line | Count | Source | 136 | 1.97k | { | 137 | 1.97k | TRACE_SERIALIZE (this); | 138 | 1.97k | return_trace (substitute.serialize (c, subst)); | 139 | 1.97k | } |
|
140 | | |
141 | | bool subset (hb_subset_context_t *c) const |
142 | 42.0k | { |
143 | 42.0k | TRACE_SUBSET (this); |
144 | 42.0k | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); |
145 | 42.0k | const hb_map_t &glyph_map = *c->plan->glyph_map; |
146 | | |
147 | 42.0k | if (!intersects (&glyphset)) return_trace (false); |
148 | | |
149 | 21.4k | auto it = |
150 | 21.4k | + hb_iter (substitute) |
151 | 21.4k | | hb_map (glyph_map) |
152 | 21.4k | ; |
153 | | |
154 | 21.4k | auto *out = c->serializer->start_embed (*this); |
155 | 21.4k | return_trace (out->serialize (c->serializer, it)); |
156 | 42.0k | } OT::Layout::GSUB_impl::Sequence<OT::Layout::SmallTypes>::subset(hb_subset_context_t*) const Line | Count | Source | 142 | 39.3k | { | 143 | 39.3k | TRACE_SUBSET (this); | 144 | 39.3k | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); | 145 | 39.3k | const hb_map_t &glyph_map = *c->plan->glyph_map; | 146 | | | 147 | 39.3k | if (!intersects (&glyphset)) return_trace (false); | 148 | | | 149 | 19.4k | auto it = | 150 | 19.4k | + hb_iter (substitute) | 151 | 19.4k | | hb_map (glyph_map) | 152 | 19.4k | ; | 153 | | | 154 | 19.4k | auto *out = c->serializer->start_embed (*this); | 155 | 19.4k | return_trace (out->serialize (c->serializer, it)); | 156 | 39.3k | } |
OT::Layout::GSUB_impl::Sequence<OT::Layout::MediumTypes>::subset(hb_subset_context_t*) const Line | Count | Source | 142 | 2.67k | { | 143 | 2.67k | TRACE_SUBSET (this); | 144 | 2.67k | const hb_set_t &glyphset = *c->plan->glyphset_gsub (); | 145 | 2.67k | const hb_map_t &glyph_map = *c->plan->glyph_map; | 146 | | | 147 | 2.67k | if (!intersects (&glyphset)) return_trace (false); | 148 | | | 149 | 1.97k | auto it = | 150 | 1.97k | + hb_iter (substitute) | 151 | 1.97k | | hb_map (glyph_map) | 152 | 1.97k | ; | 153 | | | 154 | 1.97k | auto *out = c->serializer->start_embed (*this); | 155 | 1.97k | return_trace (out->serialize (c->serializer, it)); | 156 | 2.67k | } |
|
157 | | }; |
158 | | |
159 | | |
160 | | } |
161 | | } |
162 | | } |
163 | | |
164 | | |
165 | | #endif /* OT_LAYOUT_GSUB_SEQUENCE_HH */ |