| 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 |