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 19 matching lines...) Expand all Loading... |
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 #include "hb-set-private.hh" |
35 | 35 |
36 | 36 |
37 namespace OT { | 37 namespace OT { |
38 | 38 |
39 | 39 |
40 | |
41 #define TRACE_DISPATCH(this, format) \ | |
42 hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t
> trace \ | |
43 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | |
44 "format %d", (int) format); | |
45 | |
46 #ifndef HB_DEBUG_CLOSURE | 40 #ifndef HB_DEBUG_CLOSURE |
47 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) | 41 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) |
48 #endif | 42 #endif |
49 | 43 |
50 #define TRACE_CLOSURE(this) \ | 44 #define TRACE_CLOSURE(this) \ |
51 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ | 45 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ |
52 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 46 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
53 ""); | 47 ""); |
54 | 48 |
55 struct hb_closure_context_t | 49 struct hb_closure_context_t |
56 { | 50 { |
57 inline const char *get_name (void) { return "CLOSURE"; } | 51 inline const char *get_name (void) { return "CLOSURE"; } |
58 static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; | 52 static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; |
59 typedef hb_void_t return_t; | 53 typedef hb_void_t return_t; |
60 typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int look
up_index); | 54 typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int look
up_index); |
| 55 template <typename T, typename F> |
| 56 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
61 template <typename T> | 57 template <typename T> |
62 inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID;
} | 58 inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID;
} |
63 static return_t default_return_value (void) { return HB_VOID; } | 59 static return_t default_return_value (void) { return HB_VOID; } |
64 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } | 60 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } |
65 return_t recurse (unsigned int lookup_index) | 61 return_t recurse (unsigned int lookup_index) |
66 { | 62 { |
67 if (unlikely (nesting_level_left == 0 || !recurse_func)) | 63 if (unlikely (nesting_level_left == 0 || !recurse_func)) |
68 return default_return_value (); | 64 return default_return_value (); |
69 | 65 |
70 nesting_level_left--; | 66 nesting_level_left--; |
(...skipping 29 matching lines...) Expand all Loading... |
100 #define TRACE_WOULD_APPLY(this) \ | 96 #define TRACE_WOULD_APPLY(this) \ |
101 hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ | 97 hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ |
102 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 98 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
103 "%d glyphs", c->len); | 99 "%d glyphs", c->len); |
104 | 100 |
105 struct hb_would_apply_context_t | 101 struct hb_would_apply_context_t |
106 { | 102 { |
107 inline const char *get_name (void) { return "WOULD_APPLY"; } | 103 inline const char *get_name (void) { return "WOULD_APPLY"; } |
108 static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; | 104 static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; |
109 typedef bool return_t; | 105 typedef bool return_t; |
| 106 template <typename T, typename F> |
| 107 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
110 template <typename T> | 108 template <typename T> |
111 inline return_t dispatch (const T &obj) { return obj.would_apply (this); } | 109 inline return_t dispatch (const T &obj) { return obj.would_apply (this); } |
112 static return_t default_return_value (void) { return false; } | 110 static return_t default_return_value (void) { return false; } |
113 bool stop_sublookup_iteration (return_t r) const { return r; } | 111 bool stop_sublookup_iteration (return_t r) const { return r; } |
114 | 112 |
115 hb_face_t *face; | 113 hb_face_t *face; |
116 const hb_codepoint_t *glyphs; | 114 const hb_codepoint_t *glyphs; |
117 unsigned int len; | 115 unsigned int len; |
118 bool zero_context; | 116 bool zero_context; |
119 unsigned int debug_depth; | 117 unsigned int debug_depth; |
(...skipping 19 matching lines...) Expand all Loading... |
139 hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ | 137 hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ |
140 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 138 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
141 ""); | 139 ""); |
142 | 140 |
143 struct hb_collect_glyphs_context_t | 141 struct hb_collect_glyphs_context_t |
144 { | 142 { |
145 inline const char *get_name (void) { return "COLLECT_GLYPHS"; } | 143 inline const char *get_name (void) { return "COLLECT_GLYPHS"; } |
146 static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; | 144 static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; |
147 typedef hb_void_t return_t; | 145 typedef hb_void_t return_t; |
148 typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned i
nt lookup_index); | 146 typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned i
nt lookup_index); |
| 147 template <typename T, typename F> |
| 148 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
149 template <typename T> | 149 template <typename T> |
150 inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB
_VOID; } | 150 inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB
_VOID; } |
151 static return_t default_return_value (void) { return HB_VOID; } | 151 static return_t default_return_value (void) { return HB_VOID; } |
152 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } | 152 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } |
153 return_t recurse (unsigned int lookup_index) | 153 return_t recurse (unsigned int lookup_index) |
154 { | 154 { |
155 if (unlikely (nesting_level_left == 0 || !recurse_func)) | 155 if (unlikely (nesting_level_left == 0 || !recurse_func)) |
156 return default_return_value (); | 156 return default_return_value (); |
157 | 157 |
158 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get | 158 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 | 225 |
226 void set_recurse_func (recurse_func_t func) { recurse_func = func; } | 226 void set_recurse_func (recurse_func_t func) { recurse_func = func; } |
227 }; | 227 }; |
228 | 228 |
229 | 229 |
230 | 230 |
231 #ifndef HB_DEBUG_GET_COVERAGE | 231 #ifndef HB_DEBUG_GET_COVERAGE |
232 #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) | 232 #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) |
233 #endif | 233 #endif |
234 | 234 |
235 struct hb_get_coverage_context_t | 235 template <typename set_t> |
| 236 struct hb_add_coverage_context_t |
236 { | 237 { |
237 inline const char *get_name (void) { return "GET_COVERAGE"; } | 238 inline const char *get_name (void) { return "GET_COVERAGE"; } |
238 static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; | 239 static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; |
239 typedef const Coverage &return_t; | 240 typedef const Coverage &return_t; |
| 241 template <typename T, typename F> |
| 242 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
240 template <typename T> | 243 template <typename T> |
241 inline return_t dispatch (const T &obj) { return obj.get_coverage (); } | 244 inline return_t dispatch (const T &obj) { return obj.get_coverage (); } |
242 static return_t default_return_value (void) { return Null(Coverage); } | 245 static return_t default_return_value (void) { return Null(Coverage); } |
| 246 bool stop_sublookup_iteration (return_t r) const |
| 247 { |
| 248 r.add_coverage (set); |
| 249 return false; |
| 250 } |
243 | 251 |
244 hb_get_coverage_context_t (void) : | 252 hb_add_coverage_context_t (set_t *set_) : |
| 253 » » » set (set_), |
245 debug_depth (0) {} | 254 debug_depth (0) {} |
246 | 255 |
| 256 set_t *set; |
247 unsigned int debug_depth; | 257 unsigned int debug_depth; |
248 }; | 258 }; |
249 | 259 |
250 | 260 |
251 | 261 |
252 #ifndef HB_DEBUG_APPLY | 262 #ifndef HB_DEBUG_APPLY |
253 #define HB_DEBUG_APPLY (HB_DEBUG+0) | 263 #define HB_DEBUG_APPLY (HB_DEBUG+0) |
254 #endif | 264 #endif |
255 | 265 |
256 #define TRACE_APPLY(this) \ | 266 #define TRACE_APPLY(this) \ |
257 hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ | 267 hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ |
258 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 268 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
259 "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); | 269 "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); |
260 | 270 |
261 struct hb_apply_context_t | 271 struct hb_apply_context_t |
262 { | 272 { |
263 inline const char *get_name (void) { return "APPLY"; } | |
264 static const unsigned int max_debug_depth = HB_DEBUG_APPLY; | |
265 typedef bool return_t; | |
266 typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup
_index); | |
267 template <typename T> | |
268 inline return_t dispatch (const T &obj) { return obj.apply (this); } | |
269 static return_t default_return_value (void) { return false; } | |
270 bool stop_sublookup_iteration (return_t r) const { return r; } | |
271 return_t recurse (unsigned int lookup_index) | |
272 { | |
273 if (unlikely (nesting_level_left == 0 || !recurse_func)) | |
274 return default_return_value (); | |
275 | |
276 nesting_level_left--; | |
277 bool ret = recurse_func (this, lookup_index); | |
278 nesting_level_left++; | |
279 return ret; | |
280 } | |
281 | |
282 unsigned int table_index; /* GSUB/GPOS */ | |
283 hb_font_t *font; | |
284 hb_face_t *face; | |
285 hb_buffer_t *buffer; | |
286 hb_direction_t direction; | |
287 hb_mask_t lookup_mask; | |
288 bool auto_zwj; | |
289 recurse_func_t recurse_func; | |
290 unsigned int nesting_level_left; | |
291 unsigned int lookup_props; | |
292 const GDEF &gdef; | |
293 bool has_glyph_classes; | |
294 unsigned int debug_depth; | |
295 | |
296 | |
297 hb_apply_context_t (unsigned int table_index_, | |
298 hb_font_t *font_, | |
299 hb_buffer_t *buffer_) : | |
300 table_index (table_index_), | |
301 font (font_), face (font->face), buffer (buffer_), | |
302 direction (buffer_->props.direction), | |
303 lookup_mask (1), | |
304 auto_zwj (true), | |
305 recurse_func (NULL), | |
306 nesting_level_left (MAX_NESTING_LEVEL), | |
307 lookup_props (0), | |
308 gdef (*hb_ot_layout_from_face (face)->gdef), | |
309 has_glyph_classes (gdef.has_glyph_classes ()), | |
310 debug_depth (0) {} | |
311 | |
312 inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } | |
313 inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } | |
314 inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } | |
315 inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = loo
kup_props_; } | |
316 inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } | |
317 | |
318 struct matcher_t | 273 struct matcher_t |
319 { | 274 { |
320 inline matcher_t (void) : | 275 inline matcher_t (void) : |
321 lookup_props (0), | 276 lookup_props (0), |
322 ignore_zwnj (false), | 277 ignore_zwnj (false), |
323 ignore_zwj (false), | 278 ignore_zwj (false), |
324 mask (-1), | 279 mask (-1), |
325 #define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ | 280 #define arg1(arg) (arg) /* Remove the macro to see why it's needed! */ |
326 syllable arg1(0), | 281 syllable arg1(0), |
327 #undef arg1 | 282 #undef arg1 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 protected: | 338 protected: |
384 unsigned int lookup_props; | 339 unsigned int lookup_props; |
385 bool ignore_zwnj; | 340 bool ignore_zwnj; |
386 bool ignore_zwj; | 341 bool ignore_zwj; |
387 hb_mask_t mask; | 342 hb_mask_t mask; |
388 uint8_t syllable; | 343 uint8_t syllable; |
389 match_func_t match_func; | 344 match_func_t match_func; |
390 const void *match_data; | 345 const void *match_data; |
391 }; | 346 }; |
392 | 347 |
393 struct skipping_forward_iterator_t | 348 struct skipping_iterator_t |
394 { | 349 { |
395 inline skipping_forward_iterator_t (hb_apply_context_t *c_, | 350 inline void init (hb_apply_context_t *c_, bool context_match = false) |
396 » » » » » unsigned int start_index_, | |
397 » » » » » unsigned int num_items_, | |
398 » » » » » bool context_match = false) : | |
399 » » » » » idx (start_index_), | |
400 » » » » » c (c_), | |
401 » » » » » match_glyph_data (NULL), | |
402 » » » » » num_items (num_items_), | |
403 » » » » » end (c->buffer->len) | |
404 { | 351 { |
| 352 c = c_; |
| 353 match_glyph_data = NULL, |
| 354 matcher.set_match_func (NULL, NULL); |
405 matcher.set_lookup_props (c->lookup_props); | 355 matcher.set_lookup_props (c->lookup_props); |
406 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ | 356 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ |
407 matcher.set_ignore_zwnj (context_match || c->table_index == 1); | 357 matcher.set_ignore_zwnj (context_match || c->table_index == 1); |
408 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask
ed to. */ | 358 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask
ed to. */ |
409 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw
j); | 359 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw
j); |
410 if (!context_match) | 360 matcher.set_mask (context_match ? -1 : c->lookup_mask); |
411 » matcher.set_mask (c->lookup_mask); | |
412 matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().sy
llable () : 0); | |
413 } | 361 } |
414 inline void set_lookup_props (unsigned int lookup_props) { matcher.set_looku
p_props (lookup_props); } | 362 inline void set_lookup_props (unsigned int lookup_props) |
415 inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syl
lable); } | 363 { |
| 364 matcher.set_lookup_props (lookup_props); |
| 365 } |
416 inline void set_match_func (matcher_t::match_func_t match_func, | 366 inline void set_match_func (matcher_t::match_func_t match_func, |
417 const void *match_data, | 367 const void *match_data, |
418 const USHORT glyph_data[]) | 368 const USHORT glyph_data[]) |
419 { | 369 { |
420 matcher.set_match_func (match_func, match_data); | 370 matcher.set_match_func (match_func, match_data); |
421 match_glyph_data = glyph_data; | 371 match_glyph_data = glyph_data; |
422 } | 372 } |
423 | 373 |
424 inline bool has_no_chance (void) const { return unlikely (num_items && idx +
num_items >= end); } | 374 inline void reset (unsigned int start_index_, |
| 375 » » unsigned int num_items_) |
| 376 { |
| 377 idx = start_index_; |
| 378 num_items = num_items_; |
| 379 end = c->buffer->len; |
| 380 matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().sy
llable () : 0); |
| 381 } |
| 382 |
425 inline void reject (void) { num_items++; match_glyph_data--; } | 383 inline void reject (void) { num_items++; match_glyph_data--; } |
| 384 |
426 inline bool next (void) | 385 inline bool next (void) |
427 { | 386 { |
428 assert (num_items > 0); | 387 assert (num_items > 0); |
429 while (!has_no_chance ()) | 388 while (idx + num_items < end) |
430 { | 389 { |
431 idx++; | 390 idx++; |
432 const hb_glyph_info_t &info = c->buffer->info[idx]; | 391 const hb_glyph_info_t &info = c->buffer->info[idx]; |
433 | 392 |
434 matcher_t::may_skip_t skip = matcher.may_skip (c, info); | 393 matcher_t::may_skip_t skip = matcher.may_skip (c, info); |
435 if (unlikely (skip == matcher_t::SKIP_YES)) | 394 if (unlikely (skip == matcher_t::SKIP_YES)) |
436 continue; | 395 continue; |
437 | 396 |
438 matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data
); | 397 matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data
); |
439 if (match == matcher_t::MATCH_YES || | 398 if (match == matcher_t::MATCH_YES || |
440 (match == matcher_t::MATCH_MAYBE && | 399 (match == matcher_t::MATCH_MAYBE && |
441 skip == matcher_t::SKIP_NO)) | 400 skip == matcher_t::SKIP_NO)) |
442 { | 401 { |
443 num_items--; | 402 num_items--; |
444 match_glyph_data++; | 403 match_glyph_data++; |
445 return true; | 404 return true; |
446 } | 405 } |
447 | 406 |
448 if (skip == matcher_t::SKIP_NO) | 407 if (skip == matcher_t::SKIP_NO) |
449 return false; | 408 return false; |
450 } | 409 } |
451 return false; | 410 return false; |
452 } | 411 } |
453 | |
454 unsigned int idx; | |
455 protected: | |
456 hb_apply_context_t *c; | |
457 matcher_t matcher; | |
458 const USHORT *match_glyph_data; | |
459 | |
460 unsigned int num_items; | |
461 unsigned int end; | |
462 }; | |
463 | |
464 struct skipping_backward_iterator_t | |
465 { | |
466 inline skipping_backward_iterator_t (hb_apply_context_t *c_, | |
467 unsigned int start_index_, | |
468 unsigned int num_items_, | |
469 bool context_match = false) : | |
470 idx (start_index_), | |
471 c (c_), | |
472 match_glyph_data (NULL), | |
473 num_items (num_items_) | |
474 { | |
475 matcher.set_lookup_props (c->lookup_props); | |
476 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ | |
477 matcher.set_ignore_zwnj (context_match || c->table_index == 1); | |
478 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask
ed to. */ | |
479 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw
j); | |
480 if (!context_match) | |
481 matcher.set_mask (c->lookup_mask); | |
482 matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().sy
llable () : 0); | |
483 } | |
484 inline void set_lookup_props (unsigned int lookup_props) { matcher.set_looku
p_props (lookup_props); } | |
485 inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syl
lable); } | |
486 inline void set_match_func (matcher_t::match_func_t match_func, | |
487 const void *match_data, | |
488 const USHORT glyph_data[]) | |
489 { | |
490 matcher.set_match_func (match_func, match_data); | |
491 match_glyph_data = glyph_data; | |
492 } | |
493 | |
494 inline bool has_no_chance (void) const { return unlikely (idx < num_items);
} | |
495 inline void reject (void) { num_items++; } | |
496 inline bool prev (void) | 412 inline bool prev (void) |
497 { | 413 { |
498 assert (num_items > 0); | 414 assert (num_items > 0); |
499 while (!has_no_chance ()) | 415 while (idx >= num_items) |
500 { | 416 { |
501 idx--; | 417 idx--; |
502 const hb_glyph_info_t &info = c->buffer->out_info[idx]; | 418 const hb_glyph_info_t &info = c->buffer->out_info[idx]; |
503 | 419 |
504 matcher_t::may_skip_t skip = matcher.may_skip (c, info); | 420 matcher_t::may_skip_t skip = matcher.may_skip (c, info); |
505 if (unlikely (skip == matcher_t::SKIP_YES)) | 421 if (unlikely (skip == matcher_t::SKIP_YES)) |
506 continue; | 422 continue; |
507 | 423 |
508 matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data
); | 424 matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data
); |
509 if (match == matcher_t::MATCH_YES || | 425 if (match == matcher_t::MATCH_YES || |
(...skipping 11 matching lines...) Expand all Loading... |
521 return false; | 437 return false; |
522 } | 438 } |
523 | 439 |
524 unsigned int idx; | 440 unsigned int idx; |
525 protected: | 441 protected: |
526 hb_apply_context_t *c; | 442 hb_apply_context_t *c; |
527 matcher_t matcher; | 443 matcher_t matcher; |
528 const USHORT *match_glyph_data; | 444 const USHORT *match_glyph_data; |
529 | 445 |
530 unsigned int num_items; | 446 unsigned int num_items; |
| 447 unsigned int end; |
531 }; | 448 }; |
532 | 449 |
| 450 |
| 451 inline const char *get_name (void) { return "APPLY"; } |
| 452 static const unsigned int max_debug_depth = HB_DEBUG_APPLY; |
| 453 typedef bool return_t; |
| 454 typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup
_index); |
| 455 template <typename T, typename F> |
| 456 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
| 457 template <typename T> |
| 458 inline return_t dispatch (const T &obj) { return obj.apply (this); } |
| 459 static return_t default_return_value (void) { return false; } |
| 460 bool stop_sublookup_iteration (return_t r) const { return r; } |
| 461 return_t recurse (unsigned int lookup_index) |
| 462 { |
| 463 if (unlikely (nesting_level_left == 0 || !recurse_func)) |
| 464 return default_return_value (); |
| 465 |
| 466 nesting_level_left--; |
| 467 bool ret = recurse_func (this, lookup_index); |
| 468 nesting_level_left++; |
| 469 return ret; |
| 470 } |
| 471 |
| 472 unsigned int table_index; /* GSUB/GPOS */ |
| 473 hb_font_t *font; |
| 474 hb_face_t *face; |
| 475 hb_buffer_t *buffer; |
| 476 hb_direction_t direction; |
| 477 hb_mask_t lookup_mask; |
| 478 bool auto_zwj; |
| 479 recurse_func_t recurse_func; |
| 480 unsigned int nesting_level_left; |
| 481 unsigned int lookup_props; |
| 482 const GDEF &gdef; |
| 483 bool has_glyph_classes; |
| 484 skipping_iterator_t iter_input, iter_context; |
| 485 unsigned int debug_depth; |
| 486 |
| 487 |
| 488 hb_apply_context_t (unsigned int table_index_, |
| 489 hb_font_t *font_, |
| 490 hb_buffer_t *buffer_) : |
| 491 table_index (table_index_), |
| 492 font (font_), face (font->face), buffer (buffer_), |
| 493 direction (buffer_->props.direction), |
| 494 lookup_mask (1), |
| 495 auto_zwj (true), |
| 496 recurse_func (NULL), |
| 497 nesting_level_left (MAX_NESTING_LEVEL), |
| 498 lookup_props (0), |
| 499 gdef (*hb_ot_layout_from_face (face)->gdef), |
| 500 has_glyph_classes (gdef.has_glyph_classes ()), |
| 501 iter_input (), |
| 502 iter_context (), |
| 503 debug_depth (0) {} |
| 504 |
| 505 inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } |
| 506 inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } |
| 507 inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } |
| 508 inline void set_lookup (const Lookup &l) { set_lookup_props (l.get_props ());
} |
| 509 inline void set_lookup_props (unsigned int lookup_props_) |
| 510 { |
| 511 lookup_props = lookup_props_; |
| 512 iter_input.init (this, false); |
| 513 iter_context.init (this, true); |
| 514 } |
| 515 |
533 inline bool | 516 inline bool |
534 match_properties_mark (hb_codepoint_t glyph, | 517 match_properties_mark (hb_codepoint_t glyph, |
535 unsigned int glyph_props, | 518 unsigned int glyph_props, |
536 unsigned int lookup_props) const | 519 unsigned int lookup_props) const |
537 { | 520 { |
538 /* If using mark filtering sets, the high short of | 521 /* If using mark filtering sets, the high short of |
539 * lookup_props has the set index. | 522 * lookup_props has the set index. |
540 */ | 523 */ |
541 if (lookup_props & LookupFlag::UseMarkFilteringSet) | 524 if (lookup_props & LookupFlag::UseMarkFilteringSet) |
542 return gdef.mark_set_covers (lookup_props >> 16, glyph); | 525 return gdef.mark_set_covers (lookup_props >> 16, glyph); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 unsigned int match_positions[MAX_CONTEXT_LENGTH]
, | 717 unsigned int match_positions[MAX_CONTEXT_LENGTH]
, |
735 bool *p_is_mark_ligature = NULL, | 718 bool *p_is_mark_ligature = NULL, |
736 unsigned int *p_total_component_count = NULL) | 719 unsigned int *p_total_component_count = NULL) |
737 { | 720 { |
738 TRACE_APPLY (NULL); | 721 TRACE_APPLY (NULL); |
739 | 722 |
740 if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); | 723 if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); |
741 | 724 |
742 hb_buffer_t *buffer = c->buffer; | 725 hb_buffer_t *buffer = c->buffer; |
743 | 726 |
744 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, c
ount - 1); | 727 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; |
| 728 skippy_iter.reset (buffer->idx, count - 1); |
745 skippy_iter.set_match_func (match_func, match_data, input); | 729 skippy_iter.set_match_func (match_func, match_data, input); |
746 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
747 | 730 |
748 /* | 731 /* |
749 * This is perhaps the trickiest part of OpenType... Remarks: | 732 * This is perhaps the trickiest part of OpenType... Remarks: |
750 * | 733 * |
751 * - If all components of the ligature were marks, we call this a mark ligatur
e. | 734 * - If all components of the ligature were marks, we call this a mark ligatur
e. |
752 * | 735 * |
753 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori
ze | 736 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori
ze |
754 * it as a ligature glyph. | 737 * it as a ligature glyph. |
755 * | 738 * |
756 * - Ligatures cannot be formed across glyphs attached to different components | 739 * - Ligatures cannot be formed across glyphs attached to different components |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 } | 886 } |
904 | 887 |
905 static inline bool match_backtrack (hb_apply_context_t *c, | 888 static inline bool match_backtrack (hb_apply_context_t *c, |
906 unsigned int count, | 889 unsigned int count, |
907 const USHORT backtrack[], | 890 const USHORT backtrack[], |
908 match_func_t match_func, | 891 match_func_t match_func, |
909 const void *match_data) | 892 const void *match_data) |
910 { | 893 { |
911 TRACE_APPLY (NULL); | 894 TRACE_APPLY (NULL); |
912 | 895 |
913 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->ba
cktrack_len (), count, true); | 896 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
| 897 skippy_iter.reset (c->buffer->backtrack_len (), count); |
914 skippy_iter.set_match_func (match_func, match_data, backtrack); | 898 skippy_iter.set_match_func (match_func, match_data, backtrack); |
915 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
916 | 899 |
917 for (unsigned int i = 0; i < count; i++) | 900 for (unsigned int i = 0; i < count; i++) |
918 if (!skippy_iter.prev ()) | 901 if (!skippy_iter.prev ()) |
919 return TRACE_RETURN (false); | 902 return TRACE_RETURN (false); |
920 | 903 |
921 return TRACE_RETURN (true); | 904 return TRACE_RETURN (true); |
922 } | 905 } |
923 | 906 |
924 static inline bool match_lookahead (hb_apply_context_t *c, | 907 static inline bool match_lookahead (hb_apply_context_t *c, |
925 unsigned int count, | 908 unsigned int count, |
926 const USHORT lookahead[], | 909 const USHORT lookahead[], |
927 match_func_t match_func, | 910 match_func_t match_func, |
928 const void *match_data, | 911 const void *match_data, |
929 unsigned int offset) | 912 unsigned int offset) |
930 { | 913 { |
931 TRACE_APPLY (NULL); | 914 TRACE_APPLY (NULL); |
932 | 915 |
933 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx
+ offset - 1, count, true); | 916 hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; |
| 917 skippy_iter.reset (c->buffer->idx + offset - 1, count); |
934 skippy_iter.set_match_func (match_func, match_data, lookahead); | 918 skippy_iter.set_match_func (match_func, match_data, lookahead); |
935 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); | |
936 | 919 |
937 for (unsigned int i = 0; i < count; i++) | 920 for (unsigned int i = 0; i < count; i++) |
938 if (!skippy_iter.next ()) | 921 if (!skippy_iter.next ()) |
939 return TRACE_RETURN (false); | 922 return TRACE_RETURN (false); |
940 | 923 |
941 return TRACE_RETURN (true); | 924 return TRACE_RETURN (true); |
942 } | 925 } |
943 | 926 |
944 | 927 |
945 | 928 |
946 struct LookupRecord | 929 struct LookupRecord |
947 { | 930 { |
948 inline bool sanitize (hb_sanitize_context_t *c) { | 931 inline bool sanitize (hb_sanitize_context_t *c) const |
| 932 { |
949 TRACE_SANITIZE (this); | 933 TRACE_SANITIZE (this); |
950 return TRACE_RETURN (c->check_struct (this)); | 934 return TRACE_RETURN (c->check_struct (this)); |
951 } | 935 } |
952 | 936 |
953 USHORT sequenceIndex; /* Index into current glyph | 937 USHORT sequenceIndex; /* Index into current glyph |
954 * sequence--first glyph = 0 */ | 938 * sequence--first glyph = 0 */ |
955 USHORT lookupListIndex; /* Lookup to apply to that | 939 USHORT lookupListIndex; /* Lookup to apply to that |
956 * position--zero--based */ | 940 * position--zero--based */ |
957 public: | 941 public: |
958 DEFINE_SIZE_STATIC (4); | 942 DEFINE_SIZE_STATIC (4); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 } | 1145 } |
1162 | 1146 |
1163 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const | 1147 inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_co
ntext) const |
1164 { | 1148 { |
1165 TRACE_APPLY (this); | 1149 TRACE_APPLY (this); |
1166 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, in
putZ[0].static_size * (inputCount ? inputCount - 1 : 0)); | 1150 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, in
putZ[0].static_size * (inputCount ? inputCount - 1 : 0)); |
1167 return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCoun
t, lookupRecord, lookup_context)); | 1151 return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCoun
t, lookupRecord, lookup_context)); |
1168 } | 1152 } |
1169 | 1153 |
1170 public: | 1154 public: |
1171 inline bool sanitize (hb_sanitize_context_t *c) { | 1155 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1156 { |
1172 TRACE_SANITIZE (this); | 1157 TRACE_SANITIZE (this); |
1173 return inputCount.sanitize (c) | 1158 return inputCount.sanitize (c) |
1174 && lookupCount.sanitize (c) | 1159 && lookupCount.sanitize (c) |
1175 && c->check_range (inputZ, | 1160 && c->check_range (inputZ, |
1176 inputZ[0].static_size * inputCount | 1161 inputZ[0].static_size * inputCount |
1177 + lookupRecordX[0].static_size * lookupCount); | 1162 + lookupRecordX[0].static_size * lookupCount); |
1178 } | 1163 } |
1179 | 1164 |
1180 protected: | 1165 protected: |
1181 USHORT inputCount; /* Total number of glyphs in input | 1166 USHORT inputCount; /* Total number of glyphs in input |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1225 TRACE_APPLY (this); | 1210 TRACE_APPLY (this); |
1226 unsigned int num_rules = rule.len; | 1211 unsigned int num_rules = rule.len; |
1227 for (unsigned int i = 0; i < num_rules; i++) | 1212 for (unsigned int i = 0; i < num_rules; i++) |
1228 { | 1213 { |
1229 if ((this+rule[i]).apply (c, lookup_context)) | 1214 if ((this+rule[i]).apply (c, lookup_context)) |
1230 return TRACE_RETURN (true); | 1215 return TRACE_RETURN (true); |
1231 } | 1216 } |
1232 return TRACE_RETURN (false); | 1217 return TRACE_RETURN (false); |
1233 } | 1218 } |
1234 | 1219 |
1235 inline bool sanitize (hb_sanitize_context_t *c) { | 1220 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1221 { |
1236 TRACE_SANITIZE (this); | 1222 TRACE_SANITIZE (this); |
1237 return TRACE_RETURN (rule.sanitize (c, this)); | 1223 return TRACE_RETURN (rule.sanitize (c, this)); |
1238 } | 1224 } |
1239 | 1225 |
1240 protected: | 1226 protected: |
1241 OffsetArrayOf<Rule> | 1227 OffsetArrayOf<Rule> |
1242 rule; /* Array of Rule tables | 1228 rule; /* Array of Rule tables |
1243 * ordered by preference */ | 1229 * ordered by preference */ |
1244 public: | 1230 public: |
1245 DEFINE_SIZE_ARRAY (2, rule); | 1231 DEFINE_SIZE_ARRAY (2, rule); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 return TRACE_RETURN (false); | 1293 return TRACE_RETURN (false); |
1308 | 1294 |
1309 const RuleSet &rule_set = this+ruleSet[index]; | 1295 const RuleSet &rule_set = this+ruleSet[index]; |
1310 struct ContextApplyLookupContext lookup_context = { | 1296 struct ContextApplyLookupContext lookup_context = { |
1311 {match_glyph}, | 1297 {match_glyph}, |
1312 NULL | 1298 NULL |
1313 }; | 1299 }; |
1314 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1300 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1315 } | 1301 } |
1316 | 1302 |
1317 inline bool sanitize (hb_sanitize_context_t *c) { | 1303 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1304 { |
1318 TRACE_SANITIZE (this); | 1305 TRACE_SANITIZE (this); |
1319 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); | 1306 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
1320 } | 1307 } |
1321 | 1308 |
1322 protected: | 1309 protected: |
1323 USHORT format; /* Format identifier--format = 1 */ | 1310 USHORT format; /* Format identifier--format = 1 */ |
1324 OffsetTo<Coverage> | 1311 OffsetTo<Coverage> |
1325 coverage; /* Offset to Coverage table--from | 1312 coverage; /* Offset to Coverage table--from |
1326 * beginning of table */ | 1313 * beginning of table */ |
1327 OffsetArrayOf<RuleSet> | 1314 OffsetArrayOf<RuleSet> |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 const ClassDef &class_def = this+classDef; | 1386 const ClassDef &class_def = this+classDef; |
1400 index = class_def.get_class (c->buffer->cur().codepoint); | 1387 index = class_def.get_class (c->buffer->cur().codepoint); |
1401 const RuleSet &rule_set = this+ruleSet[index]; | 1388 const RuleSet &rule_set = this+ruleSet[index]; |
1402 struct ContextApplyLookupContext lookup_context = { | 1389 struct ContextApplyLookupContext lookup_context = { |
1403 {match_class}, | 1390 {match_class}, |
1404 &class_def | 1391 &class_def |
1405 }; | 1392 }; |
1406 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1393 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1407 } | 1394 } |
1408 | 1395 |
1409 inline bool sanitize (hb_sanitize_context_t *c) { | 1396 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1397 { |
1410 TRACE_SANITIZE (this); | 1398 TRACE_SANITIZE (this); |
1411 return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, th
is) && ruleSet.sanitize (c, this)); | 1399 return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, th
is) && ruleSet.sanitize (c, this)); |
1412 } | 1400 } |
1413 | 1401 |
1414 protected: | 1402 protected: |
1415 USHORT format; /* Format identifier--format = 2 */ | 1403 USHORT format; /* Format identifier--format = 2 */ |
1416 OffsetTo<Coverage> | 1404 OffsetTo<Coverage> |
1417 coverage; /* Offset to Coverage table--from | 1405 coverage; /* Offset to Coverage table--from |
1418 * beginning of table */ | 1406 * beginning of table */ |
1419 OffsetTo<ClassDef> | 1407 OffsetTo<ClassDef> |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1487 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1475 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
1488 | 1476 |
1489 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ,
coverageZ[0].static_size * glyphCount); | 1477 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ,
coverageZ[0].static_size * glyphCount); |
1490 struct ContextApplyLookupContext lookup_context = { | 1478 struct ContextApplyLookupContext lookup_context = { |
1491 {match_coverage}, | 1479 {match_coverage}, |
1492 this | 1480 this |
1493 }; | 1481 }; |
1494 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (
coverageZ + 1), lookupCount, lookupRecord, lookup_context)); | 1482 return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (
coverageZ + 1), lookupCount, lookupRecord, lookup_context)); |
1495 } | 1483 } |
1496 | 1484 |
1497 inline bool sanitize (hb_sanitize_context_t *c) { | 1485 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1486 { |
1498 TRACE_SANITIZE (this); | 1487 TRACE_SANITIZE (this); |
1499 if (!c->check_struct (this)) return TRACE_RETURN (false); | 1488 if (!c->check_struct (this)) return TRACE_RETURN (false); |
1500 unsigned int count = glyphCount; | 1489 unsigned int count = glyphCount; |
1501 if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] f
reely. */ | 1490 if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] f
reely. */ |
1502 if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRA
CE_RETURN (false); | 1491 if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRA
CE_RETURN (false); |
1503 for (unsigned int i = 0; i < count; i++) | 1492 for (unsigned int i = 0; i < count; i++) |
1504 if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); | 1493 if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); |
1505 LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, cover
ageZ[0].static_size * count); | 1494 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ,
coverageZ[0].static_size * count); |
1506 return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_si
ze, lookupCount)); | 1495 return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_si
ze, lookupCount)); |
1507 } | 1496 } |
1508 | 1497 |
1509 protected: | 1498 protected: |
1510 USHORT format; /* Format identifier--format = 3 */ | 1499 USHORT format; /* Format identifier--format = 3 */ |
1511 USHORT glyphCount; /* Number of glyphs in the input glyph | 1500 USHORT glyphCount; /* Number of glyphs in the input glyph |
1512 * sequence */ | 1501 * sequence */ |
1513 USHORT lookupCount; /* Number of LookupRecords */ | 1502 USHORT lookupCount; /* Number of LookupRecords */ |
1514 OffsetTo<Coverage> | 1503 OffsetTo<Coverage> |
1515 coverageZ[VAR]; /* Array of offsets to Coverage | 1504 coverageZ[VAR]; /* Array of offsets to Coverage |
1516 * table in glyph sequence order */ | 1505 * table in glyph sequence order */ |
1517 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in | 1506 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in |
1518 * design order */ | 1507 * design order */ |
1519 public: | 1508 public: |
1520 DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); | 1509 DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); |
1521 }; | 1510 }; |
1522 | 1511 |
1523 struct Context | 1512 struct Context |
1524 { | 1513 { |
1525 template <typename context_t> | 1514 template <typename context_t> |
1526 inline typename context_t::return_t dispatch (context_t *c) const | 1515 inline typename context_t::return_t dispatch (context_t *c) const |
1527 { | 1516 { |
1528 TRACE_DISPATCH (this, u.format); | 1517 TRACE_DISPATCH (this, u.format); |
| 1518 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
1529 switch (u.format) { | 1519 switch (u.format) { |
1530 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 1520 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
1531 case 2: return TRACE_RETURN (c->dispatch (u.format2)); | 1521 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
1532 case 3: return TRACE_RETURN (c->dispatch (u.format3)); | 1522 case 3: return TRACE_RETURN (c->dispatch (u.format3)); |
1533 default:return TRACE_RETURN (c->default_return_value ()); | 1523 default:return TRACE_RETURN (c->default_return_value ()); |
1534 } | 1524 } |
1535 } | 1525 } |
1536 | 1526 |
1537 inline bool sanitize (hb_sanitize_context_t *c) { | |
1538 TRACE_SANITIZE (this); | |
1539 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
1540 switch (u.format) { | |
1541 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
1542 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | |
1543 case 3: return TRACE_RETURN (u.format3.sanitize (c)); | |
1544 default:return TRACE_RETURN (true); | |
1545 } | |
1546 } | |
1547 | |
1548 protected: | 1527 protected: |
1549 union { | 1528 union { |
1550 USHORT format; /* Format identifier */ | 1529 USHORT format; /* Format identifier */ |
1551 ContextFormat1 format1; | 1530 ContextFormat1 format1; |
1552 ContextFormat2 format2; | 1531 ContextFormat2 format2; |
1553 ContextFormat3 format3; | 1532 ContextFormat3 format3; |
1554 } u; | 1533 } u; |
1555 }; | 1534 }; |
1556 | 1535 |
1557 | 1536 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); | 1698 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
1720 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 1699 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1721 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); | 1700 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
1722 return TRACE_RETURN (chain_context_apply_lookup (c, | 1701 return TRACE_RETURN (chain_context_apply_lookup (c, |
1723 backtrack.len, backtrack.ar
ray, | 1702 backtrack.len, backtrack.ar
ray, |
1724 input.len, input.array, | 1703 input.len, input.array, |
1725 lookahead.len, lookahead.ar
ray, lookup.len, | 1704 lookahead.len, lookahead.ar
ray, lookup.len, |
1726 lookup.array, lookup_contex
t)); | 1705 lookup.array, lookup_contex
t)); |
1727 } | 1706 } |
1728 | 1707 |
1729 inline bool sanitize (hb_sanitize_context_t *c) { | 1708 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1709 { |
1730 TRACE_SANITIZE (this); | 1710 TRACE_SANITIZE (this); |
1731 if (!backtrack.sanitize (c)) return TRACE_RETURN (false); | 1711 if (!backtrack.sanitize (c)) return TRACE_RETURN (false); |
1732 HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (back
track); | 1712 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> >
(backtrack); |
1733 if (!input.sanitize (c)) return TRACE_RETURN (false); | 1713 if (!input.sanitize (c)) return TRACE_RETURN (false); |
1734 ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); | 1714 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); |
1735 if (!lookahead.sanitize (c)) return TRACE_RETURN (false); | 1715 if (!lookahead.sanitize (c)) return TRACE_RETURN (false); |
1736 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 1716 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
1737 return TRACE_RETURN (lookup.sanitize (c)); | 1717 return TRACE_RETURN (lookup.sanitize (c)); |
1738 } | 1718 } |
1739 | 1719 |
1740 protected: | 1720 protected: |
1741 ArrayOf<USHORT> | 1721 ArrayOf<USHORT> |
1742 backtrack; /* Array of backtracking values | 1722 backtrack; /* Array of backtracking values |
1743 * (to be matched before the input | 1723 * (to be matched before the input |
1744 * sequence) */ | 1724 * sequence) */ |
1745 HeadlessArrayOf<USHORT> | 1725 HeadlessArrayOf<USHORT> |
1746 inputX; /* Array of input values (start with | 1726 inputX; /* Array of input values (start with |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 { | 1768 { |
1789 TRACE_APPLY (this); | 1769 TRACE_APPLY (this); |
1790 unsigned int num_rules = rule.len; | 1770 unsigned int num_rules = rule.len; |
1791 for (unsigned int i = 0; i < num_rules; i++) | 1771 for (unsigned int i = 0; i < num_rules; i++) |
1792 if ((this+rule[i]).apply (c, lookup_context)) | 1772 if ((this+rule[i]).apply (c, lookup_context)) |
1793 return TRACE_RETURN (true); | 1773 return TRACE_RETURN (true); |
1794 | 1774 |
1795 return TRACE_RETURN (false); | 1775 return TRACE_RETURN (false); |
1796 } | 1776 } |
1797 | 1777 |
1798 inline bool sanitize (hb_sanitize_context_t *c) { | 1778 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1779 { |
1799 TRACE_SANITIZE (this); | 1780 TRACE_SANITIZE (this); |
1800 return TRACE_RETURN (rule.sanitize (c, this)); | 1781 return TRACE_RETURN (rule.sanitize (c, this)); |
1801 } | 1782 } |
1802 | 1783 |
1803 protected: | 1784 protected: |
1804 OffsetArrayOf<ChainRule> | 1785 OffsetArrayOf<ChainRule> |
1805 rule; /* Array of ChainRule tables | 1786 rule; /* Array of ChainRule tables |
1806 * ordered by preference */ | 1787 * ordered by preference */ |
1807 public: | 1788 public: |
1808 DEFINE_SIZE_ARRAY (2, rule); | 1789 DEFINE_SIZE_ARRAY (2, rule); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1867 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); | 1848 if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); |
1868 | 1849 |
1869 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1850 const ChainRuleSet &rule_set = this+ruleSet[index]; |
1870 struct ChainContextApplyLookupContext lookup_context = { | 1851 struct ChainContextApplyLookupContext lookup_context = { |
1871 {match_glyph}, | 1852 {match_glyph}, |
1872 {NULL, NULL, NULL} | 1853 {NULL, NULL, NULL} |
1873 }; | 1854 }; |
1874 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1855 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1875 } | 1856 } |
1876 | 1857 |
1877 inline bool sanitize (hb_sanitize_context_t *c) { | 1858 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1859 { |
1878 TRACE_SANITIZE (this); | 1860 TRACE_SANITIZE (this); |
1879 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); | 1861 return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, thi
s)); |
1880 } | 1862 } |
1881 | 1863 |
1882 protected: | 1864 protected: |
1883 USHORT format; /* Format identifier--format = 1 */ | 1865 USHORT format; /* Format identifier--format = 1 */ |
1884 OffsetTo<Coverage> | 1866 OffsetTo<Coverage> |
1885 coverage; /* Offset to Coverage table--from | 1867 coverage; /* Offset to Coverage table--from |
1886 * beginning of table */ | 1868 * beginning of table */ |
1887 OffsetArrayOf<ChainRuleSet> | 1869 OffsetArrayOf<ChainRuleSet> |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1977 const ChainRuleSet &rule_set = this+ruleSet[index]; | 1959 const ChainRuleSet &rule_set = this+ruleSet[index]; |
1978 struct ChainContextApplyLookupContext lookup_context = { | 1960 struct ChainContextApplyLookupContext lookup_context = { |
1979 {match_class}, | 1961 {match_class}, |
1980 {&backtrack_class_def, | 1962 {&backtrack_class_def, |
1981 &input_class_def, | 1963 &input_class_def, |
1982 &lookahead_class_def} | 1964 &lookahead_class_def} |
1983 }; | 1965 }; |
1984 return TRACE_RETURN (rule_set.apply (c, lookup_context)); | 1966 return TRACE_RETURN (rule_set.apply (c, lookup_context)); |
1985 } | 1967 } |
1986 | 1968 |
1987 inline bool sanitize (hb_sanitize_context_t *c) { | 1969 inline bool sanitize (hb_sanitize_context_t *c) const |
| 1970 { |
1988 TRACE_SANITIZE (this); | 1971 TRACE_SANITIZE (this); |
1989 return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.saniti
ze (c, this) && | 1972 return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.saniti
ze (c, this) && |
1990 inputClassDef.sanitize (c, this) && lookaheadClassDef.s
anitize (c, this) && | 1973 inputClassDef.sanitize (c, this) && lookaheadClassDef.s
anitize (c, this) && |
1991 ruleSet.sanitize (c, this)); | 1974 ruleSet.sanitize (c, this)); |
1992 } | 1975 } |
1993 | 1976 |
1994 protected: | 1977 protected: |
1995 USHORT format; /* Format identifier--format = 2 */ | 1978 USHORT format; /* Format identifier--format = 2 */ |
1996 OffsetTo<Coverage> | 1979 OffsetTo<Coverage> |
1997 coverage; /* Offset to Coverage table--from | 1980 coverage; /* Offset to Coverage table--from |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 {match_coverage}, | 2081 {match_coverage}, |
2099 {this, this, this} | 2082 {this, this, this} |
2100 }; | 2083 }; |
2101 return TRACE_RETURN (chain_context_apply_lookup (c, | 2084 return TRACE_RETURN (chain_context_apply_lookup (c, |
2102 backtrack.len, (const USHOR
T *) backtrack.array, | 2085 backtrack.len, (const USHOR
T *) backtrack.array, |
2103 input.len, (const USHORT *)
input.array + 1, | 2086 input.len, (const USHORT *)
input.array + 1, |
2104 lookahead.len, (const USHOR
T *) lookahead.array, | 2087 lookahead.len, (const USHOR
T *) lookahead.array, |
2105 lookup.len, lookup.array, l
ookup_context)); | 2088 lookup.len, lookup.array, l
ookup_context)); |
2106 } | 2089 } |
2107 | 2090 |
2108 inline bool sanitize (hb_sanitize_context_t *c) { | 2091 inline bool sanitize (hb_sanitize_context_t *c) const |
| 2092 { |
2109 TRACE_SANITIZE (this); | 2093 TRACE_SANITIZE (this); |
2110 if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); | 2094 if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); |
2111 OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (back
track); | 2095 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> >
(backtrack); |
2112 if (!input.sanitize (c, this)) return TRACE_RETURN (false); | 2096 if (!input.sanitize (c, this)) return TRACE_RETURN (false); |
2113 if (!input.len) return TRACE_RETURN (false); /* To be consistent with Contex
t. */ | 2097 if (!input.len) return TRACE_RETURN (false); /* To be consistent with Contex
t. */ |
2114 OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (
input); | 2098 const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverag
e> > (input); |
2115 if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); | 2099 if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); |
2116 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahe
ad); | 2100 const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (l
ookahead); |
2117 return TRACE_RETURN (lookup.sanitize (c)); | 2101 return TRACE_RETURN (lookup.sanitize (c)); |
2118 } | 2102 } |
2119 | 2103 |
2120 protected: | 2104 protected: |
2121 USHORT format; /* Format identifier--format = 3 */ | 2105 USHORT format; /* Format identifier--format = 3 */ |
2122 OffsetArrayOf<Coverage> | 2106 OffsetArrayOf<Coverage> |
2123 backtrack; /* Array of coverage tables | 2107 backtrack; /* Array of coverage tables |
2124 * in backtracking sequence, in glyph | 2108 * in backtracking sequence, in glyph |
2125 * sequence order */ | 2109 * sequence order */ |
2126 OffsetArrayOf<Coverage> | 2110 OffsetArrayOf<Coverage> |
(...skipping 10 matching lines...) Expand all Loading... |
2137 public: | 2121 public: |
2138 DEFINE_SIZE_MIN (10); | 2122 DEFINE_SIZE_MIN (10); |
2139 }; | 2123 }; |
2140 | 2124 |
2141 struct ChainContext | 2125 struct ChainContext |
2142 { | 2126 { |
2143 template <typename context_t> | 2127 template <typename context_t> |
2144 inline typename context_t::return_t dispatch (context_t *c) const | 2128 inline typename context_t::return_t dispatch (context_t *c) const |
2145 { | 2129 { |
2146 TRACE_DISPATCH (this, u.format); | 2130 TRACE_DISPATCH (this, u.format); |
| 2131 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
2147 switch (u.format) { | 2132 switch (u.format) { |
2148 case 1: return TRACE_RETURN (c->dispatch (u.format1)); | 2133 case 1: return TRACE_RETURN (c->dispatch (u.format1)); |
2149 case 2: return TRACE_RETURN (c->dispatch (u.format2)); | 2134 case 2: return TRACE_RETURN (c->dispatch (u.format2)); |
2150 case 3: return TRACE_RETURN (c->dispatch (u.format3)); | 2135 case 3: return TRACE_RETURN (c->dispatch (u.format3)); |
2151 default:return TRACE_RETURN (c->default_return_value ()); | 2136 default:return TRACE_RETURN (c->default_return_value ()); |
2152 } | 2137 } |
2153 } | 2138 } |
2154 | 2139 |
2155 inline bool sanitize (hb_sanitize_context_t *c) { | |
2156 TRACE_SANITIZE (this); | |
2157 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
2158 switch (u.format) { | |
2159 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | |
2160 case 2: return TRACE_RETURN (u.format2.sanitize (c)); | |
2161 case 3: return TRACE_RETURN (u.format3.sanitize (c)); | |
2162 default:return TRACE_RETURN (true); | |
2163 } | |
2164 } | |
2165 | |
2166 protected: | 2140 protected: |
2167 union { | 2141 union { |
2168 USHORT format; /* Format identifier */ | 2142 USHORT format; /* Format identifier */ |
2169 ChainContextFormat1 format1; | 2143 ChainContextFormat1 format1; |
2170 ChainContextFormat2 format2; | 2144 ChainContextFormat2 format2; |
2171 ChainContextFormat3 format3; | 2145 ChainContextFormat3 format3; |
2172 } u; | 2146 } u; |
2173 }; | 2147 }; |
2174 | 2148 |
2175 | 2149 |
| 2150 template <typename T> |
2176 struct ExtensionFormat1 | 2151 struct ExtensionFormat1 |
2177 { | 2152 { |
2178 inline unsigned int get_type (void) const { return extensionLookupType; } | 2153 inline unsigned int get_type (void) const { return extensionLookupType; } |
2179 inline unsigned int get_offset (void) const { return extensionOffset; } | |
2180 | 2154 |
2181 inline bool sanitize (hb_sanitize_context_t *c) { | 2155 template <typename X> |
| 2156 inline const X& get_subtable (void) const |
| 2157 { |
| 2158 unsigned int offset = extensionOffset; |
| 2159 if (unlikely (!offset)) return Null(typename T::LookupSubTable); |
| 2160 return StructAtOffset<typename T::LookupSubTable> (this, offset); |
| 2161 } |
| 2162 |
| 2163 template <typename context_t> |
| 2164 inline typename context_t::return_t dispatch (context_t *c) const |
| 2165 { |
| 2166 TRACE_DISPATCH (this, format); |
| 2167 if (unlikely (!c->may_dispatch (this, this))) TRACE_RETURN (c->default_retur
n_value ()); |
| 2168 return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ())
; |
| 2169 } |
| 2170 |
| 2171 /* This is called from may_dispatch() above with hb_sanitize_context_t. */ |
| 2172 inline bool sanitize (hb_sanitize_context_t *c) const |
| 2173 { |
2182 TRACE_SANITIZE (this); | 2174 TRACE_SANITIZE (this); |
2183 return TRACE_RETURN (c->check_struct (this)); | 2175 return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0); |
2184 } | 2176 } |
2185 | 2177 |
2186 protected: | 2178 protected: |
2187 USHORT format; /* Format identifier. Set to 1. */ | 2179 USHORT format; /* Format identifier. Set to 1. */ |
2188 USHORT extensionLookupType; /* Lookup type of subtable referenced | 2180 USHORT extensionLookupType; /* Lookup type of subtable referenced |
2189 * by ExtensionOffset (i.e. the | 2181 * by ExtensionOffset (i.e. the |
2190 * extension subtable). */ | 2182 * extension subtable). */ |
2191 ULONG extensionOffset; /* Offset to the extension subtable, | 2183 ULONG extensionOffset; /* Offset to the extension subtable, |
2192 * of lookup type subtable. */ | 2184 * of lookup type subtable. */ |
2193 public: | 2185 public: |
2194 DEFINE_SIZE_STATIC (8); | 2186 DEFINE_SIZE_STATIC (8); |
2195 }; | 2187 }; |
2196 | 2188 |
2197 template <typename T> | 2189 template <typename T> |
2198 struct Extension | 2190 struct Extension |
2199 { | 2191 { |
2200 inline unsigned int get_type (void) const | 2192 inline unsigned int get_type (void) const |
2201 { | 2193 { |
2202 switch (u.format) { | 2194 switch (u.format) { |
2203 case 1: return u.format1.get_type (); | 2195 case 1: return u.format1.get_type (); |
2204 default:return 0; | 2196 default:return 0; |
2205 } | 2197 } |
2206 } | 2198 } |
2207 inline unsigned int get_offset (void) const | |
2208 { | |
2209 switch (u.format) { | |
2210 case 1: return u.format1.get_offset (); | |
2211 default:return 0; | |
2212 } | |
2213 } | |
2214 | |
2215 template <typename X> | 2199 template <typename X> |
2216 inline const X& get_subtable (void) const | 2200 inline const X& get_subtable (void) const |
2217 { | 2201 { |
2218 unsigned int offset = get_offset (); | 2202 switch (u.format) { |
2219 if (unlikely (!offset)) return Null(typename T::LookupSubTable); | 2203 case 1: return u.format1.template get_subtable<typename T::LookupSubTable> (
); |
2220 return StructAtOffset<typename T::LookupSubTable> (this, offset); | 2204 default:return Null(typename T::LookupSubTable); |
| 2205 } |
2221 } | 2206 } |
2222 | 2207 |
2223 template <typename context_t> | 2208 template <typename context_t> |
2224 inline typename context_t::return_t dispatch (context_t *c) const | 2209 inline typename context_t::return_t dispatch (context_t *c) const |
2225 { | 2210 { |
2226 return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ())
; | 2211 TRACE_DISPATCH (this, u.format); |
2227 } | 2212 if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_
return_value ()); |
2228 | |
2229 inline bool sanitize_self (hb_sanitize_context_t *c) { | |
2230 TRACE_SANITIZE (this); | |
2231 if (!u.format.sanitize (c)) return TRACE_RETURN (false); | |
2232 switch (u.format) { | 2213 switch (u.format) { |
2233 case 1: return TRACE_RETURN (u.format1.sanitize (c)); | 2214 case 1: return TRACE_RETURN (u.format1.dispatch (c)); |
2234 default:return TRACE_RETURN (true); | 2215 default:return TRACE_RETURN (c->default_return_value ()); |
2235 } | 2216 } |
2236 } | 2217 } |
2237 | 2218 |
2238 inline bool sanitize (hb_sanitize_context_t *c) { | |
2239 TRACE_SANITIZE (this); | |
2240 if (!sanitize_self (c)) return TRACE_RETURN (false); | |
2241 unsigned int offset = get_offset (); | |
2242 if (unlikely (!offset)) return TRACE_RETURN (true); | |
2243 return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offse
t).sanitize (c, get_type ())); | |
2244 } | |
2245 | |
2246 protected: | 2219 protected: |
2247 union { | 2220 union { |
2248 USHORT format; /* Format identifier */ | 2221 USHORT format; /* Format identifier */ |
2249 ExtensionFormat1» format1; | 2222 ExtensionFormat1<T>» format1; |
2250 } u; | 2223 } u; |
2251 }; | 2224 }; |
2252 | 2225 |
2253 | 2226 |
2254 /* | 2227 /* |
2255 * GSUB/GPOS Common | 2228 * GSUB/GPOS Common |
2256 */ | 2229 */ |
2257 | 2230 |
2258 struct GSUBGPOS | 2231 struct GSUBGPOS |
2259 { | 2232 { |
(...skipping 24 matching lines...) Expand all Loading... |
2284 inline const Feature& get_feature (unsigned int i) const | 2257 inline const Feature& get_feature (unsigned int i) const |
2285 { return (this+featureList)[i]; } | 2258 { return (this+featureList)[i]; } |
2286 inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const | 2259 inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const |
2287 { return (this+featureList).find_index (tag, index); } | 2260 { return (this+featureList).find_index (tag, index); } |
2288 | 2261 |
2289 inline unsigned int get_lookup_count (void) const | 2262 inline unsigned int get_lookup_count (void) const |
2290 { return (this+lookupList).len; } | 2263 { return (this+lookupList).len; } |
2291 inline const Lookup& get_lookup (unsigned int i) const | 2264 inline const Lookup& get_lookup (unsigned int i) const |
2292 { return (this+lookupList)[i]; } | 2265 { return (this+lookupList)[i]; } |
2293 | 2266 |
2294 inline bool sanitize (hb_sanitize_context_t *c) { | 2267 inline bool sanitize (hb_sanitize_context_t *c) const |
| 2268 { |
2295 TRACE_SANITIZE (this); | 2269 TRACE_SANITIZE (this); |
2296 return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && | 2270 return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && |
2297 scriptList.sanitize (c, this) && | 2271 scriptList.sanitize (c, this) && |
2298 featureList.sanitize (c, this) && | 2272 featureList.sanitize (c, this) && |
2299 lookupList.sanitize (c, this)); | 2273 lookupList.sanitize (c, this)); |
2300 } | 2274 } |
2301 | 2275 |
2302 protected: | 2276 protected: |
2303 FixedVersion version; /* Version of the GSUB/GPOS table--initially set | 2277 FixedVersion version; /* Version of the GSUB/GPOS table--initially set |
2304 * to 0x00010000u */ | 2278 * to 0x00010000u */ |
2305 OffsetTo<ScriptList> | 2279 OffsetTo<ScriptList> |
2306 scriptList; /* ScriptList table */ | 2280 scriptList; /* ScriptList table */ |
2307 OffsetTo<FeatureList> | 2281 OffsetTo<FeatureList> |
2308 featureList; /* FeatureList table */ | 2282 featureList; /* FeatureList table */ |
2309 OffsetTo<LookupList> | 2283 OffsetTo<LookupList> |
2310 lookupList; /* LookupList table */ | 2284 lookupList; /* LookupList table */ |
2311 public: | 2285 public: |
2312 DEFINE_SIZE_STATIC (10); | 2286 DEFINE_SIZE_STATIC (10); |
2313 }; | 2287 }; |
2314 | 2288 |
2315 | 2289 |
2316 } /* namespace OT */ | 2290 } /* namespace OT */ |
2317 | 2291 |
2318 | 2292 |
2319 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ | 2293 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ |
OLD | NEW |