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 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 |
11 * all copies of this software. | 11 * all copies of this software. |
12 * | 12 * |
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
(...skipping 12 matching lines...) Expand all Loading... |
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 | 34 |
35 | 35 |
36 /* buffer var allocations */ | 36 |
37 #define lig_id() var2.u8[2] /* unique ligature id */ | 37 /* unique ligature id */ |
38 #define lig_comp() var2.u8[3] /* component number in the ligature (0 = base) */ | 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 } |
39 | 54 |
40 static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { | 55 static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { |
41 uint8_t lig_id = buffer->next_serial (); | 56 uint8_t lig_id = buffer->next_serial () & 0x0F; |
42 if (unlikely (!lig_id)) lig_id = buffer->next_serial (); /* in case of overflo
w */ | 57 if (unlikely (!lig_id)) |
| 58 lig_id = allocate_lig_id (buffer); /* in case of overflow */ |
43 return lig_id; | 59 return lig_id; |
44 } | 60 } |
45 | 61 |
46 | 62 |
47 | 63 |
| 64 #ifndef HB_DEBUG_CLOSURE |
| 65 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) |
| 66 #endif |
| 67 |
| 68 #define TRACE_CLOSURE() \ |
| 69 hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", thi
s, HB_FUNC, ""); |
| 70 |
| 71 |
| 72 /* TODO Add TRACE_RETURN annotation for would_apply */ |
| 73 |
| 74 |
| 75 struct hb_closure_context_t |
| 76 { |
| 77 hb_face_t *face; |
| 78 hb_set_t *glyphs; |
| 79 unsigned int nesting_level_left; |
| 80 unsigned int debug_depth; |
| 81 |
| 82 |
| 83 hb_closure_context_t (hb_face_t *face_, |
| 84 hb_set_t *glyphs_, |
| 85 unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : |
| 86 face (face_), glyphs (glyphs_), |
| 87 nesting_level_left (nesting_level_left_), |
| 88 debug_depth (0) {} |
| 89 }; |
| 90 |
| 91 |
| 92 |
48 #ifndef HB_DEBUG_APPLY | 93 #ifndef HB_DEBUG_APPLY |
49 #define HB_DEBUG_APPLY (HB_DEBUG+0) | 94 #define HB_DEBUG_APPLY (HB_DEBUG+0) |
50 #endif | 95 #endif |
51 | 96 |
52 #define TRACE_APPLY() \ | 97 #define TRACE_APPLY() \ |
53 » hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, N
ULL, HB_FUNC); | 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); |
54 | 99 |
55 | 100 |
56 | 101 |
57 struct hb_apply_context_t | 102 struct hb_apply_context_t |
58 { | 103 { |
59 unsigned int debug_depth; | |
60 hb_font_t *font; | 104 hb_font_t *font; |
61 hb_face_t *face; | 105 hb_face_t *face; |
62 hb_buffer_t *buffer; | 106 hb_buffer_t *buffer; |
63 hb_direction_t direction; | 107 hb_direction_t direction; |
64 hb_mask_t lookup_mask; | 108 hb_mask_t lookup_mask; |
65 unsigned int context_length; | |
66 unsigned int nesting_level_left; | 109 unsigned int nesting_level_left; |
67 unsigned int lookup_props; | 110 unsigned int lookup_props; |
68 unsigned int property; /* propety of first glyph */ | 111 unsigned int property; /* propety of first glyph */ |
| 112 unsigned int debug_depth; |
| 113 |
| 114 |
| 115 hb_apply_context_t (hb_font_t *font_, |
| 116 hb_face_t *face_, |
| 117 hb_buffer_t *buffer_, |
| 118 hb_mask_t lookup_mask_) : |
| 119 font (font_), face (face_), buffer (buffer_), |
| 120 direction (buffer_->props.direction), |
| 121 lookup_mask (lookup_mask_), |
| 122 nesting_level_left (MAX_NESTING_LEVEL), |
| 123 lookup_props (0), property (0), debug_depth (0) {} |
| 124 |
| 125 void set_lookup (const Lookup &l) { |
| 126 lookup_props = l.get_props (); |
| 127 } |
69 | 128 |
70 struct mark_skipping_forward_iterator_t | 129 struct mark_skipping_forward_iterator_t |
71 { | 130 { |
72 inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, | 131 inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, |
73 unsigned int start_index_, | 132 unsigned int start_index_, |
74 » » » » » unsigned int num_items_) | 133 » » » » » unsigned int num_items_, |
| 134 » » » » » bool context_match = false) |
75 { | 135 { |
76 c = c_; | 136 c = c_; |
77 idx = start_index_; | 137 idx = start_index_; |
78 num_items = num_items_; | 138 num_items = num_items_; |
79 end = MIN (c->buffer->len, c->buffer->idx + c->context_length); | 139 mask = context_match ? -1 : c->lookup_mask; |
| 140 syllable = context_match ? 0 : c->buffer->cur().syllable (); |
| 141 end = c->buffer->len; |
80 } | 142 } |
81 inline bool has_no_chance (void) const | 143 inline bool has_no_chance (void) const |
82 { | 144 { |
83 return unlikely (num_items && idx + num_items >= end); | 145 return unlikely (num_items && idx + num_items >= end); |
84 } | 146 } |
85 inline bool next (unsigned int *property_out, | 147 inline bool next (unsigned int *property_out, |
86 unsigned int lookup_props) | 148 unsigned int lookup_props) |
87 { | 149 { |
88 assert (num_items > 0); | 150 assert (num_items > 0); |
89 do | 151 do |
90 { | 152 { |
91 if (has_no_chance ()) | 153 if (has_no_chance ()) |
92 return false; | 154 return false; |
93 idx++; | 155 idx++; |
94 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[idx], lookup_p
rops, property_out)); | 156 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->info[idx], lookup_p
rops, property_out)); |
95 num_items--; | 157 num_items--; |
96 return true; | 158 return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c->
buffer->info[idx].syllable ()); |
97 } | 159 } |
98 inline bool next (unsigned int *property_out = NULL) | 160 inline bool next (unsigned int *property_out = NULL) |
99 { | 161 { |
100 return next (property_out, c->lookup_props); | 162 return next (property_out, c->lookup_props); |
101 } | 163 } |
102 | 164 |
103 unsigned int idx; | 165 unsigned int idx; |
104 private: | 166 private: |
105 hb_apply_context_t *c; | 167 hb_apply_context_t *c; |
106 unsigned int num_items; | 168 unsigned int num_items; |
| 169 hb_mask_t mask; |
| 170 uint8_t syllable; |
107 unsigned int end; | 171 unsigned int end; |
108 }; | 172 }; |
109 | 173 |
110 struct mark_skipping_backward_iterator_t | 174 struct mark_skipping_backward_iterator_t |
111 { | 175 { |
112 inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, | 176 inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, |
113 unsigned int start_index_, | 177 unsigned int start_index_, |
114 » » » » » unsigned int num_items_) | 178 » » » » » unsigned int num_items_, |
| 179 » » » » » hb_mask_t mask_ = 0, |
| 180 » » » » » bool match_syllable_ = true) |
115 { | 181 { |
116 c = c_; | 182 c = c_; |
117 idx = start_index_; | 183 idx = start_index_; |
118 num_items = num_items_; | 184 num_items = num_items_; |
| 185 mask = mask_ ? mask_ : c->lookup_mask; |
| 186 syllable = match_syllable_ ? c->buffer->cur().syllable () : 0; |
119 } | 187 } |
120 inline bool has_no_chance (void) const | 188 inline bool has_no_chance (void) const |
121 { | 189 { |
122 return unlikely (idx < num_items); | 190 return unlikely (idx < num_items); |
123 } | 191 } |
124 inline bool prev (unsigned int *property_out, | 192 inline bool prev (unsigned int *property_out, |
125 unsigned int lookup_props) | 193 unsigned int lookup_props) |
126 { | 194 { |
127 assert (num_items > 0); | 195 assert (num_items > 0); |
128 do | 196 do |
129 { | 197 { |
130 if (has_no_chance ()) | 198 if (has_no_chance ()) |
131 return false; | 199 return false; |
132 idx--; | 200 idx--; |
133 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[idx], look
up_props, property_out)); | 201 } while (_hb_ot_layout_skip_mark (c->face, &c->buffer->out_info[idx], look
up_props, property_out)); |
134 num_items--; | 202 num_items--; |
135 return true; | 203 return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable ==
c->buffer->out_info[idx].syllable ()); |
136 } | 204 } |
137 inline bool prev (unsigned int *property_out = NULL) | 205 inline bool prev (unsigned int *property_out = NULL) |
138 { | 206 { |
139 return prev (property_out, c->lookup_props); | 207 return prev (property_out, c->lookup_props); |
140 } | 208 } |
141 | 209 |
142 unsigned int idx; | 210 unsigned int idx; |
143 private: | 211 private: |
144 hb_apply_context_t *c; | 212 hb_apply_context_t *c; |
145 unsigned int num_items; | 213 unsigned int num_items; |
| 214 hb_mask_t mask; |
| 215 uint8_t syllable; |
146 }; | 216 }; |
147 | 217 |
148 inline bool should_mark_skip_current_glyph (void) const | 218 inline bool should_mark_skip_current_glyph (void) const |
149 { | 219 { |
150 return _hb_ot_layout_skip_mark (face, &buffer->info[buffer->idx], lookup_pro
ps, NULL); | 220 return _hb_ot_layout_skip_mark (face, &buffer->cur(), lookup_props, NULL); |
151 } | 221 } |
152 | 222 |
153 | 223 |
154 | 224 |
155 inline void replace_glyph (hb_codepoint_t glyph_index) const | 225 inline void replace_glyph (hb_codepoint_t glyph_index, |
| 226 » » » unsigned int klass = 0) const |
156 { | 227 { |
157 clear_property (); | 228 buffer->cur().props_cache() = klass; /*XXX if has gdef? */ |
158 buffer->replace_glyph (glyph_index); | 229 buffer->replace_glyph (glyph_index); |
159 } | 230 } |
160 inline void replace_glyphs_be16 (unsigned int num_in, | 231 inline void replace_glyphs_be16 (unsigned int num_in, |
161 unsigned int num_out, | 232 unsigned int num_out, |
162 » » » » const uint16_t *glyph_data_be) const | 233 » » » » const uint16_t *glyph_data_be, |
| 234 » » » » unsigned int klass = 0) const |
163 { | 235 { |
164 clear_property (); | 236 buffer->cur().props_cache() = klass; /* XXX if has gdef? */ |
165 buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be); | 237 buffer->replace_glyphs_be16 (num_in, num_out, glyph_data_be); |
166 } | 238 } |
167 | |
168 inline void guess_glyph_class (unsigned int klass) | |
169 { | |
170 /* XXX if ! has gdef */ | |
171 buffer->info[buffer->idx].props_cache() = klass; | |
172 } | |
173 | |
174 private: | |
175 inline void clear_property (void) const | |
176 { | |
177 /* XXX if has gdef */ | |
178 buffer->info[buffer->idx].props_cache() = 0; | |
179 } | |
180 }; | 239 }; |
181 | 240 |
182 | 241 |
183 | 242 |
| 243 typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const
void *data); |
184 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, cons
t void *data); | 244 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); |
185 typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_
index); | 246 typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_
index); |
186 | 247 |
187 struct ContextFuncs | 248 struct ContextClosureFuncs |
| 249 { |
| 250 intersects_func_t intersects; |
| 251 closure_lookup_func_t closure; |
| 252 }; |
| 253 struct ContextApplyFuncs |
188 { | 254 { |
189 match_func_t match; | 255 match_func_t match; |
190 apply_lookup_func_t apply; | 256 apply_lookup_func_t apply; |
191 }; | 257 }; |
192 | 258 |
| 259 static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, cons
t void *data HB_UNUSED) |
| 260 { |
| 261 return glyphs->has (value); |
| 262 } |
| 263 static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, cons
t void *data) |
| 264 { |
| 265 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
| 266 return class_def.intersects_class (glyphs, value); |
| 267 } |
| 268 static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, c
onst void *data) |
| 269 { |
| 270 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
| 271 return (data+coverage).intersects (glyphs); |
| 272 } |
| 273 |
| 274 static inline bool intersects_array (hb_closure_context_t *c, |
| 275 unsigned int count, |
| 276 const USHORT values[], |
| 277 intersects_func_t intersects_func, |
| 278 const void *intersects_data) |
| 279 { |
| 280 for (unsigned int i = 0; i < count; i++) |
| 281 if (likely (!intersects_func (c->glyphs, values[i], intersects_data))) |
| 282 return false; |
| 283 return true; |
| 284 } |
| 285 |
193 | 286 |
194 static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, co
nst void *data HB_UNUSED) | 287 static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, co
nst void *data HB_UNUSED) |
195 { | 288 { |
196 return glyph_id == value; | 289 return glyph_id == value; |
197 } | 290 } |
198 | |
199 static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, co
nst void *data) | 291 static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, co
nst void *data) |
200 { | 292 { |
201 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); | 293 const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); |
202 return class_def.get_class (glyph_id) == value; | 294 return class_def.get_class (glyph_id) == value; |
203 } | 295 } |
204 | |
205 static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
const void *data) | 296 static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
const void *data) |
206 { | 297 { |
207 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; | 298 const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; |
208 return (data+coverage) (glyph_id) != NOT_COVERED; | 299 return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; |
209 } | 300 } |
210 | 301 |
211 | 302 |
212 static inline bool match_input (hb_apply_context_t *c, | 303 static inline bool match_input (hb_apply_context_t *c, |
213 unsigned int count, /* Including the first glyph
(not matched) */ | 304 unsigned int count, /* Including the first glyph
(not matched) */ |
214 const USHORT input[], /* Array of input values--
start with second glyph */ | 305 const USHORT input[], /* Array of input values--
start with second glyph */ |
215 match_func_t match_func, | 306 match_func_t match_func, |
216 const void *match_data, | 307 const void *match_data, |
217 » » » » unsigned int *context_length_out) | 308 » » » » unsigned int *end_offset = NULL) |
218 { | 309 { |
219 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx, count - 1); | 310 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx, count - 1); |
220 if (skippy_iter.has_no_chance ()) | 311 if (skippy_iter.has_no_chance ()) |
221 return false; | 312 return false; |
222 | 313 |
223 for (unsigned int i = 1; i < count; i++) | 314 for (unsigned int i = 1; i < count; i++) |
224 { | 315 { |
225 if (!skippy_iter.next ()) | 316 if (!skippy_iter.next ()) |
226 return false; | 317 return false; |
227 | 318 |
228 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i
- 1], match_data))) | 319 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i
- 1], match_data))) |
229 return false; | 320 return false; |
230 } | 321 } |
231 | 322 |
232 *context_length_out = skippy_iter.idx - c->buffer->idx + 1; | 323 if (end_offset) |
| 324 *end_offset = skippy_iter.idx - c->buffer->idx + 1; |
233 | 325 |
234 return true; | 326 return true; |
235 } | 327 } |
236 | 328 |
237 static inline bool match_backtrack (hb_apply_context_t *c, | 329 static inline bool match_backtrack (hb_apply_context_t *c, |
238 unsigned int count, | 330 unsigned int count, |
239 const USHORT backtrack[], | 331 const USHORT backtrack[], |
240 match_func_t match_func, | 332 match_func_t match_func, |
241 const void *match_data) | 333 const void *match_data) |
242 { | 334 { |
243 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffe
r->backtrack_len (), count); | 335 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffe
r->backtrack_len (), count, true); |
244 if (skippy_iter.has_no_chance ()) | 336 if (skippy_iter.has_no_chance ()) |
245 return false; | 337 return false; |
246 | 338 |
247 for (unsigned int i = 0; i < count; i++) | 339 for (unsigned int i = 0; i < count; i++) |
248 { | 340 { |
249 if (!skippy_iter.prev ()) | 341 if (!skippy_iter.prev ()) |
250 return false; | 342 return false; |
251 | 343 |
252 if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, bac
ktrack[i], match_data))) | 344 if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, bac
ktrack[i], match_data))) |
253 return false; | 345 return false; |
254 } | 346 } |
255 | 347 |
256 return true; | 348 return true; |
257 } | 349 } |
258 | 350 |
259 static inline bool match_lookahead (hb_apply_context_t *c, | 351 static inline bool match_lookahead (hb_apply_context_t *c, |
260 unsigned int count, | 352 unsigned int count, |
261 const USHORT lookahead[], | 353 const USHORT lookahead[], |
262 match_func_t match_func, | 354 match_func_t match_func, |
263 const void *match_data, | 355 const void *match_data, |
264 unsigned int offset) | 356 unsigned int offset) |
265 { | 357 { |
266 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx + offset - 1, count); | 358 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer
->idx + offset - 1, count, true); |
267 if (skippy_iter.has_no_chance ()) | 359 if (skippy_iter.has_no_chance ()) |
268 return false; | 360 return false; |
269 | 361 |
270 for (unsigned int i = 0; i < count; i++) | 362 for (unsigned int i = 0; i < count; i++) |
271 { | 363 { |
272 if (!skippy_iter.next ()) | 364 if (!skippy_iter.next ()) |
273 return false; | 365 return false; |
274 | 366 |
275 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahe
ad[i], match_data))) | 367 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahe
ad[i], match_data))) |
276 return false; | 368 return false; |
277 } | 369 } |
278 | 370 |
279 return true; | 371 return true; |
280 } | 372 } |
281 | 373 |
282 | 374 |
283 | 375 |
284 struct LookupRecord | 376 struct LookupRecord |
285 { | 377 { |
286 inline bool sanitize (hb_sanitize_context_t *c) { | 378 inline bool sanitize (hb_sanitize_context_t *c) { |
287 TRACE_SANITIZE (); | 379 TRACE_SANITIZE (); |
288 return c->check_struct (this); | 380 return TRACE_RETURN (c->check_struct (this)); |
289 } | 381 } |
290 | 382 |
291 USHORT sequenceIndex; /* Index into current glyph | 383 USHORT sequenceIndex; /* Index into current glyph |
292 * sequence--first glyph = 0 */ | 384 * sequence--first glyph = 0 */ |
293 USHORT lookupListIndex; /* Lookup to apply to that | 385 USHORT lookupListIndex; /* Lookup to apply to that |
294 * position--zero--based */ | 386 * position--zero--based */ |
295 public: | 387 public: |
296 DEFINE_SIZE_STATIC (4); | 388 DEFINE_SIZE_STATIC (4); |
297 }; | 389 }; |
298 | 390 |
299 | 391 |
| 392 static inline void closure_lookup (hb_closure_context_t *c, |
| 393 unsigned int lookupCount, |
| 394 const LookupRecord lookupRecord[], /* Array o
f LookupRecords--in design order */ |
| 395 closure_lookup_func_t closure_func) |
| 396 { |
| 397 for (unsigned int i = 0; i < lookupCount; i++) |
| 398 closure_func (c, lookupRecord->lookupListIndex); |
| 399 } |
300 | 400 |
301 static inline bool apply_lookup (hb_apply_context_t *c, | 401 static inline bool apply_lookup (hb_apply_context_t *c, |
302 unsigned int count, /* Including the first glyp
h */ | 402 unsigned int count, /* Including the first glyp
h */ |
303 unsigned int lookupCount, | 403 unsigned int lookupCount, |
304 const LookupRecord lookupRecord[], /* Array of
LookupRecords--in design order */ | 404 const LookupRecord lookupRecord[], /* Array of
LookupRecords--in design order */ |
305 apply_lookup_func_t apply_func) | 405 apply_lookup_func_t apply_func) |
306 { | 406 { |
307 unsigned int end = MIN (c->buffer->len, c->buffer->idx + c->context_length); | 407 unsigned int end = c->buffer->len; |
308 if (unlikely (count == 0 || c->buffer->idx + count > end)) | 408 if (unlikely (count == 0 || c->buffer->idx + count > end)) |
309 return false; | 409 return false; |
310 | 410 |
311 /* TODO We don't support lookupRecord arrays that are not increasing: | 411 /* TODO We don't support lookupRecord arrays that are not increasing: |
312 * Should be easy for in_place ones at least. */ | 412 * Should be easy for in_place ones at least. */ |
313 | 413 |
314 /* Note: If sublookup is reverse, it will underflow after the first loop | 414 /* Note: If sublookup is reverse, it will underflow after the first loop |
315 * and we jump out of it. Not entirely disastrous. So we don't check | 415 * and we jump out of it. Not entirely disastrous. So we don't check |
316 * for reverse lookup here. | 416 * for reverse lookup here. |
317 */ | 417 */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 } | 453 } |
354 } | 454 } |
355 | 455 |
356 return true; | 456 return true; |
357 } | 457 } |
358 | 458 |
359 | 459 |
360 | 460 |
361 /* Contextual lookups */ | 461 /* Contextual lookups */ |
362 | 462 |
363 struct ContextLookupContext | 463 struct ContextClosureLookupContext |
364 { | 464 { |
365 ContextFuncs funcs; | 465 ContextClosureFuncs funcs; |
| 466 const void *intersects_data; |
| 467 }; |
| 468 |
| 469 struct ContextApplyLookupContext |
| 470 { |
| 471 ContextApplyFuncs funcs; |
366 const void *match_data; | 472 const void *match_data; |
367 }; | 473 }; |
368 | 474 |
369 static inline bool context_lookup (hb_apply_context_t *c, | 475 static inline void context_closure_lookup (hb_closure_context_t *c, |
370 » » » » unsigned int inputCount, /* Including the fir
st glyph (not matched) */ | 476 » » » » » unsigned int inputCount, /* Including
the first glyph (not matched) */ |
371 » » » » const USHORT input[], /* Array of input value
s--start with second glyph */ | 477 » » » » » const USHORT input[], /* Array of inp
ut values--start with second glyph */ |
372 » » » » unsigned int lookupCount, | 478 » » » » » unsigned int lookupCount, |
373 » » » » const LookupRecord lookupRecord[], | 479 » » » » » const LookupRecord lookupRecord[], |
374 » » » » ContextLookupContext &lookup_context) | 480 » » » » » ContextClosureLookupContext &lookup_c
ontext) |
375 { | 481 { |
376 hb_apply_context_t new_context = *c; | 482 if (intersects_array (c, |
| 483 » » » inputCount ? inputCount - 1 : 0, input, |
| 484 » » » lookup_context.funcs.intersects, lookup_context.intersec
ts_data)) |
| 485 closure_lookup (c, |
| 486 » » lookupCount, lookupRecord, |
| 487 » » lookup_context.funcs.closure); |
| 488 } |
| 489 |
| 490 |
| 491 static inline bool context_apply_lookup (hb_apply_context_t *c, |
| 492 » » » » » unsigned int inputCount, /* Including t
he first glyph (not matched) */ |
| 493 » » » » » const USHORT input[], /* Array of input
values--start with second glyph */ |
| 494 » » » » » unsigned int lookupCount, |
| 495 » » » » » const LookupRecord lookupRecord[], |
| 496 » » » » » ContextApplyLookupContext &lookup_conte
xt) |
| 497 { |
377 return match_input (c, | 498 return match_input (c, |
378 inputCount, input, | 499 inputCount, input, |
379 » » lookup_context.funcs.match, lookup_context.match_data, | 500 » » lookup_context.funcs.match, lookup_context.match_data) |
380 » » &new_context.context_length) | 501 && apply_lookup (c, |
381 && apply_lookup (&new_context, | |
382 inputCount, | 502 inputCount, |
383 lookupCount, lookupRecord, | 503 lookupCount, lookupRecord, |
384 lookup_context.funcs.apply); | 504 lookup_context.funcs.apply); |
385 } | 505 } |
386 | 506 |
387 struct Rule | 507 struct Rule |
388 { | 508 { |
389 friend struct RuleSet; | 509 friend struct RuleSet; |
390 | 510 |
391 private: | 511 private: |
392 inline bool apply (hb_apply_context_t *c, ContextLookupContext &lookup_context
) const | 512 |
| 513 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const |
| 514 { |
| 515 TRACE_CLOSURE (); |
| 516 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); |
| 517 context_closure_lookup (c, |
| 518 » » » inputCount, input, |
| 519 » » » lookupCount, lookupRecord, |
| 520 » » » lookup_context); |
| 521 } |
| 522 |
| 523 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const |
393 { | 524 { |
394 TRACE_APPLY (); | 525 TRACE_APPLY (); |
395 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); | 526 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp
ut[0].static_size * (inputCount ? inputCount - 1 : 0)); |
396 return context_lookup (c, | 527 return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount
, lookupRecord, lookup_context)); |
397 » » » inputCount, input, | |
398 » » » lookupCount, lookupRecord, | |
399 » » » lookup_context); | |
400 } | 528 } |
401 | 529 |
402 public: | 530 public: |
403 inline bool sanitize (hb_sanitize_context_t *c) { | 531 inline bool sanitize (hb_sanitize_context_t *c) { |
404 TRACE_SANITIZE (); | 532 TRACE_SANITIZE (); |
405 return inputCount.sanitize (c) | 533 return inputCount.sanitize (c) |
406 && lookupCount.sanitize (c) | 534 && lookupCount.sanitize (c) |
407 && c->check_range (input, | 535 && c->check_range (input, |
408 » » » » input[0].static_size * inputCount | 536 » » » input[0].static_size * inputCount |
409 » » » » + lookupRecordX[0].static_size * lookupCount); | 537 » » » + lookupRecordX[0].static_size * lookupCount); |
410 } | 538 } |
411 | 539 |
412 private: | 540 private: |
413 USHORT inputCount; /* Total number of glyphs in input | 541 USHORT inputCount; /* Total number of glyphs in input |
414 » » » » » * glyph sequence--includes the first | 542 » » » » » * glyph sequence--includes the first |
415 * glyph */ | 543 * glyph */ |
416 USHORT lookupCount; /* Number of LookupRecords */ | 544 USHORT lookupCount; /* Number of LookupRecords */ |
417 USHORT input[VAR]; /* Array of match inputs--start with | 545 USHORT input[VAR]; /* Array of match inputs--start with |
418 * second glyph */ | 546 * second glyph */ |
419 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in | 547 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
420 * design order */ | 548 * design order */ |
421 public: | 549 public: |
422 DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); | 550 DEFINE_SIZE_ARRAY2 (4, input, lookupRecordX); |
423 }; | 551 }; |
424 | 552 |
425 struct RuleSet | 553 struct RuleSet |
426 { | 554 { |
427 inline bool apply (hb_apply_context_t *c, ContextLookupContext &lookup_context
) const | 555 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo
kup_context) const |
| 556 { |
| 557 TRACE_CLOSURE (); |
| 558 unsigned int num_rules = rule.len; |
| 559 for (unsigned int i = 0; i < num_rules; i++) |
| 560 (this+rule[i]).closure (c, lookup_context); |
| 561 } |
| 562 |
| 563 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const |
428 { | 564 { |
429 TRACE_APPLY (); | 565 TRACE_APPLY (); |
430 unsigned int num_rules = rule.len; | 566 unsigned int num_rules = rule.len; |
431 for (unsigned int i = 0; i < num_rules; i++) | 567 for (unsigned int i = 0; i < num_rules; i++) |
432 { | 568 { |
433 if ((this+rule[i]).apply (c, lookup_context)) | 569 if ((this+rule[i]).apply (c, lookup_context)) |
434 return true; | 570 return TRACE_RETURN (true); |
435 } | 571 } |
436 | 572 return TRACE_RETURN (false); |
437 return false; | |
438 } | 573 } |
439 | 574 |
440 inline bool sanitize (hb_sanitize_context_t *c) { | 575 inline bool sanitize (hb_sanitize_context_t *c) { |
441 TRACE_SANITIZE (); | 576 TRACE_SANITIZE (); |
442 return rule.sanitize (c, this); | 577 return TRACE_RETURN (rule.sanitize (c, this)); |
443 } | 578 } |
444 | 579 |
445 private: | 580 private: |
446 OffsetArrayOf<Rule> | 581 OffsetArrayOf<Rule> |
447 rule; /* Array of Rule tables | 582 rule; /* Array of Rule tables |
448 * ordered by preference */ | 583 * ordered by preference */ |
449 public: | 584 public: |
450 DEFINE_SIZE_ARRAY (2, rule); | 585 DEFINE_SIZE_ARRAY (2, rule); |
451 }; | 586 }; |
452 | 587 |
453 | 588 |
454 struct ContextFormat1 | 589 struct ContextFormat1 |
455 { | 590 { |
456 friend struct Context; | 591 friend struct Context; |
457 | 592 |
458 private: | 593 private: |
| 594 |
| 595 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 596 { |
| 597 TRACE_CLOSURE (); |
| 598 |
| 599 const Coverage &cov = (this+coverage); |
| 600 |
| 601 struct ContextClosureLookupContext lookup_context = { |
| 602 {intersects_glyph, closure_func}, |
| 603 NULL |
| 604 }; |
| 605 |
| 606 unsigned int count = ruleSet.len; |
| 607 for (unsigned int i = 0; i < count; i++) |
| 608 if (cov.intersects_coverage (c->glyphs, i)) { |
| 609 const RuleSet &rule_set = this+ruleSet[i]; |
| 610 rule_set.closure (c, lookup_context); |
| 611 } |
| 612 } |
| 613 |
459 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 614 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
460 { | 615 { |
461 TRACE_APPLY (); | 616 TRACE_APPLY (); |
462 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 617 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
463 if (likely (index == NOT_COVERED)) | 618 if (likely (index == NOT_COVERED)) |
464 return false; | 619 return TRACE_RETURN (false); |
465 | 620 |
466 const RuleSet &rule_set = this+ruleSet[index]; | 621 const RuleSet &rule_set = this+ruleSet[index]; |
467 struct ContextLookupContext lookup_context = { | 622 struct ContextApplyLookupContext lookup_context = { |
468 {match_glyph, apply_func}, | 623 {match_glyph, apply_func}, |
469 NULL | 624 NULL |
470 }; | 625 }; |
471 return rule_set.apply (c, lookup_context); | 626 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
472 } | 627 } |
473 | 628 |
474 inline bool sanitize (hb_sanitize_context_t *c) { | 629 inline bool sanitize (hb_sanitize_context_t *c) { |
475 TRACE_SANITIZE (); | 630 TRACE_SANITIZE (); |
476 return coverage.sanitize (c, this) | 631 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
477 » && ruleSet.sanitize (c, this); | |
478 } | 632 } |
479 | 633 |
480 private: | 634 private: |
481 USHORT format; /* Format identifier--format = 1 */ | 635 USHORT format; /* Format identifier--format = 1 */ |
482 OffsetTo<Coverage> | 636 OffsetTo<Coverage> |
483 coverage; /* Offset to Coverage table--from | 637 coverage; /* Offset to Coverage table--from |
484 * beginning of table */ | 638 * beginning of table */ |
485 OffsetArrayOf<RuleSet> | 639 OffsetArrayOf<RuleSet> |
486 ruleSet; /* Array of RuleSet tables | 640 ruleSet; /* Array of RuleSet tables |
487 * ordered by Coverage Index */ | 641 * ordered by Coverage Index */ |
488 public: | 642 public: |
489 DEFINE_SIZE_ARRAY (6, ruleSet); | 643 DEFINE_SIZE_ARRAY (6, ruleSet); |
490 }; | 644 }; |
491 | 645 |
492 | 646 |
493 struct ContextFormat2 | 647 struct ContextFormat2 |
494 { | 648 { |
495 friend struct Context; | 649 friend struct Context; |
496 | 650 |
497 private: | 651 private: |
| 652 |
| 653 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 654 { |
| 655 TRACE_CLOSURE (); |
| 656 if (!(this+coverage).intersects (c->glyphs)) |
| 657 return; |
| 658 |
| 659 const ClassDef &class_def = this+classDef; |
| 660 |
| 661 struct ContextClosureLookupContext lookup_context = { |
| 662 {intersects_class, closure_func}, |
| 663 NULL |
| 664 }; |
| 665 |
| 666 unsigned int count = ruleSet.len; |
| 667 for (unsigned int i = 0; i < count; i++) |
| 668 if (class_def.intersects_class (c->glyphs, i)) { |
| 669 const RuleSet &rule_set = this+ruleSet[i]; |
| 670 rule_set.closure (c, lookup_context); |
| 671 } |
| 672 } |
| 673 |
498 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 674 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
499 { | 675 { |
500 TRACE_APPLY (); | 676 TRACE_APPLY (); |
501 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 677 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
502 if (likely (index == NOT_COVERED)) | 678 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
503 return false; | |
504 | 679 |
505 const ClassDef &class_def = this+classDef; | 680 const ClassDef &class_def = this+classDef; |
506 index = class_def (c->buffer->info[c->buffer->idx].codepoint); | 681 index = class_def (c->buffer->cur().codepoint); |
507 const RuleSet &rule_set = this+ruleSet[index]; | 682 const RuleSet &rule_set = this+ruleSet[index]; |
508 struct ContextLookupContext lookup_context = { | 683 struct ContextApplyLookupContext lookup_context = { |
509 {match_class, apply_func}, | 684 {match_class, apply_func}, |
510 &class_def | 685 &class_def |
511 }; | 686 }; |
512 return rule_set.apply (c, lookup_context); | 687 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
513 } | 688 } |
514 | 689 |
515 inline bool sanitize (hb_sanitize_context_t *c) { | 690 inline bool sanitize (hb_sanitize_context_t *c) { |
516 TRACE_SANITIZE (); | 691 TRACE_SANITIZE (); |
517 return coverage.sanitize (c, this) | 692 return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, th
is) && ruleSet.sanitize (c, this)); |
518 && classDef.sanitize (c, this) | |
519 » && ruleSet.sanitize (c, this); | |
520 } | 693 } |
521 | 694 |
522 private: | 695 private: |
523 USHORT format; /* Format identifier--format = 2 */ | 696 USHORT format; /* Format identifier--format = 2 */ |
524 OffsetTo<Coverage> | 697 OffsetTo<Coverage> |
525 coverage; /* Offset to Coverage table--from | 698 coverage; /* Offset to Coverage table--from |
526 * beginning of table */ | 699 * beginning of table */ |
527 OffsetTo<ClassDef> | 700 OffsetTo<ClassDef> |
528 classDef; /* Offset to glyph ClassDef table--from | 701 classDef; /* Offset to glyph ClassDef table--from |
529 * beginning of table */ | 702 * beginning of table */ |
530 OffsetArrayOf<RuleSet> | 703 OffsetArrayOf<RuleSet> |
531 ruleSet; /* Array of RuleSet tables | 704 ruleSet; /* Array of RuleSet tables |
532 * ordered by class */ | 705 * ordered by class */ |
533 public: | 706 public: |
534 DEFINE_SIZE_ARRAY (8, ruleSet); | 707 DEFINE_SIZE_ARRAY (8, ruleSet); |
535 }; | 708 }; |
536 | 709 |
537 | 710 |
538 struct ContextFormat3 | 711 struct ContextFormat3 |
539 { | 712 { |
540 friend struct Context; | 713 friend struct Context; |
541 | 714 |
542 private: | 715 private: |
| 716 |
| 717 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 718 { |
| 719 TRACE_CLOSURE (); |
| 720 if (!(this+coverage[0]).intersects (c->glyphs)) |
| 721 return; |
| 722 |
| 723 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); |
| 724 struct ContextClosureLookupContext lookup_context = { |
| 725 {intersects_coverage, closure_func}, |
| 726 this |
| 727 }; |
| 728 context_closure_lookup (c, |
| 729 glyphCount, (const USHORT *) (coverage + 1), |
| 730 lookupCount, lookupRecord, |
| 731 lookup_context); |
| 732 } |
| 733 |
543 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 734 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
544 { | 735 { |
545 TRACE_APPLY (); | 736 TRACE_APPLY (); |
546 unsigned int index = (this+coverage[0]) (c->buffer->info[c->buffer->idx].cod
epoint); | 737 unsigned int index = (this+coverage[0]) (c->buffer->cur().codepoint); |
547 if (likely (index == NOT_COVERED)) | 738 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
548 return false; | |
549 | 739 |
550 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); | 740 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage,
coverage[0].static_size * glyphCount); |
551 struct ContextLookupContext lookup_context = { | 741 struct ContextApplyLookupContext lookup_context = { |
552 {match_coverage, apply_func}, | 742 {match_coverage, apply_func}, |
553 this | 743 this |
554 }; | 744 }; |
555 return context_lookup (c, | 745 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (
coverage + 1), lookupCount, lookupRecord, lookup_context)); |
556 » » » glyphCount, (const USHORT *) (coverage + 1), | |
557 » » » lookupCount, lookupRecord, | |
558 » » » lookup_context); | |
559 } | 746 } |
560 | 747 |
561 inline bool sanitize (hb_sanitize_context_t *c) { | 748 inline bool sanitize (hb_sanitize_context_t *c) { |
562 TRACE_SANITIZE (); | 749 TRACE_SANITIZE (); |
563 if (!c->check_struct (this)) return false; | 750 if (!c->check_struct (this)) return TRACE_RETURN (false); |
564 unsigned int count = glyphCount; | 751 unsigned int count = glyphCount; |
565 if (!c->check_array (coverage, coverage[0].static_size, count)) return false
; | 752 if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE
_RETURN (false); |
566 for (unsigned int i = 0; i < count; i++) | 753 for (unsigned int i = 0; i < count; i++) |
567 if (!coverage[i].sanitize (c, this)) return false; | 754 if (!coverage[i].sanitize (c, this)) return TRACE_RETURN (false); |
568 LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, covera
ge[0].static_size * count); | 755 LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, covera
ge[0].static_size * count); |
569 return c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCoun
t); | 756 return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_si
ze, lookupCount)); |
570 } | 757 } |
571 | 758 |
572 private: | 759 private: |
573 USHORT format; /* Format identifier--format = 3 */ | 760 USHORT format; /* Format identifier--format = 3 */ |
574 USHORT glyphCount; /* Number of glyphs in the input glyph | 761 USHORT glyphCount; /* Number of glyphs in the input glyph |
575 * sequence */ | 762 * sequence */ |
576 USHORT lookupCount; /* Number of LookupRecords */ | 763 USHORT lookupCount; /* Number of LookupRecords */ |
577 OffsetTo<Coverage> | 764 OffsetTo<Coverage> |
578 coverage[VAR]; /* Array of offsets to Coverage | 765 coverage[VAR]; /* Array of offsets to Coverage |
579 * table in glyph sequence order */ | 766 * table in glyph sequence order */ |
580 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in | 767 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
581 * design order */ | 768 * design order */ |
582 public: | 769 public: |
583 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); | 770 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); |
584 }; | 771 }; |
585 | 772 |
586 struct Context | 773 struct Context |
587 { | 774 { |
588 protected: | 775 protected: |
| 776 |
| 777 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 778 { |
| 779 TRACE_CLOSURE (); |
| 780 switch (u.format) { |
| 781 case 1: u.format1.closure (c, closure_func); break; |
| 782 case 2: u.format2.closure (c, closure_func); break; |
| 783 case 3: u.format3.closure (c, closure_func); break; |
| 784 default: break; |
| 785 } |
| 786 } |
| 787 |
589 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 788 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
590 { | 789 { |
591 TRACE_APPLY (); | 790 TRACE_APPLY (); |
592 switch (u.format) { | 791 switch (u.format) { |
593 case 1: return u.format1.apply (c, apply_func); | 792 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); |
594 case 2: return u.format2.apply (c, apply_func); | 793 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); |
595 case 3: return u.format3.apply (c, apply_func); | 794 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); |
596 default:return false; | 795 default:return TRACE_RETURN (false); |
597 } | 796 } |
598 } | 797 } |
599 | 798 |
600 inline bool sanitize (hb_sanitize_context_t *c) { | 799 inline bool sanitize (hb_sanitize_context_t *c) { |
601 TRACE_SANITIZE (); | 800 TRACE_SANITIZE (); |
602 if (!u.format.sanitize (c)) return false; | 801 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
603 switch (u.format) { | 802 switch (u.format) { |
604 case 1: return u.format1.sanitize (c); | 803 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
605 case 2: return u.format2.sanitize (c); | 804 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
606 case 3: return u.format3.sanitize (c); | 805 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
607 default:return true; | 806 default:return TRACE_RETURN (true); |
608 } | 807 } |
609 } | 808 } |
610 | 809 |
611 private: | 810 private: |
612 union { | 811 union { |
613 USHORT format; /* Format identifier */ | 812 USHORT format; /* Format identifier */ |
614 ContextFormat1 format1; | 813 ContextFormat1 format1; |
615 ContextFormat2 format2; | 814 ContextFormat2 format2; |
616 ContextFormat3 format3; | 815 ContextFormat3 format3; |
617 } u; | 816 } u; |
618 }; | 817 }; |
619 | 818 |
620 | 819 |
621 /* Chaining Contextual lookups */ | 820 /* Chaining Contextual lookups */ |
622 | 821 |
623 struct ChainContextLookupContext | 822 struct ChainContextClosureLookupContext |
624 { | 823 { |
625 ContextFuncs funcs; | 824 ContextClosureFuncs funcs; |
| 825 const void *intersects_data[3]; |
| 826 }; |
| 827 |
| 828 struct ChainContextApplyLookupContext |
| 829 { |
| 830 ContextApplyFuncs funcs; |
626 const void *match_data[3]; | 831 const void *match_data[3]; |
627 }; | 832 }; |
628 | 833 |
629 static inline bool chain_context_lookup (hb_apply_context_t *c, | 834 static inline void chain_context_closure_lookup (hb_closure_context_t *c, |
630 » » » » » unsigned int backtrackCount, | 835 » » » » » » unsigned int backtrackCount, |
631 » » » » » const USHORT backtrack[], | 836 » » » » » » const USHORT backtrack[], |
632 » » » » » unsigned int inputCount, /* Including t
he first glyph (not matched) */ | 837 » » » » » » unsigned int inputCount, /* Inc
luding the first glyph (not matched) */ |
633 » » » » » const USHORT input[], /* Array of input
values--start with second glyph */ | 838 » » » » » » const USHORT input[], /* Array
of input values--start with second glyph */ |
634 » » » » » unsigned int lookaheadCount, | 839 » » » » » » unsigned int lookaheadCount, |
635 » » » » » const USHORT lookahead[], | 840 » » » » » » const USHORT lookahead[], |
636 » » » » » unsigned int lookupCount, | 841 » » » » » » unsigned int lookupCount, |
637 » » » » » const LookupRecord lookupRecord[], | 842 » » » » » » const LookupRecord lookupRecord
[], |
638 » » » » » ChainContextLookupContext &lookup_conte
xt) | 843 » » » » » » ChainContextClosureLookupContex
t &lookup_context) |
639 { | 844 { |
640 /* First guess */ | 845 if (intersects_array (c, |
641 if (unlikely (c->buffer->backtrack_len () < backtrackCount || | 846 » » » backtrackCount, backtrack, |
642 » » c->buffer->idx + inputCount + lookaheadCount > c->buffer->len || | 847 » » » lookup_context.funcs.intersects, lookup_context.intersec
ts_data[0]) |
643 » » inputCount + lookaheadCount > c->context_length)) | 848 && intersects_array (c, |
644 return false; | 849 » » » inputCount ? inputCount - 1 : 0, input, |
| 850 » » » lookup_context.funcs.intersects, lookup_context.intersec
ts_data[1]) |
| 851 && intersects_array (c, |
| 852 » » lookaheadCount, lookahead, |
| 853 » » lookup_context.funcs.intersects, lookup_context.intersect
s_data[2])) |
| 854 closure_lookup (c, |
| 855 » » lookupCount, lookupRecord, |
| 856 » » lookup_context.funcs.closure); |
| 857 } |
645 | 858 |
646 hb_apply_context_t new_context = *c; | 859 static inline bool chain_context_apply_lookup (hb_apply_context_t *c, |
| 860 » » » » » unsigned int backtrackCount, |
| 861 » » » » » const USHORT backtrack[], |
| 862 » » » » » unsigned int inputCount, /* Inclu
ding the first glyph (not matched) */ |
| 863 » » » » » const USHORT input[], /* Array of
input values--start with second glyph */ |
| 864 » » » » » unsigned int lookaheadCount, |
| 865 » » » » » const USHORT lookahead[], |
| 866 » » » » » unsigned int lookupCount, |
| 867 » » » » » const LookupRecord lookupRecord[]
, |
| 868 » » » » » ChainContextApplyLookupContext &l
ookup_context) |
| 869 { |
| 870 unsigned int lookahead_offset; |
647 return match_backtrack (c, | 871 return match_backtrack (c, |
648 backtrackCount, backtrack, | 872 backtrackCount, backtrack, |
649 lookup_context.funcs.match, lookup_context.match_data[
0]) | 873 lookup_context.funcs.match, lookup_context.match_data[
0]) |
650 && match_input (c, | 874 && match_input (c, |
651 inputCount, input, | 875 inputCount, input, |
652 lookup_context.funcs.match, lookup_context.match_data[1], | 876 lookup_context.funcs.match, lookup_context.match_data[1], |
653 » » &new_context.context_length) | 877 » » &lookahead_offset) |
654 && match_lookahead (c, | 878 && match_lookahead (c, |
655 lookaheadCount, lookahead, | 879 lookaheadCount, lookahead, |
656 lookup_context.funcs.match, lookup_context.match_data[
2], | 880 lookup_context.funcs.match, lookup_context.match_data[
2], |
657 » » » new_context.context_length) | 881 » » » lookahead_offset) |
658 && apply_lookup (&new_context, | 882 && apply_lookup (c, |
659 inputCount, | 883 inputCount, |
660 lookupCount, lookupRecord, | 884 lookupCount, lookupRecord, |
661 lookup_context.funcs.apply); | 885 lookup_context.funcs.apply); |
662 } | 886 } |
663 | 887 |
664 struct ChainRule | 888 struct ChainRule |
665 { | 889 { |
666 friend struct ChainRuleSet; | 890 friend struct ChainRuleSet; |
667 | 891 |
668 private: | 892 private: |
669 inline bool apply (hb_apply_context_t *c, ChainContextLookupContext &lookup_co
ntext) const | 893 |
| 894 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext
&lookup_context) const |
| 895 { |
| 896 TRACE_CLOSURE (); |
| 897 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
| 898 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
| 899 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
| 900 chain_context_closure_lookup (c, |
| 901 » » » » backtrack.len, backtrack.array, |
| 902 » » » » input.len, input.array, |
| 903 » » » » lookahead.len, lookahead.array, |
| 904 » » » » lookup.len, lookup.array, |
| 905 » » » » lookup_context); |
| 906 } |
| 907 |
| 908 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const |
670 { | 909 { |
671 TRACE_APPLY (); | 910 TRACE_APPLY (); |
672 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); | 911 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
673 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 912 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
674 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 913 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
675 return chain_context_lookup (c, | 914 return TRACE_RETURN (chain_context_apply_lookup (c, |
676 » » » » backtrack.len, backtrack.array, | 915 » » » » » » backtrack.len, backtrack.ar
ray, |
677 » » » » input.len, input.array, | 916 » » » » » » input.len, input.array, |
678 » » » » lookahead.len, lookahead.array, | 917 » » » » » » lookahead.len, lookahead.ar
ray, lookup.len, |
679 » » » » lookup.len, lookup.array, | 918 » » » » » » lookup.array, lookup_contex
t)); |
680 » » » » lookup_context); | |
681 } | 919 } |
682 | 920 |
683 public: | 921 public: |
684 inline bool sanitize (hb_sanitize_context_t *c) { | 922 inline bool sanitize (hb_sanitize_context_t *c) { |
685 TRACE_SANITIZE (); | 923 TRACE_SANITIZE (); |
686 if (!backtrack.sanitize (c)) return false; | 924 if (!backtrack.sanitize (c)) return TRACE_RETURN (false); |
687 HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (back
track); | 925 HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (back
track); |
688 if (!input.sanitize (c)) return false; | 926 if (!input.sanitize (c)) return TRACE_RETURN (false); |
689 ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 927 ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
690 if (!lookahead.sanitize (c)) return false; | 928 if (!lookahead.sanitize (c)) return TRACE_RETURN (false); |
691 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 929 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); |
692 return lookup.sanitize (c); | 930 return TRACE_RETURN (lookup.sanitize (c)); |
693 } | 931 } |
694 | 932 |
695 private: | 933 private: |
696 ArrayOf<USHORT> | 934 ArrayOf<USHORT> |
697 backtrack; /* Array of backtracking values | 935 backtrack; /* Array of backtracking values |
698 * (to be matched before the input | 936 * (to be matched before the input |
699 * sequence) */ | 937 * sequence) */ |
700 HeadlessArrayOf<USHORT> | 938 HeadlessArrayOf<USHORT> |
701 inputX; /* Array of input values (start with | 939 inputX; /* Array of input values (start with |
702 * second glyph) */ | 940 * second glyph) */ |
703 ArrayOf<USHORT> | 941 ArrayOf<USHORT> |
704 lookaheadX; /* Array of lookahead values's (to be | 942 lookaheadX; /* Array of lookahead values's (to be |
705 * matched after the input sequence) */ | 943 * matched after the input sequence) */ |
706 ArrayOf<LookupRecord> | 944 ArrayOf<LookupRecord> |
707 lookupX; /* Array of LookupRecords--in | 945 lookupX; /* Array of LookupRecords--in |
708 * design order) */ | 946 * design order) */ |
709 public: | 947 public: |
710 DEFINE_SIZE_MIN (8); | 948 DEFINE_SIZE_MIN (8); |
711 }; | 949 }; |
712 | 950 |
713 struct ChainRuleSet | 951 struct ChainRuleSet |
714 { | 952 { |
715 inline bool apply (hb_apply_context_t *c, ChainContextLookupContext &lookup_co
ntext) const | 953 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext
&lookup_context) const |
| 954 { |
| 955 TRACE_CLOSURE (); |
| 956 unsigned int num_rules = rule.len; |
| 957 for (unsigned int i = 0; i < num_rules; i++) |
| 958 (this+rule[i]).closure (c, lookup_context); |
| 959 } |
| 960 |
| 961 inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &look
up_context) const |
716 { | 962 { |
717 TRACE_APPLY (); | 963 TRACE_APPLY (); |
718 unsigned int num_rules = rule.len; | 964 unsigned int num_rules = rule.len; |
719 for (unsigned int i = 0; i < num_rules; i++) | 965 for (unsigned int i = 0; i < num_rules; i++) |
720 { | |
721 if ((this+rule[i]).apply (c, lookup_context)) | 966 if ((this+rule[i]).apply (c, lookup_context)) |
722 return true; | 967 return TRACE_RETURN (true); |
723 } | |
724 | 968 |
725 return false; | 969 return TRACE_RETURN (false); |
726 } | 970 } |
727 | 971 |
728 inline bool sanitize (hb_sanitize_context_t *c) { | 972 inline bool sanitize (hb_sanitize_context_t *c) { |
729 TRACE_SANITIZE (); | 973 TRACE_SANITIZE (); |
730 return rule.sanitize (c, this); | 974 return TRACE_RETURN (rule.sanitize (c, this)); |
731 } | 975 } |
732 | 976 |
733 private: | 977 private: |
734 OffsetArrayOf<ChainRule> | 978 OffsetArrayOf<ChainRule> |
735 rule; /* Array of ChainRule tables | 979 rule; /* Array of ChainRule tables |
736 * ordered by preference */ | 980 * ordered by preference */ |
737 public: | 981 public: |
738 DEFINE_SIZE_ARRAY (2, rule); | 982 DEFINE_SIZE_ARRAY (2, rule); |
739 }; | 983 }; |
740 | 984 |
741 struct ChainContextFormat1 | 985 struct ChainContextFormat1 |
742 { | 986 { |
743 friend struct ChainContext; | 987 friend struct ChainContext; |
744 | 988 |
745 private: | 989 private: |
| 990 |
| 991 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 992 { |
| 993 TRACE_CLOSURE (); |
| 994 const Coverage &cov = (this+coverage); |
| 995 |
| 996 struct ChainContextClosureLookupContext lookup_context = { |
| 997 {intersects_glyph, closure_func}, |
| 998 {NULL, NULL, NULL} |
| 999 }; |
| 1000 |
| 1001 unsigned int count = ruleSet.len; |
| 1002 for (unsigned int i = 0; i < count; i++) |
| 1003 if (cov.intersects_coverage (c->glyphs, i)) { |
| 1004 const ChainRuleSet &rule_set = this+ruleSet[i]; |
| 1005 rule_set.closure (c, lookup_context); |
| 1006 } |
| 1007 } |
| 1008 |
746 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1009 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
747 { | 1010 { |
748 TRACE_APPLY (); | 1011 TRACE_APPLY (); |
749 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 1012 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
750 if (likely (index == NOT_COVERED)) | 1013 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
751 return false; | |
752 | 1014 |
753 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1015 const ChainRuleSet &rule_set = this+ruleSet[index]; |
754 struct ChainContextLookupContext lookup_context = { | 1016 struct ChainContextApplyLookupContext lookup_context = { |
755 {match_glyph, apply_func}, | 1017 {match_glyph, apply_func}, |
756 {NULL, NULL, NULL} | 1018 {NULL, NULL, NULL} |
757 }; | 1019 }; |
758 return rule_set.apply (c, lookup_context); | 1020 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
759 } | 1021 } |
760 | 1022 |
761 inline bool sanitize (hb_sanitize_context_t *c) { | 1023 inline bool sanitize (hb_sanitize_context_t *c) { |
762 TRACE_SANITIZE (); | 1024 TRACE_SANITIZE (); |
763 return coverage.sanitize (c, this) | 1025 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
764 » && ruleSet.sanitize (c, this); | |
765 } | 1026 } |
766 | 1027 |
767 private: | 1028 private: |
768 USHORT format; /* Format identifier--format = 1 */ | 1029 USHORT format; /* Format identifier--format = 1 */ |
769 OffsetTo<Coverage> | 1030 OffsetTo<Coverage> |
770 coverage; /* Offset to Coverage table--from | 1031 coverage; /* Offset to Coverage table--from |
771 * beginning of table */ | 1032 * beginning of table */ |
772 OffsetArrayOf<ChainRuleSet> | 1033 OffsetArrayOf<ChainRuleSet> |
773 ruleSet; /* Array of ChainRuleSet tables | 1034 ruleSet; /* Array of ChainRuleSet tables |
774 * ordered by Coverage Index */ | 1035 * ordered by Coverage Index */ |
775 public: | 1036 public: |
776 DEFINE_SIZE_ARRAY (6, ruleSet); | 1037 DEFINE_SIZE_ARRAY (6, ruleSet); |
777 }; | 1038 }; |
778 | 1039 |
779 struct ChainContextFormat2 | 1040 struct ChainContextFormat2 |
780 { | 1041 { |
781 friend struct ChainContext; | 1042 friend struct ChainContext; |
782 | 1043 |
783 private: | 1044 private: |
784 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1045 |
| 1046 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
785 { | 1047 { |
786 TRACE_APPLY (); | 1048 TRACE_CLOSURE (); |
787 unsigned int index = (this+coverage) (c->buffer->info[c->buffer->idx].codepo
int); | 1049 if (!(this+coverage).intersects (c->glyphs)) |
788 if (likely (index == NOT_COVERED)) | 1050 return; |
789 return false; | |
790 | 1051 |
791 const ClassDef &backtrack_class_def = this+backtrackClassDef; | 1052 const ClassDef &backtrack_class_def = this+backtrackClassDef; |
792 const ClassDef &input_class_def = this+inputClassDef; | 1053 const ClassDef &input_class_def = this+inputClassDef; |
793 const ClassDef &lookahead_class_def = this+lookaheadClassDef; | 1054 const ClassDef &lookahead_class_def = this+lookaheadClassDef; |
794 | 1055 |
795 index = input_class_def (c->buffer->info[c->buffer->idx].codepoint); | 1056 struct ChainContextClosureLookupContext lookup_context = { |
| 1057 {intersects_class, closure_func}, |
| 1058 {&backtrack_class_def, |
| 1059 &input_class_def, |
| 1060 &lookahead_class_def} |
| 1061 }; |
| 1062 |
| 1063 unsigned int count = ruleSet.len; |
| 1064 for (unsigned int i = 0; i < count; i++) |
| 1065 if (input_class_def.intersects_class (c->glyphs, i)) { |
| 1066 » const ChainRuleSet &rule_set = this+ruleSet[i]; |
| 1067 » rule_set.closure (c, lookup_context); |
| 1068 } |
| 1069 } |
| 1070 |
| 1071 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
| 1072 { |
| 1073 TRACE_APPLY (); |
| 1074 unsigned int index = (this+coverage) (c->buffer->cur().codepoint); |
| 1075 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
| 1076 |
| 1077 const ClassDef &backtrack_class_def = this+backtrackClassDef; |
| 1078 const ClassDef &input_class_def = this+inputClassDef; |
| 1079 const ClassDef &lookahead_class_def = this+lookaheadClassDef; |
| 1080 |
| 1081 index = input_class_def (c->buffer->cur().codepoint); |
796 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1082 const ChainRuleSet &rule_set = this+ruleSet[index]; |
797 struct ChainContextLookupContext lookup_context = { | 1083 struct ChainContextApplyLookupContext lookup_context = { |
798 {match_class, apply_func}, | 1084 {match_class, apply_func}, |
799 {&backtrack_class_def, | 1085 {&backtrack_class_def, |
800 &input_class_def, | 1086 &input_class_def, |
801 &lookahead_class_def} | 1087 &lookahead_class_def} |
802 }; | 1088 }; |
803 return rule_set.apply (c, lookup_context); | 1089 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
804 } | 1090 } |
805 | 1091 |
806 inline bool sanitize (hb_sanitize_context_t *c) { | 1092 inline bool sanitize (hb_sanitize_context_t *c) { |
807 TRACE_SANITIZE (); | 1093 TRACE_SANITIZE (); |
808 return coverage.sanitize (c, this) | 1094 return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.saniti
ze (c, this) && |
809 » && backtrackClassDef.sanitize (c, this) | 1095 » » » inputClassDef.sanitize (c, this) && lookaheadClassDef.s
anitize (c, this) && |
810 » && inputClassDef.sanitize (c, this) | 1096 » » » ruleSet.sanitize (c, this)); |
811 » && lookaheadClassDef.sanitize (c, this) | |
812 » && ruleSet.sanitize (c, this); | |
813 } | 1097 } |
814 | 1098 |
815 private: | 1099 private: |
816 USHORT format; /* Format identifier--format = 2 */ | 1100 USHORT format; /* Format identifier--format = 2 */ |
817 OffsetTo<Coverage> | 1101 OffsetTo<Coverage> |
818 coverage; /* Offset to Coverage table--from | 1102 coverage; /* Offset to Coverage table--from |
819 * beginning of table */ | 1103 * beginning of table */ |
820 OffsetTo<ClassDef> | 1104 OffsetTo<ClassDef> |
821 backtrackClassDef; /* Offset to glyph ClassDef table | 1105 backtrackClassDef; /* Offset to glyph ClassDef table |
822 * containing backtrack sequence | 1106 * containing backtrack sequence |
(...skipping 12 matching lines...) Expand all Loading... |
835 public: | 1119 public: |
836 DEFINE_SIZE_ARRAY (12, ruleSet); | 1120 DEFINE_SIZE_ARRAY (12, ruleSet); |
837 }; | 1121 }; |
838 | 1122 |
839 struct ChainContextFormat3 | 1123 struct ChainContextFormat3 |
840 { | 1124 { |
841 friend struct ChainContext; | 1125 friend struct ChainContext; |
842 | 1126 |
843 private: | 1127 private: |
844 | 1128 |
| 1129 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 1130 { |
| 1131 TRACE_CLOSURE (); |
| 1132 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
| 1133 |
| 1134 if (!(this+input[0]).intersects (c->glyphs)) |
| 1135 return; |
| 1136 |
| 1137 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); |
| 1138 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
| 1139 struct ChainContextClosureLookupContext lookup_context = { |
| 1140 {intersects_coverage, closure_func}, |
| 1141 {this, this, this} |
| 1142 }; |
| 1143 chain_context_closure_lookup (c, |
| 1144 backtrack.len, (const USHORT *) backtrack.arra
y, |
| 1145 input.len, (const USHORT *) input.array + 1, |
| 1146 lookahead.len, (const USHORT *) lookahead.arra
y, |
| 1147 lookup.len, lookup.array, |
| 1148 lookup_context); |
| 1149 } |
| 1150 |
845 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1151 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
846 { | 1152 { |
847 TRACE_APPLY (); | 1153 TRACE_APPLY (); |
848 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); | 1154 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
849 | 1155 |
850 unsigned int index = (this+input[0]) (c->buffer->info[c->buffer->idx].codepo
int); | 1156 unsigned int index = (this+input[0]) (c->buffer->cur().codepoint); |
851 if (likely (index == NOT_COVERED)) | 1157 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
852 return false; | |
853 | 1158 |
854 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); | 1159 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); |
855 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 1160 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
856 struct ChainContextLookupContext lookup_context = { | 1161 struct ChainContextApplyLookupContext lookup_context = { |
857 {match_coverage, apply_func}, | 1162 {match_coverage, apply_func}, |
858 {this, this, this} | 1163 {this, this, this} |
859 }; | 1164 }; |
860 return chain_context_lookup (c, | 1165 return TRACE_RETURN (chain_context_apply_lookup (c, |
861 » » » » backtrack.len, (const USHORT *) backtrack.array
, | 1166 » » » » » » backtrack.len, (const USHOR
T *) backtrack.array, |
862 » » » » input.len, (const USHORT *) input.array + 1, | 1167 » » » » » » input.len, (const USHORT *)
input.array + 1, |
863 » » » » lookahead.len, (const USHORT *) lookahead.array
, | 1168 » » » » » » lookahead.len, (const USHOR
T *) lookahead.array, |
864 » » » » lookup.len, lookup.array, | 1169 » » » » » » lookup.len, lookup.array, l
ookup_context)); |
865 » » » » lookup_context); | |
866 } | 1170 } |
867 | 1171 |
868 inline bool sanitize (hb_sanitize_context_t *c) { | 1172 inline bool sanitize (hb_sanitize_context_t *c) { |
869 TRACE_SANITIZE (); | 1173 TRACE_SANITIZE (); |
870 if (!backtrack.sanitize (c, this)) return false; | 1174 if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); |
871 OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (back
track); | 1175 OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (back
track); |
872 if (!input.sanitize (c, this)) return false; | 1176 if (!input.sanitize (c, this)) return TRACE_RETURN (false); |
873 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (
input); | 1177 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (
input); |
874 if (!lookahead.sanitize (c, this)) return false; | 1178 if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); |
875 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 1179 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); |
876 return lookup.sanitize (c); | 1180 return TRACE_RETURN (lookup.sanitize (c)); |
877 } | 1181 } |
878 | 1182 |
879 private: | 1183 private: |
880 USHORT format; /* Format identifier--format = 3 */ | 1184 USHORT format; /* Format identifier--format = 3 */ |
881 OffsetArrayOf<Coverage> | 1185 OffsetArrayOf<Coverage> |
882 backtrack; /* Array of coverage tables | 1186 backtrack; /* Array of coverage tables |
883 * in backtracking sequence, in glyph | 1187 * in backtracking sequence, in glyph |
884 * sequence order */ | 1188 * sequence order */ |
885 OffsetArrayOf<Coverage> | 1189 OffsetArrayOf<Coverage> |
886 inputX ; /* Array of coverage | 1190 inputX ; /* Array of coverage |
887 * tables in input sequence, in glyph | 1191 * tables in input sequence, in glyph |
888 * sequence order */ | 1192 * sequence order */ |
889 OffsetArrayOf<Coverage> | 1193 OffsetArrayOf<Coverage> |
890 lookaheadX; /* Array of coverage tables | 1194 lookaheadX; /* Array of coverage tables |
891 * in lookahead sequence, in glyph | 1195 * in lookahead sequence, in glyph |
892 * sequence order */ | 1196 * sequence order */ |
893 ArrayOf<LookupRecord> | 1197 ArrayOf<LookupRecord> |
894 lookupX; /* Array of LookupRecords--in | 1198 lookupX; /* Array of LookupRecords--in |
895 * design order) */ | 1199 * design order) */ |
896 public: | 1200 public: |
897 DEFINE_SIZE_MIN (10); | 1201 DEFINE_SIZE_MIN (10); |
898 }; | 1202 }; |
899 | 1203 |
900 struct ChainContext | 1204 struct ChainContext |
901 { | 1205 { |
902 protected: | 1206 protected: |
| 1207 |
| 1208 inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_fu
nc) const |
| 1209 { |
| 1210 TRACE_CLOSURE (); |
| 1211 switch (u.format) { |
| 1212 case 1: u.format1.closure (c, closure_func); break; |
| 1213 case 2: u.format2.closure (c, closure_func); break; |
| 1214 case 3: u.format3.closure (c, closure_func); break; |
| 1215 default: break; |
| 1216 } |
| 1217 } |
| 1218 |
903 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t | 1219 inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) cons
t |
904 { | 1220 { |
905 TRACE_APPLY (); | 1221 TRACE_APPLY (); |
906 switch (u.format) { | 1222 switch (u.format) { |
907 case 1: return u.format1.apply (c, apply_func); | 1223 case 1: return TRACE_RETURN (u.format1.apply (c, apply_func)); |
908 case 2: return u.format2.apply (c, apply_func); | 1224 case 2: return TRACE_RETURN (u.format2.apply (c, apply_func)); |
909 case 3: return u.format3.apply (c, apply_func); | 1225 case 3: return TRACE_RETURN (u.format3.apply (c, apply_func)); |
910 default:return false; | 1226 default:return TRACE_RETURN (false); |
911 } | 1227 } |
912 } | 1228 } |
913 | 1229 |
914 inline bool sanitize (hb_sanitize_context_t *c) { | 1230 inline bool sanitize (hb_sanitize_context_t *c) { |
915 TRACE_SANITIZE (); | 1231 TRACE_SANITIZE (); |
916 if (!u.format.sanitize (c)) return false; | 1232 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
917 switch (u.format) { | 1233 switch (u.format) { |
918 case 1: return u.format1.sanitize (c); | 1234 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
919 case 2: return u.format2.sanitize (c); | 1235 case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
920 case 3: return u.format3.sanitize (c); | 1236 case 3: return TRACE_RETURN (u.format3.sanitize (c)); |
921 default:return true; | 1237 default:return TRACE_RETURN (true); |
922 } | 1238 } |
923 } | 1239 } |
924 | 1240 |
925 private: | 1241 private: |
926 union { | 1242 union { |
927 USHORT format; /* Format identifier */ | 1243 USHORT format; /* Format identifier */ |
928 ChainContextFormat1 format1; | 1244 ChainContextFormat1 format1; |
929 ChainContextFormat2 format2; | 1245 ChainContextFormat2 format2; |
930 ChainContextFormat3 format3; | 1246 ChainContextFormat3 format3; |
931 } u; | 1247 } u; |
932 }; | 1248 }; |
933 | 1249 |
934 | 1250 |
935 struct ExtensionFormat1 | 1251 struct ExtensionFormat1 |
936 { | 1252 { |
937 friend struct Extension; | 1253 friend struct Extension; |
938 | 1254 |
939 protected: | 1255 protected: |
940 inline unsigned int get_type (void) const { return extensionLookupType; } | 1256 inline unsigned int get_type (void) const { return extensionLookupType; } |
941 inline unsigned int get_offset (void) const { return extensionOffset; } | 1257 inline unsigned int get_offset (void) const { return extensionOffset; } |
942 | 1258 |
943 inline bool sanitize (hb_sanitize_context_t *c) { | 1259 inline bool sanitize (hb_sanitize_context_t *c) { |
944 TRACE_SANITIZE (); | 1260 TRACE_SANITIZE (); |
945 return c->check_struct (this); | 1261 return TRACE_RETURN (c->check_struct (this)); |
946 } | 1262 } |
947 | 1263 |
948 private: | 1264 private: |
949 USHORT format; /* Format identifier. Set to 1. */ | 1265 USHORT format; /* Format identifier. Set to 1. */ |
950 USHORT extensionLookupType; /* Lookup type of subtable referenced | 1266 USHORT extensionLookupType; /* Lookup type of subtable referenced |
951 * by ExtensionOffset (i.e. the | 1267 * by ExtensionOffset (i.e. the |
952 * extension subtable). */ | 1268 * extension subtable). */ |
953 ULONG extensionOffset; /* Offset to the extension subtable, | 1269 ULONG extensionOffset; /* Offset to the extension subtable, |
954 * of lookup type subtable. */ | 1270 * of lookup type subtable. */ |
955 public: | 1271 public: |
(...skipping 12 matching lines...) Expand all Loading... |
968 inline unsigned int get_offset (void) const | 1284 inline unsigned int get_offset (void) const |
969 { | 1285 { |
970 switch (u.format) { | 1286 switch (u.format) { |
971 case 1: return u.format1.get_offset (); | 1287 case 1: return u.format1.get_offset (); |
972 default:return 0; | 1288 default:return 0; |
973 } | 1289 } |
974 } | 1290 } |
975 | 1291 |
976 inline bool sanitize (hb_sanitize_context_t *c) { | 1292 inline bool sanitize (hb_sanitize_context_t *c) { |
977 TRACE_SANITIZE (); | 1293 TRACE_SANITIZE (); |
978 if (!u.format.sanitize (c)) return false; | 1294 if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
979 switch (u.format) { | 1295 switch (u.format) { |
980 case 1: return u.format1.sanitize (c); | 1296 case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
981 default:return true; | 1297 default:return TRACE_RETURN (true); |
982 } | 1298 } |
983 } | 1299 } |
984 | 1300 |
985 private: | 1301 private: |
986 union { | 1302 union { |
987 USHORT format; /* Format identifier */ | 1303 USHORT format; /* Format identifier */ |
988 ExtensionFormat1 format1; | 1304 ExtensionFormat1 format1; |
989 } u; | 1305 } u; |
990 }; | 1306 }; |
991 | 1307 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const | 1341 inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const |
1026 { return (this+featureList).find_index (tag, index); } | 1342 { return (this+featureList).find_index (tag, index); } |
1027 | 1343 |
1028 inline unsigned int get_lookup_count (void) const | 1344 inline unsigned int get_lookup_count (void) const |
1029 { return (this+lookupList).len; } | 1345 { return (this+lookupList).len; } |
1030 inline const Lookup& get_lookup (unsigned int i) const | 1346 inline const Lookup& get_lookup (unsigned int i) const |
1031 { return (this+lookupList)[i]; } | 1347 { return (this+lookupList)[i]; } |
1032 | 1348 |
1033 inline bool sanitize (hb_sanitize_context_t *c) { | 1349 inline bool sanitize (hb_sanitize_context_t *c) { |
1034 TRACE_SANITIZE (); | 1350 TRACE_SANITIZE (); |
1035 return version.sanitize (c) && likely (version.major == 1) | 1351 return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && |
1036 » && scriptList.sanitize (c, this) | 1352 » » » scriptList.sanitize (c, this) && |
1037 » && featureList.sanitize (c, this) | 1353 » » » featureList.sanitize (c, this) && |
1038 » && lookupList.sanitize (c, this); | 1354 » » » lookupList.sanitize (c, this)); |
1039 } | 1355 } |
1040 | 1356 |
1041 protected: | 1357 protected: |
1042 FixedVersion version; /* Version of the GSUB/GPOS table--initially set | 1358 FixedVersion version; /* Version of the GSUB/GPOS table--initially set |
1043 * to 0x00010000 */ | 1359 * to 0x00010000 */ |
1044 OffsetTo<ScriptList> | 1360 OffsetTo<ScriptList> |
1045 scriptList; /* ScriptList table */ | 1361 scriptList; /* ScriptList table */ |
1046 OffsetTo<FeatureList> | 1362 OffsetTo<FeatureList> |
1047 featureList; /* FeatureList table */ | 1363 featureList; /* FeatureList table */ |
1048 OffsetTo<LookupList> | 1364 OffsetTo<LookupList> |
1049 lookupList; /* LookupList table */ | 1365 lookupList; /* LookupList table */ |
1050 public: | 1366 public: |
1051 DEFINE_SIZE_STATIC (10); | 1367 DEFINE_SIZE_STATIC (10); |
1052 }; | 1368 }; |
1053 | 1369 |
1054 | 1370 |
1055 | 1371 |
1056 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ | 1372 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ |
OLD | NEW |