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 Google, Inc. | 3 * Copyright © 2010,2012 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 13 matching lines...) Expand all Loading... |
24 * | 24 * |
25 * Red Hat Author(s): Behdad Esfahbod | 25 * Red Hat Author(s): Behdad Esfahbod |
26 * Google Author(s): Behdad Esfahbod | 26 * Google Author(s): Behdad Esfahbod |
27 */ | 27 */ |
28 | 28 |
29 #ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH | 29 #ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH |
30 #define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH | 30 #define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH |
31 | 31 |
32 #include "hb-buffer-private.hh" | 32 #include "hb-buffer-private.hh" |
33 #include "hb-ot-layout-gdef-table.hh" | 33 #include "hb-ot-layout-gdef-table.hh" |
| 34 #include "hb-set-private.hh" |
34 | 35 |
35 | 36 |
36 | 37 namespace OT { |
37 /* unique ligature id */ | |
38 /* component number in the ligature (0 = base) */ | |
39 static inline void | |
40 set_lig_props (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp
) | |
41 { | |
42 info.lig_props() = (lig_id << 4) | (lig_comp & 0x0F); | |
43 } | |
44 static inline unsigned int | |
45 get_lig_id (hb_glyph_info_t &info) | |
46 { | |
47 return info.lig_props() >> 4; | |
48 } | |
49 static inline unsigned int | |
50 get_lig_comp (hb_glyph_info_t &info) | |
51 { | |
52 return info.lig_props() & 0x0F; | |
53 } | |
54 | |
55 static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { | |
56 uint8_t lig_id = buffer->next_serial () & 0x0F; | |
57 if (unlikely (!lig_id)) | |
58 lig_id = allocate_lig_id (buffer); /* in case of overflow */ | |
59 return lig_id; | |
60 } | |
61 | |
62 | 38 |
63 | 39 |
64 #ifndef HB_DEBUG_CLOSURE | 40 #ifndef HB_DEBUG_CLOSURE |
65 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) | 41 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) |
66 #endif | 42 #endif |
67 | 43 |
68 #define TRACE_CLOSURE() \ | 44 #define TRACE_CLOSURE() \ |
69 hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", thi
s, HB_FUNC, ""); | 45 hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", thi
s, HB_FUNC, ""); |
70 | 46 |
71 | 47 |
72 /* TODO Add TRACE_RETURN annotation for would_apply */ | |
73 | |
74 | |
75 struct hb_closure_context_t | 48 struct hb_closure_context_t |
76 { | 49 { |
77 hb_face_t *face; | 50 hb_face_t *face; |
78 hb_set_t *glyphs; | 51 hb_set_t *glyphs; |
79 unsigned int nesting_level_left; | 52 unsigned int nesting_level_left; |
80 unsigned int debug_depth; | 53 unsigned int debug_depth; |
81 | 54 |
82 | 55 |
83 hb_closure_context_t (hb_face_t *face_, | 56 hb_closure_context_t (hb_face_t *face_, |
84 hb_set_t *glyphs_, | 57 hb_set_t *glyphs_, |
85 unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : | 58 unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : |
86 » » » face (face_), glyphs (glyphs_), | 59 » » » face (face_), |
| 60 » » » glyphs (glyphs_), |
87 nesting_level_left (nesting_level_left_), | 61 nesting_level_left (nesting_level_left_), |
88 debug_depth (0) {} | 62 debug_depth (0) {} |
89 }; | 63 }; |
90 | 64 |
91 | 65 |
92 | 66 |
| 67 /* TODO Add TRACE_RETURN annotation to gsub. */ |
| 68 #ifndef HB_DEBUG_WOULD_APPLY |
| 69 #define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) |
| 70 #endif |
| 71 |
| 72 #define TRACE_WOULD_APPLY() \ |
| 73 hb_auto_trace_t<HB_DEBUG_WOULD_APPLY> trace (&c->debug_depth, "WOULD_APP
LY", this, HB_FUNC, "%d glyphs", c->len); |
| 74 |
| 75 |
| 76 struct hb_would_apply_context_t |
| 77 { |
| 78 hb_face_t *face; |
| 79 const hb_codepoint_t *glyphs; |
| 80 unsigned int len; |
| 81 bool zero_context; |
| 82 unsigned int debug_depth; |
| 83 |
| 84 hb_would_apply_context_t (hb_face_t *face_, |
| 85 const hb_codepoint_t *glyphs_, |
| 86 unsigned int len_, |
| 87 bool zero_context_) : |
| 88 face (face_), |
| 89 glyphs (glyphs_), |
| 90 len (len_), |
| 91 zero_context (zero_context_), |
| 92 debug_depth (0) {}; |
| 93 }; |
| 94 |
| 95 |
93 #ifndef HB_DEBUG_APPLY | 96 #ifndef HB_DEBUG_APPLY |
94 #define HB_DEBUG_APPLY (HB_DEBUG+0) | 97 #define HB_DEBUG_APPLY (HB_DEBUG+0) |
95 #endif | 98 #endif |
96 | 99 |
97 #define TRACE_APPLY() \ | 100 #define TRACE_APPLY() \ |
98 » hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, H
B_FUNC, "idx %d codepoint %u", c->buffer->cur().codepoint); | 101 » hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, H
B_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); |
99 | |
100 | 102 |
101 | 103 |
102 struct hb_apply_context_t | 104 struct hb_apply_context_t |
103 { | 105 { |
104 hb_font_t *font; | 106 hb_font_t *font; |
105 hb_face_t *face; | 107 hb_face_t *face; |
106 hb_buffer_t *buffer; | 108 hb_buffer_t *buffer; |
107 hb_direction_t direction; | 109 hb_direction_t direction; |
108 hb_mask_t lookup_mask; | 110 hb_mask_t lookup_mask; |
109 unsigned int nesting_level_left; | 111 unsigned int nesting_level_left; |
110 unsigned int lookup_props; | 112 unsigned int lookup_props; |
111 unsigned int property; /* propety of first glyph */ | 113 unsigned int property; /* propety of first glyph */ |
112 unsigned int debug_depth; | 114 unsigned int debug_depth; |
| 115 const GDEF &gdef; |
| 116 bool has_glyph_classes; |
113 | 117 |
114 | 118 |
115 hb_apply_context_t (hb_font_t *font_, | 119 hb_apply_context_t (hb_font_t *font_, |
116 hb_face_t *face_, | |
117 hb_buffer_t *buffer_, | 120 hb_buffer_t *buffer_, |
118 hb_mask_t lookup_mask_) : | 121 hb_mask_t lookup_mask_) : |
119 » » » font (font_), face (face_), buffer (buffer_), | 122 » » » font (font_), face (font->face), buffer (buffer_), |
120 direction (buffer_->props.direction), | 123 direction (buffer_->props.direction), |
121 lookup_mask (lookup_mask_), | 124 lookup_mask (lookup_mask_), |
122 nesting_level_left (MAX_NESTING_LEVEL), | 125 nesting_level_left (MAX_NESTING_LEVEL), |
123 » » » lookup_props (0), property (0), debug_depth (0) {} | 126 » » » lookup_props (0), property (0), debug_depth (0), |
| 127 » » » gdef (*hb_ot_layout_from_face (face)->gdef), |
| 128 » » » has_glyph_classes (gdef.has_glyph_classes ()) {} |
| 129 |
| 130 void set_lookup_props (unsigned int lookup_props_) { |
| 131 lookup_props = lookup_props_; |
| 132 } |
124 | 133 |
125 void set_lookup (const Lookup &l) { | 134 void set_lookup (const Lookup &l) { |
126 lookup_props = l.get_props (); | 135 lookup_props = l.get_props (); |
127 } | 136 } |
128 | 137 |
129 struct mark_skipping_forward_iterator_t | 138 struct mark_skipping_forward_iterator_t |
130 { | 139 { |
131 inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, | 140 inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, |
132 unsigned int start_index_, | 141 unsigned int start_index_, |
133 unsigned int num_items_, | 142 unsigned int num_items_, |
134 bool context_match = false) | 143 bool context_match = false) |
135 { | 144 { |
136 c = c_; | 145 c = c_; |
137 idx = start_index_; | 146 idx = start_index_; |
138 num_items = num_items_; | 147 num_items = num_items_; |
139 mask = context_match ? -1 : c->lookup_mask; | 148 mask = context_match ? -1 : c->lookup_mask; |
140 syllable = context_match ? 0 : c->buffer->cur().syllable (); | 149 syllable = context_match ? 0 : c->buffer->cur().syllable (); |
141 end = c->buffer->len; | 150 end = c->buffer->len; |
142 } | 151 } |
143 inline bool has_no_chance (void) const | 152 inline bool has_no_chance (void) const |
144 { | 153 { |
145 return unlikely (num_items && idx + num_items >= end); | 154 return unlikely (num_items && idx + num_items >= end); |
146 } | 155 } |
| 156 inline void reject (void) |
| 157 { |
| 158 num_items++; |
| 159 } |
147 inline bool next (unsigned int *property_out, | 160 inline bool next (unsigned int *property_out, |
148 » » unsigned int lookup_props) | 161 » » unsigned int lookup_props) |
149 { | 162 { |
150 assert (num_items > 0); | 163 assert (num_items > 0); |
151 do | 164 do |
152 { | 165 { |
153 if (has_no_chance ()) | 166 if (has_no_chance ()) |
154 return false; | 167 return false; |
155 idx++; | 168 idx++; |
156 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[idx], lookup_p
rops, property_out)); | 169 } while (c->should_skip_mark (&c->buffer->info[idx], lookup_props, propert
y_out)); |
157 num_items--; | 170 num_items--; |
158 return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->
buffer->info[idx].syllable ()); | 171 return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->
buffer->info[idx].syllable ()); |
159 } | 172 } |
160 inline bool next (unsigned int *property_out = NULL) | 173 inline bool next (unsigned int *property_out = NULL) |
161 { | 174 { |
162 return next (property_out, c->lookup_props); | 175 return next (property_out, c->lookup_props); |
163 } | 176 } |
164 | 177 |
165 unsigned int idx; | 178 unsigned int idx; |
166 private: | 179 protected: |
167 hb_apply_context_t *c; | 180 hb_apply_context_t *c; |
168 unsigned int num_items; | 181 unsigned int num_items; |
169 hb_mask_t mask; | 182 hb_mask_t mask; |
170 uint8_t syllable; | 183 uint8_t syllable; |
171 unsigned int end; | 184 unsigned int end; |
172 }; | 185 }; |
173 | 186 |
174 struct mark_skipping_backward_iterator_t | 187 struct mark_skipping_backward_iterator_t |
175 { | 188 { |
176 inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, | 189 inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, |
177 unsigned int start_index_, | 190 unsigned int start_index_, |
178 unsigned int num_items_, | 191 unsigned int num_items_, |
179 hb_mask_t mask_ = 0, | 192 hb_mask_t mask_ = 0, |
180 bool match_syllable_ = true) | 193 bool match_syllable_ = true) |
181 { | 194 { |
182 c = c_; | 195 c = c_; |
183 idx = start_index_; | 196 idx = start_index_; |
184 num_items = num_items_; | 197 num_items = num_items_; |
185 mask = mask_ ? mask_ : c->lookup_mask; | 198 mask = mask_ ? mask_ : c->lookup_mask; |
186 syllable = match_syllable_ ? c->buffer->cur().syllable () : 0; | 199 syllable = match_syllable_ ? c->buffer->cur().syllable () : 0; |
187 } | 200 } |
188 inline bool has_no_chance (void) const | 201 inline bool has_no_chance (void) const |
189 { | 202 { |
190 return unlikely (idx < num_items); | 203 return unlikely (idx < num_items); |
191 } | 204 } |
| 205 inline void reject (void) |
| 206 { |
| 207 num_items++; |
| 208 } |
192 inline bool prev (unsigned int *property_out, | 209 inline bool prev (unsigned int *property_out, |
193 » » unsigned int lookup_props) | 210 » » unsigned int lookup_props) |
194 { | 211 { |
195 assert (num_items > 0); | 212 assert (num_items > 0); |
196 do | 213 do |
197 { | 214 { |
198 if (has_no_chance ()) | 215 if (has_no_chance ()) |
199 return false; | 216 return false; |
200 idx--; | 217 idx--; |
201 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[idx], look
up_props, property_out)); | 218 } while (c->should_skip_mark (&c->buffer->out_info[idx], lookup_props, pro
perty_out)); |
202 num_items--; | 219 num_items--; |
203 return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable ==
c->buffer->out_info[idx].syllable ()); | 220 return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable ==
c->buffer->out_info[idx].syllable ()); |
204 } | 221 } |
205 inline bool prev (unsigned int *property_out = NULL) | 222 inline bool prev (unsigned int *property_out = NULL) |
206 { | 223 { |
207 return prev (property_out, c->lookup_props); | 224 return prev (property_out, c->lookup_props); |
208 } | 225 } |
209 | 226 |
210 unsigned int idx; | 227 unsigned int idx; |
211 private: | 228 protected: |
212 hb_apply_context_t *c; | 229 hb_apply_context_t *c; |
213 unsigned int num_items; | 230 unsigned int num_items; |
214 hb_mask_t mask; | 231 hb_mask_t mask; |
215 uint8_t syllable; | 232 uint8_t syllable; |
216 }; | 233 }; |
217 | 234 |
218 inline bool should_mark_skip_current_glyph (void) const | 235 inline bool |
| 236 match_properties_mark (hb_codepoint_t glyph, |
| 237 » » » unsigned int glyph_props, |
| 238 » » » unsigned int lookup_props) const |
219 { | 239 { |
220 return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, NULL); | 240 /* If using mark filtering sets, the high short of |
| 241 * lookup_props has the set index. |
| 242 */ |
| 243 if (lookup_props & LookupFlag::UseMarkFilteringSet) |
| 244 return gdef.mark_set_covers (lookup_props >> 16, glyph); |
| 245 |
| 246 /* The second byte of lookup_props has the meaning |
| 247 * "ignore marks of attachment type different than |
| 248 * the attachment type specified." |
| 249 */ |
| 250 if (lookup_props & LookupFlag::MarkAttachmentType) |
| 251 return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & L
ookupFlag::MarkAttachmentType); |
| 252 |
| 253 return true; |
| 254 } |
| 255 |
| 256 inline bool |
| 257 match_properties (hb_codepoint_t glyph, |
| 258 » » unsigned int glyph_props, |
| 259 » » unsigned int lookup_props) const |
| 260 { |
| 261 /* Not covered, if, for example, glyph class is ligature and |
| 262 * lookup_props includes LookupFlags::IgnoreLigatures |
| 263 */ |
| 264 if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) |
| 265 return false; |
| 266 |
| 267 if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) |
| 268 return match_properties_mark (glyph, glyph_props, lookup_props); |
| 269 |
| 270 return true; |
| 271 } |
| 272 |
| 273 inline bool |
| 274 check_glyph_property (hb_glyph_info_t *info, |
| 275 » » » unsigned int lookup_props, |
| 276 » » » unsigned int *property_out) const |
| 277 { |
| 278 unsigned int property; |
| 279 |
| 280 property = info->glyph_props(); |
| 281 *property_out = property; |
| 282 |
| 283 return match_properties (info->codepoint, property, lookup_props); |
| 284 } |
| 285 |
| 286 inline bool |
| 287 should_skip_mark (hb_glyph_info_t *info, |
| 288 » » unsigned int lookup_props, |
| 289 » » unsigned int *property_out) const |
| 290 { |
| 291 unsigned int property; |
| 292 |
| 293 property = info->glyph_props(); |
| 294 if (property_out) |
| 295 *property_out = property; |
| 296 |
| 297 /* If it's a mark, skip it if we don't accept it. */ |
| 298 if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) |
| 299 return !match_properties (info->codepoint, property, lookup_props); |
| 300 |
| 301 /* If not a mark, don't skip. */ |
| 302 return false; |
221 } | 303 } |
222 | 304 |
223 | 305 |
| 306 inline bool should_mark_skip_current_glyph (void) const |
| 307 { |
| 308 return should_skip_mark (&buffer->cur(), lookup_props, NULL); |
| 309 } |
224 | 310 |
| 311 inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) c
onst |
| 312 { |
| 313 if (likely (has_glyph_classes)) |
| 314 buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index); |
| 315 else if (class_guess) |
| 316 buffer->cur().glyph_props() = class_guess; |
| 317 } |
| 318 |
| 319 inline void output_glyph (hb_codepoint_t glyph_index, |
| 320 unsigned int class_guess = 0) const |
| 321 { |
| 322 set_class (glyph_index, class_guess); |
| 323 buffer->output_glyph (glyph_index); |
| 324 } |
225 inline void replace_glyph (hb_codepoint_t glyph_index, | 325 inline void replace_glyph (hb_codepoint_t glyph_index, |
226 » » » unsigned int klass = 0) const | 326 » » » unsigned int class_guess = 0) const |
227 { | 327 { |
228 buffer->cur().props_cache() = klass; /*XXX if has gdef? */ | 328 set_class (glyph_index, class_guess); |
229 buffer->replace_glyph (glyph_index); | 329 buffer->replace_glyph (glyph_index); |
230 } | 330 } |
231 inline void replace_glyphs_be16 (unsigned int num_in, | 331 inline void replace_glyph_inplace (hb_codepoint_t glyph_index, |
232 » » » » unsigned int num_out, | 332 » » » » unsigned int class_guess = 0) const |
233 » » » » const char *glyph_data_be, | |
234 » » » » unsigned int klass = 0) const | |
235 { | 333 { |
236 buffer->cur().props_cache() = klass; /* XXX if has gdef? */ | 334 set_class (glyph_index, class_guess); |
237 buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be); | 335 buffer->cur().codepoint = glyph_index; |
238 } | 336 } |
239 }; | 337 }; |
240 | 338 |
241 | 339 |
242 | 340 |
243 typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const
void *data); | 341 typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const
void *data); |
244 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, cons
t void *data); | 342 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, cons
t void *data); |
245 typedef void (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int loo
kup_index); | 343 typedef void (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int loo
kup_index); |
246 typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_
index); | 344 typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_
index); |
247 | 345 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); | 391 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
294 return class_def.get_class (glyph_id) == value; | 392 return class_def.get_class (glyph_id) == value; |
295 } | 393 } |
296 static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
const void *data) | 394 static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
const void *data) |
297 { | 395 { |
298 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; | 396 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
299 return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; | 397 return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; |
300 } | 398 } |
301 | 399 |
302 | 400 |
| 401 static inline bool would_match_input (hb_would_apply_context_t *c, |
| 402 unsigned int count, /* Including the first
glyph (not matched) */ |
| 403 const USHORT input[], /* Array of input va
lues--start with second glyph */ |
| 404 match_func_t match_func, |
| 405 const void *match_data) |
| 406 { |
| 407 if (count != c->len) |
| 408 return false; |
| 409 |
| 410 for (unsigned int i = 1; i < count; i++) |
| 411 if (likely (!match_func (c->glyphs[i], input[i - 1], match_data))) |
| 412 return false; |
| 413 |
| 414 return true; |
| 415 } |
303 static inline bool match_input (hb_apply_context_t *c, | 416 static inline bool match_input (hb_apply_context_t *c, |
304 unsigned int count, /* Including the first glyph
(not matched) */ | 417 unsigned int count, /* Including the first glyph
(not matched) */ |
305 const USHORT input[], /* Array of input values--
start with second glyph */ | 418 const USHORT input[], /* Array of input values--
start with second glyph */ |
306 match_func_t match_func, | 419 match_func_t match_func, |
307 const void *match_data, | 420 const void *match_data, |
308 » » » » unsigned int *end_offset = NULL) | 421 » » » » unsigned int *end_offset = NULL, |
| 422 » » » » bool *p_is_mark_ligature = NULL, |
| 423 » » » » unsigned int *p_total_component_count = NULL) |
309 { | 424 { |
| 425 hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC
, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); |
| 426 |
310 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx, count - 1); | 427 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx, count - 1); |
311 if (skippy_iter.has_no_chance ()) | 428 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); |
312 return false; | 429 |
| 430 /* |
| 431 * This is perhaps the trickiest part of OpenType... Remarks: |
| 432 * |
| 433 * - If all components of the ligature were marks, we call this a mark ligatur
e. |
| 434 * |
| 435 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori
ze |
| 436 * it as a ligature glyph. |
| 437 * |
| 438 * - Ligatures cannot be formed across glyphs attached to different components |
| 439 * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and |
| 440 * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. |
| 441 * However, it would be wrong to ligate that SHADDA,FATHA sequence.o |
| 442 * There is an exception to this: If a ligature tries ligating with marks th
at |
| 443 * belong to it itself, go ahead, assuming that the font designer knows what |
| 444 * they are doing (otherwise it can break Indic stuff when a matra wants to |
| 445 * ligate with a conjunct...) |
| 446 */ |
| 447 |
| 448 bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK); |
| 449 |
| 450 unsigned int total_component_count = 0; |
| 451 total_component_count += get_lig_num_comps (c->buffer->cur()); |
| 452 |
| 453 unsigned int first_lig_id = get_lig_id (c->buffer->cur()); |
| 454 unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); |
313 | 455 |
314 for (unsigned int i = 1; i < count; i++) | 456 for (unsigned int i = 1; i < count; i++) |
315 { | 457 { |
316 if (!skippy_iter.next ()) | 458 unsigned int property; |
317 return false; | |
318 | 459 |
319 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i
- 1], match_data))) | 460 if (!skippy_iter.next (&property)) return TRACE_RETURN (false); |
320 return false; | 461 |
| 462 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i
- 1], match_data))) return false; |
| 463 |
| 464 unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); |
| 465 unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx])
; |
| 466 |
| 467 if (first_lig_id && first_lig_comp) { |
| 468 /* If first component was attached to a previous ligature component, |
| 469 * all subsequent components should be attached to the same ligature |
| 470 * component, otherwise we shouldn't ligate them. */ |
| 471 if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) |
| 472 » return TRACE_RETURN (false); |
| 473 } else { |
| 474 /* If first component was NOT attached to a previous ligature component, |
| 475 * all subsequent components should also NOT be attached to any ligature |
| 476 * component, unless they are attached to the first component itself! */ |
| 477 if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) |
| 478 » return TRACE_RETURN (false); |
| 479 } |
| 480 |
| 481 is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_CLASS_
MARK); |
| 482 total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]
); |
321 } | 483 } |
322 | 484 |
323 if (end_offset) | 485 if (end_offset) |
324 *end_offset = skippy_iter.idx - c->buffer->idx + 1; | 486 *end_offset = skippy_iter.idx - c->buffer->idx + 1; |
325 | 487 |
| 488 if (p_is_mark_ligature) |
| 489 *p_is_mark_ligature = is_mark_ligature; |
| 490 |
| 491 if (p_total_component_count) |
| 492 *p_total_component_count = total_component_count; |
| 493 |
326 return true; | 494 return true; |
327 } | 495 } |
| 496 static inline void ligate_input (hb_apply_context_t *c, |
| 497 unsigned int count, /* Including the first glyp
h (not matched) */ |
| 498 const USHORT input[], /* Array of input values-
-start with second glyph */ |
| 499 hb_codepoint_t lig_glyph, |
| 500 match_func_t match_func, |
| 501 const void *match_data, |
| 502 bool is_mark_ligature, |
| 503 unsigned int total_component_count) |
| 504 { |
| 505 /* |
| 506 * - If it *is* a mark ligature, we don't allocate a new ligature id, and leav
e |
| 507 * the ligature to keep its old ligature id. This will allow it to attach t
o |
| 508 * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HE
H, |
| 509 * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a |
| 510 * ligature id and component value of 2. Then if SHADDA,FATHA form a ligatu
re |
| 511 * later, we don't want them to lose their ligature id/component, otherwise |
| 512 * GPOS will fail to correctly position the mark ligature on top of the |
| 513 * LAM,LAM,HEH ligature. See: |
| 514 * https://bugzilla.gnome.org/show_bug.cgi?id=676343 |
| 515 * |
| 516 * - If a ligature is formed of components that some of which are also ligatur
es |
| 517 * themselves, and those ligature components had marks attached to *their* |
| 518 * components, we have to attach the marks to the new ligature component |
| 519 * positions! Now *that*'s tricky! And these marks may be following the |
| 520 * last component of the whole sequence, so we should loop forward looking |
| 521 * for them and update them. |
| 522 * |
| 523 * Eg. the sequence is LAM,LAM,SHADDA,FATHA,HEH, and the font first forms a |
| 524 * 'calt' ligature of LAM,HEH, leaving the SHADDA and FATHA with a ligature |
| 525 * id and component == 1. Now, during 'liga', the LAM and the LAM-HEH ligat
ure |
| 526 * form a LAM-LAM-HEH ligature. We need to reassign the SHADDA and FATHA to |
| 527 * the new ligature with a component value of 2. |
| 528 * |
| 529 * This in fact happened to a font... See: |
| 530 * https://bugzilla.gnome.org/show_bug.cgi?id=437633 |
| 531 */ |
| 532 |
| 533 unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE; |
| 534 unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer); |
| 535 unsigned int last_lig_id = get_lig_id (c->buffer->cur()); |
| 536 unsigned int last_num_components = get_lig_num_comps (c->buffer->cur()); |
| 537 unsigned int components_so_far = last_num_components; |
| 538 |
| 539 if (!is_mark_ligature) |
| 540 set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count)
; |
| 541 c->replace_glyph (lig_glyph, klass); |
| 542 |
| 543 for (unsigned int i = 1; i < count; i++) |
| 544 { |
| 545 while (c->should_mark_skip_current_glyph ()) |
| 546 { |
| 547 if (!is_mark_ligature) { |
| 548 unsigned int new_lig_comp = components_so_far - last_num_components + |
| 549 MIN (MAX (get_lig_comp (c->buffer->cur()), 1
u), last_num_components); |
| 550 set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp); |
| 551 } |
| 552 c->buffer->next_glyph (); |
| 553 } |
| 554 |
| 555 last_lig_id = get_lig_id (c->buffer->cur()); |
| 556 last_num_components = get_lig_num_comps (c->buffer->cur()); |
| 557 components_so_far += last_num_components; |
| 558 |
| 559 /* Skip the base glyph */ |
| 560 c->buffer->idx++; |
| 561 } |
| 562 |
| 563 if (!is_mark_ligature && last_lig_id) { |
| 564 /* Re-adjust components for any marks following. */ |
| 565 for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) { |
| 566 if (last_lig_id == get_lig_id (c->buffer->info[i])) { |
| 567 unsigned int new_lig_comp = components_so_far - last_num_components + |
| 568 MIN (MAX (get_lig_comp (c->buffer->info[i]),
1u), last_num_components); |
| 569 set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp); |
| 570 } else |
| 571 break; |
| 572 } |
| 573 } |
| 574 } |
328 | 575 |
329 static inline bool match_backtrack (hb_apply_context_t *c, | 576 static inline bool match_backtrack (hb_apply_context_t *c, |
330 unsigned int count, | 577 unsigned int count, |
331 const USHORT backtrack[], | 578 const USHORT backtrack[], |
332 match_func_t match_func, | 579 match_func_t match_func, |
333 const void *match_data) | 580 const void *match_data) |
334 { | 581 { |
| 582 hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC
, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); |
| 583 |
335 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffe
r->backtrack_len (), count, true); | 584 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffe
r->backtrack_len (), count, true); |
336 if (skippy_iter.has_no_chance ()) | 585 if (skippy_iter.has_no_chance ()) |
337 return false; | 586 return TRACE_RETURN (false); |
338 | 587 |
339 for (unsigned int i = 0; i < count; i++) | 588 for (unsigned int i = 0; i < count; i++) |
340 { | 589 { |
341 if (!skippy_iter.prev ()) | 590 if (!skippy_iter.prev ()) |
342 return false; | 591 return TRACE_RETURN (false); |
343 | 592 |
344 if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, bac
ktrack[i], match_data))) | 593 if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, bac
ktrack[i], match_data))) |
345 return false; | 594 return TRACE_RETURN (false); |
346 } | 595 } |
347 | 596 |
348 return true; | 597 return TRACE_RETURN (true); |
349 } | 598 } |
350 | 599 |
351 static inline bool match_lookahead (hb_apply_context_t *c, | 600 static inline bool match_lookahead (hb_apply_context_t *c, |
352 unsigned int count, | 601 unsigned int count, |
353 const USHORT lookahead[], | 602 const USHORT lookahead[], |
354 match_func_t match_func, | 603 match_func_t match_func, |
355 const void *match_data, | 604 const void *match_data, |
356 unsigned int offset) | 605 unsigned int offset) |
357 { | 606 { |
| 607 hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC
, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); |
| 608 |
358 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx + offset - 1, count, true); | 609 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx + offset - 1, count, true); |
359 if (skippy_iter.has_no_chance ()) | 610 if (skippy_iter.has_no_chance ()) |
360 return false; | 611 return TRACE_RETURN (false); |
361 | 612 |
362 for (unsigned int i = 0; i < count; i++) | 613 for (unsigned int i = 0; i < count; i++) |
363 { | 614 { |
364 if (!skippy_iter.next ()) | 615 if (!skippy_iter.next ()) |
365 return false; | 616 return TRACE_RETURN (false); |
366 | 617 |
367 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahe
ad[i], match_data))) | 618 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahe
ad[i], match_data))) |
368 return false; | 619 return TRACE_RETURN (false); |
369 } | 620 } |
370 | 621 |
371 return true; | 622 return TRACE_RETURN (true); |
372 } | 623 } |
373 | 624 |
374 | 625 |
375 | 626 |
376 struct LookupRecord | 627 struct LookupRecord |
377 { | 628 { |
378 inline bool sanitize (hb_sanitize_context_t *c) { | 629 inline bool sanitize (hb_sanitize_context_t *c) { |
379 TRACE_SANITIZE (); | 630 TRACE_SANITIZE (); |
380 return TRACE_RETURN (c->check_struct (this)); | 631 return TRACE_RETURN (c->check_struct (this)); |
381 } | 632 } |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 { | 732 { |
482 if (intersects_array (c, | 733 if (intersects_array (c, |
483 inputCount ? inputCount - 1 : 0, input, | 734 inputCount ? inputCount - 1 : 0, input, |
484 lookup_context.funcs.intersects, lookup_context.intersec
ts_data)) | 735 lookup_context.funcs.intersects, lookup_context.intersec
ts_data)) |
485 closure_lookup (c, | 736 closure_lookup (c, |
486 lookupCount, lookupRecord, | 737 lookupCount, lookupRecord, |
487 lookup_context.funcs.closure); | 738 lookup_context.funcs.closure); |
488 } | 739 } |
489 | 740 |
490 | 741 |
| 742 static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, |
| 743 unsigned int inputCount, /* Inclu
ding the first glyph (not matched) */ |
| 744 const USHORT input[], /* Array of
input values--start with second glyph */ |
| 745 unsigned int lookupCount, |
| 746 const LookupRecord lookupRecord[]
, |
| 747 ContextApplyLookupContext &lookup
_context) |
| 748 { |
| 749 return would_match_input (c, |
| 750 inputCount, input, |
| 751 lookup_context.funcs.match, lookup_context.match_dat
a); |
| 752 } |
491 static inline bool context_apply_lookup (hb_apply_context_t *c, | 753 static inline bool context_apply_lookup (hb_apply_context_t *c, |
492 unsigned int inputCount, /* Including t
he first glyph (not matched) */ | 754 unsigned int inputCount, /* Including t
he first glyph (not matched) */ |
493 const USHORT input[], /* Array of input
values--start with second glyph */ | 755 const USHORT input[], /* Array of input
values--start with second glyph */ |
494 unsigned int lookupCount, | 756 unsigned int lookupCount, |
495 const LookupRecord lookupRecord[], | 757 const LookupRecord lookupRecord[], |
496 ContextApplyLookupContext &lookup_conte
xt) | 758 ContextApplyLookupContext &lookup_conte
xt) |
497 { | 759 { |
498 return match_input (c, | 760 return match_input (c, |
499 inputCount, input, | 761 inputCount, input, |
500 lookup_context.funcs.match, lookup_context.match_data) | 762 lookup_context.funcs.match, lookup_context.match_data) |
(...skipping 12 matching lines...) Expand all Loading... |
513 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const | 775 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const |
514 { | 776 { |
515 TRACE_CLOSURE (); | 777 TRACE_CLOSURE (); |
516 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); | 778 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); |
517 context_closure_lookup (c, | 779 context_closure_lookup (c, |
518 inputCount, input, | 780 inputCount, input, |
519 lookupCount, lookupRecord, | 781 lookupCount, lookupRecord, |
520 lookup_context); | 782 lookup_context); |
521 } | 783 } |
522 | 784 |
| 785 inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContex
t &lookup_context) const |
| 786 { |
| 787 TRACE_WOULD_APPLY (); |
| 788 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); |
| 789 return TRACE_RETURN (context_would_apply_lookup (c, inputCount, input, looku
pCount, lookupRecord, lookup_context)); |
| 790 } |
| 791 |
523 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const | 792 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const |
524 { | 793 { |
525 TRACE_APPLY (); | 794 TRACE_APPLY (); |
526 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); | 795 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); |
527 return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount
, lookupRecord, lookup_context)); | 796 return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount
, lookupRecord, lookup_context)); |
528 } | 797 } |
529 | 798 |
530 public: | 799 public: |
531 inline bool sanitize (hb_sanitize_context_t *c) { | 800 inline bool sanitize (hb_sanitize_context_t *c) { |
532 TRACE_SANITIZE (); | 801 TRACE_SANITIZE (); |
533 return inputCount.sanitize (c) | 802 return inputCount.sanitize (c) |
534 && lookupCount.sanitize (c) | 803 && lookupCount.sanitize (c) |
535 && c->check_range (input, | 804 && c->check_range (input, |
536 input[0].static_size * inputCount | 805 input[0].static_size * inputCount |
537 + lookupRecordX[0].static_size * lookupCount); | 806 + lookupRecordX[0].static_size * lookupCount); |
538 } | 807 } |
539 | 808 |
540 private: | 809 protected: |
541 USHORT inputCount; /* Total number of glyphs in input | 810 USHORT inputCount; /* Total number of glyphs in input |
542 * glyph sequence--includes the first | 811 * glyph sequence--includes the first |
543 * glyph */ | 812 * glyph */ |
544 USHORT lookupCount; /* Number of LookupRecords */ | 813 USHORT lookupCount; /* Number of LookupRecords */ |
545 USHORT input[VAR]; /* Array of match inputs--start with | 814 USHORT input[VAR]; /* Array of match inputs--start with |
546 * second glyph */ | 815 * second glyph */ |
547 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in | 816 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
548 * design order */ | 817 * design order */ |
549 public: | 818 public: |
550 DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); | 819 DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); |
551 }; | 820 }; |
552 | 821 |
553 struct RuleSet | 822 struct RuleSet |
554 { | 823 { |
555 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const | 824 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const |
556 { | 825 { |
557 TRACE_CLOSURE (); | 826 TRACE_CLOSURE (); |
558 unsigned int num_rules = rule.len; | 827 unsigned int num_rules = rule.len; |
559 for (unsigned int i = 0; i < num_rules; i++) | 828 for (unsigned int i = 0; i < num_rules; i++) |
560 (this+rule[i]).closure (c, lookup_context); | 829 (this+rule[i]).closure (c, lookup_context); |
561 } | 830 } |
562 | 831 |
| 832 inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContex
t &lookup_context) const |
| 833 { |
| 834 TRACE_WOULD_APPLY (); |
| 835 unsigned int num_rules = rule.len; |
| 836 for (unsigned int i = 0; i < num_rules; i++) |
| 837 { |
| 838 if ((this+rule[i]).would_apply (c, lookup_context)) |
| 839 return TRACE_RETURN (true); |
| 840 } |
| 841 return TRACE_RETURN (false); |
| 842 } |
| 843 |
563 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const | 844 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const |
564 { | 845 { |
565 TRACE_APPLY (); | 846 TRACE_APPLY (); |
566 unsigned int num_rules = rule.len; | 847 unsigned int num_rules = rule.len; |
567 for (unsigned int i = 0; i < num_rules; i++) | 848 for (unsigned int i = 0; i < num_rules; i++) |
568 { | 849 { |
569 if ((this+rule[i]).apply (c, lookup_context)) | 850 if ((this+rule[i]).apply (c, lookup_context)) |
570 return TRACE_RETURN (true); | 851 return TRACE_RETURN (true); |
571 } | 852 } |
572 return TRACE_RETURN (false); | 853 return TRACE_RETURN (false); |
573 } | 854 } |
574 | 855 |
575 inline bool sanitize (hb_sanitize_context_t *c) { | 856 inline bool sanitize (hb_sanitize_context_t *c) { |
576 TRACE_SANITIZE (); | 857 TRACE_SANITIZE (); |
577 return TRACE_RETURN (rule.sanitize (c, this)); | 858 return TRACE_RETURN (rule.sanitize (c, this)); |
578 } | 859 } |
579 | 860 |
580 private: | 861 protected: |
581 OffsetArrayOf<Rule> | 862 OffsetArrayOf<Rule> |
582 rule; /* Array of Rule tables | 863 rule; /* Array of Rule tables |
583 * ordered by preference */ | 864 * ordered by preference */ |
584 public: | 865 public: |
585 DEFINE_SIZE_ARRAY (2, rule); | 866 DEFINE_SIZE_ARRAY (2, rule); |
586 }; | 867 }; |
587 | 868 |
588 | 869 |
589 struct ContextFormat1 | 870 struct ContextFormat1 |
590 { | 871 { |
(...skipping 13 matching lines...) Expand all Loading... |
604 }; | 885 }; |
605 | 886 |
606 unsigned int count = ruleSet.len; | 887 unsigned int count = ruleSet.len; |
607 for (unsigned int i = 0; i < count; i++) | 888 for (unsigned int i = 0; i < count; i++) |
608 if (cov.intersects_coverage (c->glyphs, i)) { | 889 if (cov.intersects_coverage (c->glyphs, i)) { |
609 const RuleSet &rule_set = this+ruleSet[i]; | 890 const RuleSet &rule_set = this+ruleSet[i]; |
610 rule_set.closure (c, lookup_context); | 891 rule_set.closure (c, lookup_context); |
611 } | 892 } |
612 } | 893 } |
613 | 894 |
| 895 inline bool would_apply (hb_would_apply_context_t *c) const |
| 896 { |
| 897 TRACE_WOULD_APPLY (); |
| 898 |
| 899 const RuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])]; |
| 900 struct ContextApplyLookupContext lookup_context = { |
| 901 {match_glyph, NULL}, |
| 902 NULL |
| 903 }; |
| 904 return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); |
| 905 } |
| 906 |
614 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 907 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
615 { | 908 { |
616 TRACE_APPLY (); | 909 TRACE_APPLY (); |
617 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); | 910 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
618 if (likely (index == NOT_COVERED)) | 911 if (likely (index == NOT_COVERED)) |
619 return TRACE_RETURN (false); | 912 return TRACE_RETURN (false); |
620 | 913 |
621 const RuleSet &rule_set = this+ruleSet[index]; | 914 const RuleSet &rule_set = this+ruleSet[index]; |
622 struct ContextApplyLookupContext lookup_context = { | 915 struct ContextApplyLookupContext lookup_context = { |
623 {match_glyph, apply_func}, | 916 {match_glyph, apply_func}, |
624 NULL | 917 NULL |
625 }; | 918 }; |
626 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 919 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
627 } | 920 } |
628 | 921 |
629 inline bool sanitize (hb_sanitize_context_t *c) { | 922 inline bool sanitize (hb_sanitize_context_t *c) { |
630 TRACE_SANITIZE (); | 923 TRACE_SANITIZE (); |
631 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); | 924 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
632 } | 925 } |
633 | 926 |
634 private: | 927 protected: |
635 USHORT format; /* Format identifier--format = 1 */ | 928 USHORT format; /* Format identifier--format = 1 */ |
636 OffsetTo<Coverage> | 929 OffsetTo<Coverage> |
637 coverage; /* Offset to Coverage table--from | 930 coverage; /* Offset to Coverage table--from |
638 * beginning of table */ | 931 * beginning of table */ |
639 OffsetArrayOf<RuleSet> | 932 OffsetArrayOf<RuleSet> |
640 ruleSet; /* Array of RuleSet tables | 933 ruleSet; /* Array of RuleSet tables |
641 * ordered by Coverage Index */ | 934 * ordered by Coverage Index */ |
642 public: | 935 public: |
643 DEFINE_SIZE_ARRAY (6, ruleSet); | 936 DEFINE_SIZE_ARRAY (6, ruleSet); |
644 }; | 937 }; |
(...skipping 19 matching lines...) Expand all Loading... |
664 }; | 957 }; |
665 | 958 |
666 unsigned int count = ruleSet.len; | 959 unsigned int count = ruleSet.len; |
667 for (unsigned int i = 0; i < count; i++) | 960 for (unsigned int i = 0; i < count; i++) |
668 if (class_def.intersects_class (c->glyphs, i)) { | 961 if (class_def.intersects_class (c->glyphs, i)) { |
669 const RuleSet &rule_set = this+ruleSet[i]; | 962 const RuleSet &rule_set = this+ruleSet[i]; |
670 rule_set.closure (c, lookup_context); | 963 rule_set.closure (c, lookup_context); |
671 } | 964 } |
672 } | 965 } |
673 | 966 |
| 967 inline bool would_apply (hb_would_apply_context_t *c) const |
| 968 { |
| 969 TRACE_WOULD_APPLY (); |
| 970 |
| 971 const ClassDef &class_def = this+classDef; |
| 972 unsigned int index = class_def (c->glyphs[0]); |
| 973 const RuleSet &rule_set = this+ruleSet[index]; |
| 974 struct ContextApplyLookupContext lookup_context = { |
| 975 {match_class, NULL}, |
| 976 &class_def |
| 977 }; |
| 978 return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); |
| 979 } |
| 980 |
674 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 981 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
675 { | 982 { |
676 TRACE_APPLY (); | 983 TRACE_APPLY (); |
677 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); | 984 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
678 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 985 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
679 | 986 |
680 const ClassDef &class_def = this+classDef; | 987 const ClassDef &class_def = this+classDef; |
681 index = class_def (c->buffer->cur().codepoint); | 988 index = class_def (c->buffer->cur().codepoint); |
682 const RuleSet &rule_set = this+ruleSet[index]; | 989 const RuleSet &rule_set = this+ruleSet[index]; |
683 struct ContextApplyLookupContext lookup_context = { | 990 struct ContextApplyLookupContext lookup_context = { |
684 {match_class, apply_func}, | 991 {match_class, apply_func}, |
685 &class_def | 992 &class_def |
686 }; | 993 }; |
687 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 994 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
688 } | 995 } |
689 | 996 |
690 inline bool sanitize (hb_sanitize_context_t *c) { | 997 inline bool sanitize (hb_sanitize_context_t *c) { |
691 TRACE_SANITIZE (); | 998 TRACE_SANITIZE (); |
692 return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, th
is) && ruleSet.sanitize (c, this)); | 999 return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, th
is) && ruleSet.sanitize (c, this)); |
693 } | 1000 } |
694 | 1001 |
695 private: | 1002 protected: |
696 USHORT format; /* Format identifier--format = 2 */ | 1003 USHORT format; /* Format identifier--format = 2 */ |
697 OffsetTo<Coverage> | 1004 OffsetTo<Coverage> |
698 coverage; /* Offset to Coverage table--from | 1005 coverage; /* Offset to Coverage table--from |
699 * beginning of table */ | 1006 * beginning of table */ |
700 OffsetTo<ClassDef> | 1007 OffsetTo<ClassDef> |
701 classDef; /* Offset to glyph ClassDef table--from | 1008 classDef; /* Offset to glyph ClassDef table--from |
702 * beginning of table */ | 1009 * beginning of table */ |
703 OffsetArrayOf<RuleSet> | 1010 OffsetArrayOf<RuleSet> |
704 ruleSet; /* Array of RuleSet tables | 1011 ruleSet; /* Array of RuleSet tables |
705 * ordered by class */ | 1012 * ordered by class */ |
(...skipping 18 matching lines...) Expand all Loading... |
724 struct ContextClosureLookupContext lookup_context = { | 1031 struct ContextClosureLookupContext lookup_context = { |
725 {intersects_coverage, closure_func}, | 1032 {intersects_coverage, closure_func}, |
726 this | 1033 this |
727 }; | 1034 }; |
728 context_closure_lookup (c, | 1035 context_closure_lookup (c, |
729 glyphCount, (const USHORT *) (coverage + 1), | 1036 glyphCount, (const USHORT *) (coverage + 1), |
730 lookupCount, lookupRecord, | 1037 lookupCount, lookupRecord, |
731 lookup_context); | 1038 lookup_context); |
732 } | 1039 } |
733 | 1040 |
| 1041 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1042 { |
| 1043 TRACE_WOULD_APPLY (); |
| 1044 |
| 1045 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); |
| 1046 struct ContextApplyLookupContext lookup_context = { |
| 1047 {match_coverage, NULL}, |
| 1048 this |
| 1049 }; |
| 1050 return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHOR
T *) (coverage + 1), lookupCount, lookupRecord, lookup_context)); |
| 1051 } |
| 1052 |
734 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1053 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
735 { | 1054 { |
736 TRACE_APPLY (); | 1055 TRACE_APPLY (); |
737 unsigned int index = (this+coverage[0]) (c->buffer->cur().codepoint); | 1056 unsigned int index = (this+coverage[0]) (c->buffer->cur().codepoint); |
738 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1057 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
739 | 1058 |
740 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); | 1059 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); |
741 struct ContextApplyLookupContext lookup_context = { | 1060 struct ContextApplyLookupContext lookup_context = { |
742 {match_coverage, apply_func}, | 1061 {match_coverage, apply_func}, |
743 this | 1062 this |
744 }; | 1063 }; |
745 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (
coverage + 1), lookupCount, lookupRecord, lookup_context)); | 1064 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (
coverage + 1), lookupCount, lookupRecord, lookup_context)); |
746 } | 1065 } |
747 | 1066 |
748 inline bool sanitize (hb_sanitize_context_t *c) { | 1067 inline bool sanitize (hb_sanitize_context_t *c) { |
749 TRACE_SANITIZE (); | 1068 TRACE_SANITIZE (); |
750 if (!c->check_struct (this)) return TRACE_RETURN (false); | 1069 if (!c->check_struct (this)) return TRACE_RETURN (false); |
751 unsigned int count = glyphCount; | 1070 unsigned int count = glyphCount; |
752 if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE
_RETURN (false); | 1071 if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE
_RETURN (false); |
753 for (unsigned int i = 0; i < count; i++) | 1072 for (unsigned int i = 0; i < count; i++) |
754 if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false); | 1073 if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false); |
755 LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, covera
ge[0].static_size * count); | 1074 LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, covera
ge[0].static_size * count); |
756 return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_si
ze, lookupCount)); | 1075 return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_si
ze, lookupCount)); |
757 } | 1076 } |
758 | 1077 |
759 private: | 1078 protected: |
760 USHORT format; /* Format identifier--format = 3 */ | 1079 USHORT format; /* Format identifier--format = 3 */ |
761 USHORT glyphCount; /* Number of glyphs in the input glyph | 1080 USHORT glyphCount; /* Number of glyphs in the input glyph |
762 * sequence */ | 1081 * sequence */ |
763 USHORT lookupCount; /* Number of LookupRecords */ | 1082 USHORT lookupCount; /* Number of LookupRecords */ |
764 OffsetTo<Coverage> | 1083 OffsetTo<Coverage> |
765 coverage[VAR]; /* Array of offsets to Coverage | 1084 coverage[VAR]; /* Array of offsets to Coverage |
766 * table in glyph sequence order */ | 1085 * table in glyph sequence order */ |
767 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in | 1086 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
768 * design order */ | 1087 * design order */ |
769 public: | 1088 public: |
770 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); | 1089 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); |
771 }; | 1090 }; |
772 | 1091 |
773 struct Context | 1092 struct Context |
774 { | 1093 { |
775 protected: | 1094 protected: |
776 | 1095 |
777 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const | 1096 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
778 { | 1097 { |
779 TRACE_CLOSURE (); | 1098 TRACE_CLOSURE (); |
780 switch (u.format) { | 1099 switch (u.format) { |
781 case 1: u.format1.closure (c, closure_func); break; | 1100 case 1: u.format1.closure (c, closure_func); break; |
782 case 2: u.format2.closure (c, closure_func); break; | 1101 case 2: u.format2.closure (c, closure_func); break; |
783 case 3: u.format3.closure (c, closure_func); break; | 1102 case 3: u.format3.closure (c, closure_func); break; |
784 default: break; | 1103 default: break; |
785 } | 1104 } |
786 } | 1105 } |
787 | 1106 |
| 1107 inline const Coverage &get_coverage (void) const |
| 1108 { |
| 1109 switch (u.format) { |
| 1110 case 1: return this + u.format1.coverage; |
| 1111 case 2: return this + u.format2.coverage; |
| 1112 case 3: return this + u.format3.coverage[0]; |
| 1113 default:return Null(Coverage); |
| 1114 } |
| 1115 } |
| 1116 |
| 1117 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1118 { |
| 1119 switch (u.format) { |
| 1120 case 1: return u.format1.would_apply (c); |
| 1121 case 2: return u.format2.would_apply (c); |
| 1122 case 3: return u.format3.would_apply (c); |
| 1123 default:return false; |
| 1124 } |
| 1125 } |
| 1126 |
788 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1127 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
789 { | 1128 { |
790 TRACE_APPLY (); | 1129 TRACE_APPLY (); |
791 switch (u.format) { | 1130 switch (u.format) { |
792 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); | 1131 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); |
793 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); | 1132 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); |
794 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); | 1133 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); |
795 default:return TRACE_RETURN (false); | 1134 default:return TRACE_RETURN (false); |
796 } | 1135 } |
797 } | 1136 } |
798 | 1137 |
799 inline bool sanitize (hb_sanitize_context_t *c) { | 1138 inline bool sanitize (hb_sanitize_context_t *c) { |
800 TRACE_SANITIZE (); | 1139 TRACE_SANITIZE (); |
801 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1140 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
802 switch (u.format) { | 1141 switch (u.format) { |
803 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1142 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
804 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 1143 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
805 case 3: return TRACE_RETURN (u.format3.sanitize (c)); | 1144 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
806 default:return TRACE_RETURN (true); | 1145 default:return TRACE_RETURN (true); |
807 } | 1146 } |
808 } | 1147 } |
809 | 1148 |
810 private: | 1149 protected: |
811 union { | 1150 union { |
812 USHORT format; /* Format identifier */ | 1151 USHORT format; /* Format identifier */ |
813 ContextFormat1 format1; | 1152 ContextFormat1 format1; |
814 ContextFormat2 format2; | 1153 ContextFormat2 format2; |
815 ContextFormat3 format3; | 1154 ContextFormat3 format3; |
816 } u; | 1155 } u; |
817 }; | 1156 }; |
818 | 1157 |
819 | 1158 |
820 /* Chaining Contextual lookups */ | 1159 /* Chaining Contextual lookups */ |
(...skipping 28 matching lines...) Expand all Loading... |
849 inputCount ? inputCount - 1 : 0, input, | 1188 inputCount ? inputCount - 1 : 0, input, |
850 lookup_context.funcs.intersects, lookup_context.intersec
ts_data[1]) | 1189 lookup_context.funcs.intersects, lookup_context.intersec
ts_data[1]) |
851 && intersects_array (c, | 1190 && intersects_array (c, |
852 lookaheadCount, lookahead, | 1191 lookaheadCount, lookahead, |
853 lookup_context.funcs.intersects, lookup_context.intersect
s_data[2])) | 1192 lookup_context.funcs.intersects, lookup_context.intersect
s_data[2])) |
854 closure_lookup (c, | 1193 closure_lookup (c, |
855 lookupCount, lookupRecord, | 1194 lookupCount, lookupRecord, |
856 lookup_context.funcs.closure); | 1195 lookup_context.funcs.closure); |
857 } | 1196 } |
858 | 1197 |
| 1198 static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c
, |
| 1199 unsigned int backtrackCount
, |
| 1200 const USHORT backtrack[], |
| 1201 unsigned int inputCount, /*
Including the first glyph (not matched) */ |
| 1202 const USHORT input[], /* Ar
ray of input values--start with second glyph */ |
| 1203 unsigned int lookaheadCount
, |
| 1204 const USHORT lookahead[], |
| 1205 unsigned int lookupCount, |
| 1206 const LookupRecord lookupRe
cord[], |
| 1207 ChainContextApplyLookupCont
ext &lookup_context) |
| 1208 { |
| 1209 return (c->zero_context ? !backtrackCount && !lookaheadCount : true) |
| 1210 && would_match_input (c, |
| 1211 inputCount, input, |
| 1212 lookup_context.funcs.match, lookup_context.match_dat
a[1]); |
| 1213 } |
| 1214 |
859 static inline bool chain_context_apply_lookup (hb_apply_context_t *c, | 1215 static inline bool chain_context_apply_lookup (hb_apply_context_t *c, |
860 unsigned int backtrackCount, | 1216 unsigned int backtrackCount, |
861 const USHORT backtrack[], | 1217 const USHORT backtrack[], |
862 unsigned int inputCount, /* Inclu
ding the first glyph (not matched) */ | 1218 unsigned int inputCount, /* Inclu
ding the first glyph (not matched) */ |
863 const USHORT input[], /* Array of
input values--start with second glyph */ | 1219 const USHORT input[], /* Array of
input values--start with second glyph */ |
864 unsigned int lookaheadCount, | 1220 unsigned int lookaheadCount, |
865 const USHORT lookahead[], | 1221 const USHORT lookahead[], |
866 unsigned int lookupCount, | 1222 unsigned int lookupCount, |
867 const LookupRecord lookupRecord[]
, | 1223 const LookupRecord lookupRecord[]
, |
868 ChainContextApplyLookupContext &l
ookup_context) | 1224 ChainContextApplyLookupContext &l
ookup_context) |
869 { | 1225 { |
870 unsigned int lookahead_offset; | 1226 unsigned int lookahead_offset; |
871 return match_backtrack (c, | 1227 return match_input (c, |
872 » » » backtrackCount, backtrack, | |
873 » » » lookup_context.funcs.match, lookup_context.match_data[
0]) | |
874 && match_input (c, | |
875 inputCount, input, | 1228 inputCount, input, |
876 lookup_context.funcs.match, lookup_context.match_data[1], | 1229 lookup_context.funcs.match, lookup_context.match_data[1], |
877 &lookahead_offset) | 1230 &lookahead_offset) |
| 1231 && match_backtrack (c, |
| 1232 backtrackCount, backtrack, |
| 1233 lookup_context.funcs.match, lookup_context.match_data[
0]) |
878 && match_lookahead (c, | 1234 && match_lookahead (c, |
879 lookaheadCount, lookahead, | 1235 lookaheadCount, lookahead, |
880 lookup_context.funcs.match, lookup_context.match_data[
2], | 1236 lookup_context.funcs.match, lookup_context.match_data[
2], |
881 lookahead_offset) | 1237 lookahead_offset) |
882 && apply_lookup (c, | 1238 && apply_lookup (c, |
883 inputCount, | 1239 inputCount, |
884 lookupCount, lookupRecord, | 1240 lookupCount, lookupRecord, |
885 lookup_context.funcs.apply); | 1241 lookup_context.funcs.apply); |
886 } | 1242 } |
887 | 1243 |
(...skipping 10 matching lines...) Expand all Loading... |
898 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 1254 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
899 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 1255 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
900 chain_context_closure_lookup (c, | 1256 chain_context_closure_lookup (c, |
901 backtrack.len, backtrack.array, | 1257 backtrack.len, backtrack.array, |
902 input.len, input.array, | 1258 input.len, input.array, |
903 lookahead.len, lookahead.array, | 1259 lookahead.len, lookahead.array, |
904 lookup.len, lookup.array, | 1260 lookup.len, lookup.array, |
905 lookup_context); | 1261 lookup_context); |
906 } | 1262 } |
907 | 1263 |
| 1264 inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupC
ontext &lookup_context) const |
| 1265 { |
| 1266 TRACE_WOULD_APPLY (); |
| 1267 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
| 1268 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
| 1269 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
| 1270 return TRACE_RETURN (chain_context_would_apply_lookup (c, |
| 1271 backtrack.len, backtr
ack.array, |
| 1272 input.len, input.arra
y, |
| 1273 lookahead.len, lookah
ead.array, lookup.len, |
| 1274 lookup.array, lookup_
context)); |
| 1275 } |
| 1276 |
908 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const | 1277 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const |
909 { | 1278 { |
910 TRACE_APPLY (); | 1279 TRACE_APPLY (); |
911 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); | 1280 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
912 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 1281 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
913 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 1282 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
914 return TRACE_RETURN (chain_context_apply_lookup (c, | 1283 return TRACE_RETURN (chain_context_apply_lookup (c, |
915 backtrack.len, backtrack.ar
ray, | 1284 backtrack.len, backtrack.ar
ray, |
916 input.len, input.array, | 1285 input.len, input.array, |
917 lookahead.len, lookahead.ar
ray, lookup.len, | 1286 lookahead.len, lookahead.ar
ray, lookup.len, |
918 lookup.array, lookup_contex
t)); | 1287 lookup.array, lookup_contex
t)); |
919 } | 1288 } |
920 | 1289 |
921 public: | 1290 public: |
922 inline bool sanitize (hb_sanitize_context_t *c) { | 1291 inline bool sanitize (hb_sanitize_context_t *c) { |
923 TRACE_SANITIZE (); | 1292 TRACE_SANITIZE (); |
924 if (!backtrack.sanitize (c)) return TRACE_RETURN (false); | 1293 if (!backtrack.sanitize (c)) return TRACE_RETURN (false); |
925 HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (back
track); | 1294 HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (back
track); |
926 if (!input.sanitize (c)) return TRACE_RETURN (false); | 1295 if (!input.sanitize (c)) return TRACE_RETURN (false); |
927 ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 1296 ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
928 if (!lookahead.sanitize (c)) return TRACE_RETURN (false); | 1297 if (!lookahead.sanitize (c)) return TRACE_RETURN (false); |
929 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 1298 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); |
930 return TRACE_RETURN (lookup.sanitize (c)); | 1299 return TRACE_RETURN (lookup.sanitize (c)); |
931 } | 1300 } |
932 | 1301 |
933 private: | 1302 protected: |
934 ArrayOf<USHORT> | 1303 ArrayOf<USHORT> |
935 backtrack; /* Array of backtracking values | 1304 backtrack; /* Array of backtracking values |
936 * (to be matched before the input | 1305 * (to be matched before the input |
937 * sequence) */ | 1306 * sequence) */ |
938 HeadlessArrayOf<USHORT> | 1307 HeadlessArrayOf<USHORT> |
939 inputX; /* Array of input values (start with | 1308 inputX; /* Array of input values (start with |
940 * second glyph) */ | 1309 * second glyph) */ |
941 ArrayOf<USHORT> | 1310 ArrayOf<USHORT> |
942 lookaheadX; /* Array of lookahead values's (to be | 1311 lookaheadX; /* Array of lookahead values's (to be |
943 * matched after the input sequence) */ | 1312 * matched after the input sequence) */ |
944 ArrayOf<LookupRecord> | 1313 ArrayOf<LookupRecord> |
945 lookupX; /* Array of LookupRecords--in | 1314 lookupX; /* Array of LookupRecords--in |
946 * design order) */ | 1315 * design order) */ |
947 public: | 1316 public: |
948 DEFINE_SIZE_MIN (8); | 1317 DEFINE_SIZE_MIN (8); |
949 }; | 1318 }; |
950 | 1319 |
951 struct ChainRuleSet | 1320 struct ChainRuleSet |
952 { | 1321 { |
953 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext
&lookup_context) const | 1322 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext
&lookup_context) const |
954 { | 1323 { |
955 TRACE_CLOSURE (); | 1324 TRACE_CLOSURE (); |
956 unsigned int num_rules = rule.len; | 1325 unsigned int num_rules = rule.len; |
957 for (unsigned int i = 0; i < num_rules; i++) | 1326 for (unsigned int i = 0; i < num_rules; i++) |
958 (this+rule[i]).closure (c, lookup_context); | 1327 (this+rule[i]).closure (c, lookup_context); |
959 } | 1328 } |
960 | 1329 |
| 1330 inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupC
ontext &lookup_context) const |
| 1331 { |
| 1332 TRACE_WOULD_APPLY (); |
| 1333 unsigned int num_rules = rule.len; |
| 1334 for (unsigned int i = 0; i < num_rules; i++) |
| 1335 if ((this+rule[i]).would_apply (c, lookup_context)) |
| 1336 return TRACE_RETURN (true); |
| 1337 |
| 1338 return TRACE_RETURN (false); |
| 1339 } |
| 1340 |
961 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const | 1341 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const |
962 { | 1342 { |
963 TRACE_APPLY (); | 1343 TRACE_APPLY (); |
964 unsigned int num_rules = rule.len; | 1344 unsigned int num_rules = rule.len; |
965 for (unsigned int i = 0; i < num_rules; i++) | 1345 for (unsigned int i = 0; i < num_rules; i++) |
966 if ((this+rule[i]).apply (c, lookup_context)) | 1346 if ((this+rule[i]).apply (c, lookup_context)) |
967 return TRACE_RETURN (true); | 1347 return TRACE_RETURN (true); |
968 | 1348 |
969 return TRACE_RETURN (false); | 1349 return TRACE_RETURN (false); |
970 } | 1350 } |
971 | 1351 |
972 inline bool sanitize (hb_sanitize_context_t *c) { | 1352 inline bool sanitize (hb_sanitize_context_t *c) { |
973 TRACE_SANITIZE (); | 1353 TRACE_SANITIZE (); |
974 return TRACE_RETURN (rule.sanitize (c, this)); | 1354 return TRACE_RETURN (rule.sanitize (c, this)); |
975 } | 1355 } |
976 | 1356 |
977 private: | 1357 protected: |
978 OffsetArrayOf<ChainRule> | 1358 OffsetArrayOf<ChainRule> |
979 rule; /* Array of ChainRule tables | 1359 rule; /* Array of ChainRule tables |
980 * ordered by preference */ | 1360 * ordered by preference */ |
981 public: | 1361 public: |
982 DEFINE_SIZE_ARRAY (2, rule); | 1362 DEFINE_SIZE_ARRAY (2, rule); |
983 }; | 1363 }; |
984 | 1364 |
985 struct ChainContextFormat1 | 1365 struct ChainContextFormat1 |
986 { | 1366 { |
987 friend struct ChainContext; | 1367 friend struct ChainContext; |
(...skipping 11 matching lines...) Expand all Loading... |
999 }; | 1379 }; |
1000 | 1380 |
1001 unsigned int count = ruleSet.len; | 1381 unsigned int count = ruleSet.len; |
1002 for (unsigned int i = 0; i < count; i++) | 1382 for (unsigned int i = 0; i < count; i++) |
1003 if (cov.intersects_coverage (c->glyphs, i)) { | 1383 if (cov.intersects_coverage (c->glyphs, i)) { |
1004 const ChainRuleSet &rule_set = this+ruleSet[i]; | 1384 const ChainRuleSet &rule_set = this+ruleSet[i]; |
1005 rule_set.closure (c, lookup_context); | 1385 rule_set.closure (c, lookup_context); |
1006 } | 1386 } |
1007 } | 1387 } |
1008 | 1388 |
| 1389 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1390 { |
| 1391 TRACE_WOULD_APPLY (); |
| 1392 |
| 1393 const ChainRuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])]; |
| 1394 struct ChainContextApplyLookupContext lookup_context = { |
| 1395 {match_glyph, NULL}, |
| 1396 {NULL, NULL, NULL} |
| 1397 }; |
| 1398 return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); |
| 1399 } |
| 1400 |
1009 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1401 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
1010 { | 1402 { |
1011 TRACE_APPLY (); | 1403 TRACE_APPLY (); |
1012 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); | 1404 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
1013 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1405 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
1014 | 1406 |
1015 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1407 const ChainRuleSet &rule_set = this+ruleSet[index]; |
1016 struct ChainContextApplyLookupContext lookup_context = { | 1408 struct ChainContextApplyLookupContext lookup_context = { |
1017 {match_glyph, apply_func}, | 1409 {match_glyph, apply_func}, |
1018 {NULL, NULL, NULL} | 1410 {NULL, NULL, NULL} |
1019 }; | 1411 }; |
1020 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1412 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1021 } | 1413 } |
1022 | 1414 |
1023 inline bool sanitize (hb_sanitize_context_t *c) { | 1415 inline bool sanitize (hb_sanitize_context_t *c) { |
1024 TRACE_SANITIZE (); | 1416 TRACE_SANITIZE (); |
1025 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); | 1417 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
1026 } | 1418 } |
1027 | 1419 |
1028 private: | 1420 protected: |
1029 USHORT format; /* Format identifier--format = 1 */ | 1421 USHORT format; /* Format identifier--format = 1 */ |
1030 OffsetTo<Coverage> | 1422 OffsetTo<Coverage> |
1031 coverage; /* Offset to Coverage table--from | 1423 coverage; /* Offset to Coverage table--from |
1032 * beginning of table */ | 1424 * beginning of table */ |
1033 OffsetArrayOf<ChainRuleSet> | 1425 OffsetArrayOf<ChainRuleSet> |
1034 ruleSet; /* Array of ChainRuleSet tables | 1426 ruleSet; /* Array of ChainRuleSet tables |
1035 * ordered by Coverage Index */ | 1427 * ordered by Coverage Index */ |
1036 public: | 1428 public: |
1037 DEFINE_SIZE_ARRAY (6, ruleSet); | 1429 DEFINE_SIZE_ARRAY (6, ruleSet); |
1038 }; | 1430 }; |
(...skipping 22 matching lines...) Expand all Loading... |
1061 }; | 1453 }; |
1062 | 1454 |
1063 unsigned int count = ruleSet.len; | 1455 unsigned int count = ruleSet.len; |
1064 for (unsigned int i = 0; i < count; i++) | 1456 for (unsigned int i = 0; i < count; i++) |
1065 if (input_class_def.intersects_class (c->glyphs, i)) { | 1457 if (input_class_def.intersects_class (c->glyphs, i)) { |
1066 const ChainRuleSet &rule_set = this+ruleSet[i]; | 1458 const ChainRuleSet &rule_set = this+ruleSet[i]; |
1067 rule_set.closure (c, lookup_context); | 1459 rule_set.closure (c, lookup_context); |
1068 } | 1460 } |
1069 } | 1461 } |
1070 | 1462 |
| 1463 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1464 { |
| 1465 TRACE_WOULD_APPLY (); |
| 1466 |
| 1467 const ClassDef &input_class_def = this+inputClassDef; |
| 1468 |
| 1469 unsigned int index = input_class_def (c->glyphs[0]); |
| 1470 const ChainRuleSet &rule_set = this+ruleSet[index]; |
| 1471 struct ChainContextApplyLookupContext lookup_context = { |
| 1472 {match_class, NULL}, |
| 1473 {NULL, &input_class_def, NULL} |
| 1474 }; |
| 1475 return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); |
| 1476 } |
| 1477 |
1071 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1478 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
1072 { | 1479 { |
1073 TRACE_APPLY (); | 1480 TRACE_APPLY (); |
1074 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); | 1481 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
1075 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1482 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
1076 | 1483 |
1077 const ClassDef &backtrack_class_def = this+backtrackClassDef; | 1484 const ClassDef &backtrack_class_def = this+backtrackClassDef; |
1078 const ClassDef &input_class_def = this+inputClassDef; | 1485 const ClassDef &input_class_def = this+inputClassDef; |
1079 const ClassDef &lookahead_class_def = this+lookaheadClassDef; | 1486 const ClassDef &lookahead_class_def = this+lookaheadClassDef; |
1080 | 1487 |
1081 index = input_class_def (c->buffer->cur().codepoint); | 1488 index = input_class_def (c->buffer->cur().codepoint); |
1082 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1489 const ChainRuleSet &rule_set = this+ruleSet[index]; |
1083 struct ChainContextApplyLookupContext lookup_context = { | 1490 struct ChainContextApplyLookupContext lookup_context = { |
1084 {match_class, apply_func}, | 1491 {match_class, apply_func}, |
1085 {&backtrack_class_def, | 1492 {&backtrack_class_def, |
1086 &input_class_def, | 1493 &input_class_def, |
1087 &lookahead_class_def} | 1494 &lookahead_class_def} |
1088 }; | 1495 }; |
1089 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1496 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1090 } | 1497 } |
1091 | 1498 |
1092 inline bool sanitize (hb_sanitize_context_t *c) { | 1499 inline bool sanitize (hb_sanitize_context_t *c) { |
1093 TRACE_SANITIZE (); | 1500 TRACE_SANITIZE (); |
1094 return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.saniti
ze (c, this) && | 1501 return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.saniti
ze (c, this) && |
1095 inputClassDef.sanitize (c, this) && lookaheadClassDef.s
anitize (c, this) && | 1502 inputClassDef.sanitize (c, this) && lookaheadClassDef.s
anitize (c, this) && |
1096 ruleSet.sanitize (c, this)); | 1503 ruleSet.sanitize (c, this)); |
1097 } | 1504 } |
1098 | 1505 |
1099 private: | 1506 protected: |
1100 USHORT format; /* Format identifier--format = 2 */ | 1507 USHORT format; /* Format identifier--format = 2 */ |
1101 OffsetTo<Coverage> | 1508 OffsetTo<Coverage> |
1102 coverage; /* Offset to Coverage table--from | 1509 coverage; /* Offset to Coverage table--from |
1103 * beginning of table */ | 1510 * beginning of table */ |
1104 OffsetTo<ClassDef> | 1511 OffsetTo<ClassDef> |
1105 backtrackClassDef; /* Offset to glyph ClassDef table | 1512 backtrackClassDef; /* Offset to glyph ClassDef table |
1106 * containing backtrack sequence | 1513 * containing backtrack sequence |
1107 * data--from beginning of table */ | 1514 * data--from beginning of table */ |
1108 OffsetTo<ClassDef> | 1515 OffsetTo<ClassDef> |
1109 inputClassDef; /* Offset to glyph ClassDef | 1516 inputClassDef; /* Offset to glyph ClassDef |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 {this, this, this} | 1548 {this, this, this} |
1142 }; | 1549 }; |
1143 chain_context_closure_lookup (c, | 1550 chain_context_closure_lookup (c, |
1144 backtrack.len, (const USHORT *) backtrack.arra
y, | 1551 backtrack.len, (const USHORT *) backtrack.arra
y, |
1145 input.len, (const USHORT *) input.array + 1, | 1552 input.len, (const USHORT *) input.array + 1, |
1146 lookahead.len, (const USHORT *) lookahead.arra
y, | 1553 lookahead.len, (const USHORT *) lookahead.arra
y, |
1147 lookup.len, lookup.array, | 1554 lookup.len, lookup.array, |
1148 lookup_context); | 1555 lookup_context); |
1149 } | 1556 } |
1150 | 1557 |
| 1558 inline const Coverage &get_coverage (void) const |
| 1559 { |
| 1560 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
| 1561 return this+input[0]; |
| 1562 } |
| 1563 |
| 1564 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1565 { |
| 1566 TRACE_WOULD_APPLY (); |
| 1567 |
| 1568 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
| 1569 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); |
| 1570 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
| 1571 struct ChainContextApplyLookupContext lookup_context = { |
| 1572 {match_coverage, NULL}, |
| 1573 {this, this, this} |
| 1574 }; |
| 1575 return TRACE_RETURN (chain_context_would_apply_lookup (c, |
| 1576 backtrack.len, (const
USHORT *) backtrack.array, |
| 1577 input.len, (const USH
ORT *) input.array + 1, |
| 1578 lookahead.len, (const
USHORT *) lookahead.array, |
| 1579 lookup.len, lookup.ar
ray, lookup_context)); |
| 1580 } |
| 1581 |
1151 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1582 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
1152 { | 1583 { |
1153 TRACE_APPLY (); | 1584 TRACE_APPLY (); |
1154 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); | 1585 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
1155 | 1586 |
1156 unsigned int index = (this+input[0]) (c->buffer->cur().codepoint); | 1587 unsigned int index = (this+input[0]) (c->buffer->cur().codepoint); |
1157 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1588 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
1158 | 1589 |
1159 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); | 1590 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); |
1160 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 1591 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
(...skipping 12 matching lines...) Expand all Loading... |
1173 TRACE_SANITIZE (); | 1604 TRACE_SANITIZE (); |
1174 if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); | 1605 if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); |
1175 OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (back
track); | 1606 OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (back
track); |
1176 if (!input.sanitize (c, this)) return TRACE_RETURN (false); | 1607 if (!input.sanitize (c, this)) return TRACE_RETURN (false); |
1177 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (
input); | 1608 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (
input); |
1178 if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); | 1609 if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); |
1179 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 1610 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); |
1180 return TRACE_RETURN (lookup.sanitize (c)); | 1611 return TRACE_RETURN (lookup.sanitize (c)); |
1181 } | 1612 } |
1182 | 1613 |
1183 private: | 1614 protected: |
1184 USHORT format; /* Format identifier--format = 3 */ | 1615 USHORT format; /* Format identifier--format = 3 */ |
1185 OffsetArrayOf<Coverage> | 1616 OffsetArrayOf<Coverage> |
1186 backtrack; /* Array of coverage tables | 1617 backtrack; /* Array of coverage tables |
1187 * in backtracking sequence, in glyph | 1618 * in backtracking sequence, in glyph |
1188 * sequence order */ | 1619 * sequence order */ |
1189 OffsetArrayOf<Coverage> | 1620 OffsetArrayOf<Coverage> |
1190 inputX ; /* Array of coverage | 1621 inputX ; /* Array of coverage |
1191 * tables in input sequence, in glyph | 1622 * tables in input sequence, in glyph |
1192 * sequence order */ | 1623 * sequence order */ |
1193 OffsetArrayOf<Coverage> | 1624 OffsetArrayOf<Coverage> |
(...skipping 15 matching lines...) Expand all Loading... |
1209 { | 1640 { |
1210 TRACE_CLOSURE (); | 1641 TRACE_CLOSURE (); |
1211 switch (u.format) { | 1642 switch (u.format) { |
1212 case 1: u.format1.closure (c, closure_func); break; | 1643 case 1: u.format1.closure (c, closure_func); break; |
1213 case 2: u.format2.closure (c, closure_func); break; | 1644 case 2: u.format2.closure (c, closure_func); break; |
1214 case 3: u.format3.closure (c, closure_func); break; | 1645 case 3: u.format3.closure (c, closure_func); break; |
1215 default: break; | 1646 default: break; |
1216 } | 1647 } |
1217 } | 1648 } |
1218 | 1649 |
| 1650 inline const Coverage &get_coverage (void) const |
| 1651 { |
| 1652 switch (u.format) { |
| 1653 case 1: return this + u.format1.coverage; |
| 1654 case 2: return this + u.format2.coverage; |
| 1655 case 3: return u.format3.get_coverage (); |
| 1656 default:return Null(Coverage); |
| 1657 } |
| 1658 } |
| 1659 |
| 1660 inline bool would_apply (hb_would_apply_context_t *c) const |
| 1661 { |
| 1662 switch (u.format) { |
| 1663 case 1: return u.format1.would_apply (c); |
| 1664 case 2: return u.format2.would_apply (c); |
| 1665 case 3: return u.format3.would_apply (c); |
| 1666 default:return false; |
| 1667 } |
| 1668 } |
| 1669 |
1219 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1670 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
1220 { | 1671 { |
1221 TRACE_APPLY (); | 1672 TRACE_APPLY (); |
1222 switch (u.format) { | 1673 switch (u.format) { |
1223 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); | 1674 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); |
1224 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); | 1675 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); |
1225 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); | 1676 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); |
1226 default:return TRACE_RETURN (false); | 1677 default:return TRACE_RETURN (false); |
1227 } | 1678 } |
1228 } | 1679 } |
1229 | 1680 |
1230 inline bool sanitize (hb_sanitize_context_t *c) { | 1681 inline bool sanitize (hb_sanitize_context_t *c) { |
1231 TRACE_SANITIZE (); | 1682 TRACE_SANITIZE (); |
1232 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1683 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1233 switch (u.format) { | 1684 switch (u.format) { |
1234 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1685 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1235 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | 1686 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
1236 case 3: return TRACE_RETURN (u.format3.sanitize (c)); | 1687 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
1237 default:return TRACE_RETURN (true); | 1688 default:return TRACE_RETURN (true); |
1238 } | 1689 } |
1239 } | 1690 } |
1240 | 1691 |
1241 private: | 1692 protected: |
1242 union { | 1693 union { |
1243 USHORT format; /* Format identifier */ | 1694 USHORT format; /* Format identifier */ |
1244 ChainContextFormat1 format1; | 1695 ChainContextFormat1 format1; |
1245 ChainContextFormat2 format2; | 1696 ChainContextFormat2 format2; |
1246 ChainContextFormat3 format3; | 1697 ChainContextFormat3 format3; |
1247 } u; | 1698 } u; |
1248 }; | 1699 }; |
1249 | 1700 |
1250 | 1701 |
1251 struct ExtensionFormat1 | 1702 struct ExtensionFormat1 |
1252 { | 1703 { |
1253 friend struct Extension; | 1704 friend struct Extension; |
1254 | 1705 |
1255 protected: | 1706 protected: |
1256 inline unsigned int get_type (void) const { return extensionLookupType; } | 1707 inline unsigned int get_type (void) const { return extensionLookupType; } |
1257 inline unsigned int get_offset (void) const { return extensionOffset; } | 1708 inline unsigned int get_offset (void) const { return extensionOffset; } |
1258 | 1709 |
1259 inline bool sanitize (hb_sanitize_context_t *c) { | 1710 inline bool sanitize (hb_sanitize_context_t *c) { |
1260 TRACE_SANITIZE (); | 1711 TRACE_SANITIZE (); |
1261 return TRACE_RETURN (c->check_struct (this)); | 1712 return TRACE_RETURN (c->check_struct (this)); |
1262 } | 1713 } |
1263 | 1714 |
1264 private: | 1715 protected: |
1265 USHORT format; /* Format identifier. Set to 1. */ | 1716 USHORT format; /* Format identifier. Set to 1. */ |
1266 USHORT extensionLookupType; /* Lookup type of subtable referenced | 1717 USHORT extensionLookupType; /* Lookup type of subtable referenced |
1267 * by ExtensionOffset (i.e. the | 1718 * by ExtensionOffset (i.e. the |
1268 * extension subtable). */ | 1719 * extension subtable). */ |
1269 ULONG extensionOffset; /* Offset to the extension subtable, | 1720 ULONG extensionOffset; /* Offset to the extension subtable, |
1270 * of lookup type subtable. */ | 1721 * of lookup type subtable. */ |
1271 public: | 1722 public: |
1272 DEFINE_SIZE_STATIC (8); | 1723 DEFINE_SIZE_STATIC (8); |
1273 }; | 1724 }; |
1274 | 1725 |
(...skipping 16 matching lines...) Expand all Loading... |
1291 | 1742 |
1292 inline bool sanitize (hb_sanitize_context_t *c) { | 1743 inline bool sanitize (hb_sanitize_context_t *c) { |
1293 TRACE_SANITIZE (); | 1744 TRACE_SANITIZE (); |
1294 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | 1745 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
1295 switch (u.format) { | 1746 switch (u.format) { |
1296 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 1747 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
1297 default:return TRACE_RETURN (true); | 1748 default:return TRACE_RETURN (true); |
1298 } | 1749 } |
1299 } | 1750 } |
1300 | 1751 |
1301 private: | 1752 protected: |
1302 union { | 1753 union { |
1303 USHORT format; /* Format identifier */ | 1754 USHORT format; /* Format identifier */ |
1304 ExtensionFormat1 format1; | 1755 ExtensionFormat1 format1; |
1305 } u; | 1756 } u; |
1306 }; | 1757 }; |
1307 | 1758 |
1308 | 1759 |
1309 /* | 1760 /* |
1310 * GSUB/GPOS Common | 1761 * GSUB/GPOS Common |
1311 */ | 1762 */ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 scriptList; /* ScriptList table */ | 1812 scriptList; /* ScriptList table */ |
1362 OffsetTo<FeatureList> | 1813 OffsetTo<FeatureList> |
1363 featureList; /* FeatureList table */ | 1814 featureList; /* FeatureList table */ |
1364 OffsetTo<LookupList> | 1815 OffsetTo<LookupList> |
1365 lookupList; /* LookupList table */ | 1816 lookupList; /* LookupList table */ |
1366 public: | 1817 public: |
1367 DEFINE_SIZE_STATIC (10); | 1818 DEFINE_SIZE_STATIC (10); |
1368 }; | 1819 }; |
1369 | 1820 |
1370 | 1821 |
| 1822 } // namespace OT |
| 1823 |
1371 | 1824 |
1372 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ | 1825 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ |
OLD | NEW |