Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh

Issue 12438036: Update harfbuzz-ng to 0.9.14 from 0.9.10 (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 20 matching lines...) Expand all
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 40
41 #define TRACE_PROCESS(this) \ 41 #define TRACE_DISPATCH(this) \
42 hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t > trace \ 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, \ 43 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
44 ""); 44 "");
45 45
46 46
47 #ifndef HB_DEBUG_CLOSURE 47 #ifndef HB_DEBUG_CLOSURE
48 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) 48 #define HB_DEBUG_CLOSURE (HB_DEBUG+0)
49 #endif 49 #endif
50 50
51 #define TRACE_CLOSURE(this) \ 51 #define TRACE_CLOSURE(this) \
52 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ 52 hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
53 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 53 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
54 ""); 54 "");
55 55
56 struct hb_closure_context_t 56 struct hb_closure_context_t
57 { 57 {
58 inline const char *get_name (void) { return "CLOSURE"; } 58 inline const char *get_name (void) { return "CLOSURE"; }
59 static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; 59 static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
60 typedef hb_void_t return_t; 60 typedef hb_void_t return_t;
61 typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int look up_index); 61 typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int look up_index);
62 template <typename T> 62 template <typename T>
63 inline return_t process (const T &obj) { obj.closure (this); return HB_VOID; } 63 inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
64 static return_t default_return_value (void) { return HB_VOID; } 64 static return_t default_return_value (void) { return HB_VOID; }
65 bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return fals e; } 65 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
66 return_t recurse (unsigned int lookup_index) 66 return_t recurse (unsigned int lookup_index)
67 { 67 {
68 if (unlikely (nesting_level_left == 0 || !recurse_func)) 68 if (unlikely (nesting_level_left == 0 || !recurse_func))
69 return default_return_value (); 69 return default_return_value ();
70 70
71 nesting_level_left--; 71 nesting_level_left--;
72 recurse_func (this, lookup_index); 72 recurse_func (this, lookup_index);
73 nesting_level_left++; 73 nesting_level_left++;
74 return HB_VOID; 74 return HB_VOID;
75 } 75 }
(...skipping 26 matching lines...) Expand all
102 hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \ 102 hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
103 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 103 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
104 "%d glyphs", c->len); 104 "%d glyphs", c->len);
105 105
106 struct hb_would_apply_context_t 106 struct hb_would_apply_context_t
107 { 107 {
108 inline const char *get_name (void) { return "WOULD_APPLY"; } 108 inline const char *get_name (void) { return "WOULD_APPLY"; }
109 static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; 109 static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
110 typedef bool return_t; 110 typedef bool return_t;
111 template <typename T> 111 template <typename T>
112 inline return_t process (const T &obj) { return obj.would_apply (this); } 112 inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
113 static return_t default_return_value (void) { return false; } 113 static return_t default_return_value (void) { return false; }
114 bool stop_sublookup_iteration (const return_t r) const { return r; } 114 bool stop_sublookup_iteration (return_t r) const { return r; }
115 115
116 hb_face_t *face; 116 hb_face_t *face;
117 const hb_codepoint_t *glyphs; 117 const hb_codepoint_t *glyphs;
118 unsigned int len; 118 unsigned int len;
119 bool zero_context; 119 bool zero_context;
120 unsigned int debug_depth; 120 unsigned int debug_depth;
121 121
122 hb_would_apply_context_t (hb_face_t *face_, 122 hb_would_apply_context_t (hb_face_t *face_,
123 const hb_codepoint_t *glyphs_, 123 const hb_codepoint_t *glyphs_,
124 unsigned int len_, 124 unsigned int len_,
(...skipping 16 matching lines...) Expand all
141 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 141 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
142 ""); 142 "");
143 143
144 struct hb_collect_glyphs_context_t 144 struct hb_collect_glyphs_context_t
145 { 145 {
146 inline const char *get_name (void) { return "COLLECT_GLYPHS"; } 146 inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
147 static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; 147 static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
148 typedef hb_void_t return_t; 148 typedef hb_void_t return_t;
149 typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned i nt lookup_index); 149 typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned i nt lookup_index);
150 template <typename T> 150 template <typename T>
151 inline return_t process (const T &obj) { obj.collect_glyphs (this); return HB_ VOID; } 151 inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB _VOID; }
152 static return_t default_return_value (void) { return HB_VOID; } 152 static return_t default_return_value (void) { return HB_VOID; }
153 bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return fals e; } 153 bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; }
154 return_t recurse (unsigned int lookup_index) 154 return_t recurse (unsigned int lookup_index)
155 { 155 {
156 if (unlikely (nesting_level_left == 0 || !recurse_func)) 156 if (unlikely (nesting_level_left == 0 || !recurse_func))
157 return default_return_value (); 157 return default_return_value ();
158 158
159 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get 159 /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
160 * past the previous check. For GSUB, we only want to collect the output 160 * past the previous check. For GSUB, we only want to collect the output
161 * glyphs in the recursion. If output is not requested, we can go home now. */ 161 * glyphs in the recursion. If output is not requested, we can go home now. */
162 162
163 if (output == hb_set_get_empty ()) 163 if (output == hb_set_get_empty ())
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 }; 207 };
208 208
209 209
210 210
211 struct hb_get_coverage_context_t 211 struct hb_get_coverage_context_t
212 { 212 {
213 inline const char *get_name (void) { return "GET_COVERAGE"; } 213 inline const char *get_name (void) { return "GET_COVERAGE"; }
214 static const unsigned int max_debug_depth = 0; 214 static const unsigned int max_debug_depth = 0;
215 typedef const Coverage &return_t; 215 typedef const Coverage &return_t;
216 template <typename T> 216 template <typename T>
217 inline return_t process (const T &obj) { return obj.get_coverage (); } 217 inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
218 static return_t default_return_value (void) { return Null(Coverage); } 218 static return_t default_return_value (void) { return Null(Coverage); }
219 219
220 hb_get_coverage_context_t (void) : 220 hb_get_coverage_context_t (void) :
221 debug_depth (0) {} 221 debug_depth (0) {}
222 222
223 unsigned int debug_depth; 223 unsigned int debug_depth;
224 }; 224 };
225 225
226 226
227 227
228 #ifndef HB_DEBUG_APPLY 228 #ifndef HB_DEBUG_APPLY
229 #define HB_DEBUG_APPLY (HB_DEBUG+0) 229 #define HB_DEBUG_APPLY (HB_DEBUG+0)
230 #endif 230 #endif
231 231
232 #define TRACE_APPLY(this) \ 232 #define TRACE_APPLY(this) \
233 hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ 233 hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
234 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ 234 (&c->debug_depth, c->get_name (), this, HB_FUNC, \
235 "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); 235 "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
236 236
237 struct hb_apply_context_t 237 struct hb_apply_context_t
238 { 238 {
239 inline const char *get_name (void) { return "APPLY"; } 239 inline const char *get_name (void) { return "APPLY"; }
240 static const unsigned int max_debug_depth = HB_DEBUG_APPLY; 240 static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
241 typedef bool return_t; 241 typedef bool return_t;
242 typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup _index); 242 typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup _index);
243 template <typename T> 243 template <typename T>
244 inline return_t process (const T &obj) { return obj.apply (this); } 244 inline return_t dispatch (const T &obj) { return obj.apply (this); }
245 static return_t default_return_value (void) { return false; } 245 static return_t default_return_value (void) { return false; }
246 bool stop_sublookup_iteration (const return_t r) const { return r; } 246 bool stop_sublookup_iteration (return_t r) const { return r; }
247 return_t recurse (unsigned int lookup_index) 247 return_t recurse (unsigned int lookup_index)
248 { 248 {
249 if (unlikely (nesting_level_left == 0 || !recurse_func)) 249 if (unlikely (nesting_level_left == 0 || !recurse_func))
250 return default_return_value (); 250 return default_return_value ();
251 251
252 nesting_level_left--; 252 nesting_level_left--;
253 bool ret = recurse_func (this, lookup_index); 253 bool ret = recurse_func (this, lookup_index);
254 nesting_level_left++; 254 nesting_level_left++;
255 return ret; 255 return ret;
256 } 256 }
257 257
258 unsigned int table_index; /* GSUB/GPOS */
258 hb_font_t *font; 259 hb_font_t *font;
259 hb_face_t *face; 260 hb_face_t *face;
260 hb_buffer_t *buffer; 261 hb_buffer_t *buffer;
261 hb_direction_t direction; 262 hb_direction_t direction;
262 hb_mask_t lookup_mask; 263 hb_mask_t lookup_mask;
264 bool auto_zwj;
263 recurse_func_t recurse_func; 265 recurse_func_t recurse_func;
264 unsigned int nesting_level_left; 266 unsigned int nesting_level_left;
265 unsigned int lookup_props; 267 unsigned int lookup_props;
266 unsigned int property; /* propety of first glyph */
267 const GDEF &gdef; 268 const GDEF &gdef;
268 bool has_glyph_classes; 269 bool has_glyph_classes;
269 unsigned int debug_depth; 270 unsigned int debug_depth;
270 271
271 272
272 hb_apply_context_t (hb_font_t *font_, 273 hb_apply_context_t (unsigned int table_index_,
274 » » hb_font_t *font_,
273 hb_buffer_t *buffer_, 275 hb_buffer_t *buffer_,
274 » » hb_mask_t lookup_mask_) : 276 » » hb_mask_t lookup_mask_,
277 » » bool auto_zwj_) :
278 » » » table_index (table_index_),
275 font (font_), face (font->face), buffer (buffer_), 279 font (font_), face (font->face), buffer (buffer_),
276 direction (buffer_->props.direction), 280 direction (buffer_->props.direction),
277 lookup_mask (lookup_mask_), 281 lookup_mask (lookup_mask_),
282 auto_zwj (auto_zwj_),
278 recurse_func (NULL), 283 recurse_func (NULL),
279 nesting_level_left (MAX_NESTING_LEVEL), 284 nesting_level_left (MAX_NESTING_LEVEL),
280 » » » lookup_props (0), property (0), 285 » » » lookup_props (0),
281 gdef (*hb_ot_layout_from_face (face)->gdef), 286 gdef (*hb_ot_layout_from_face (face)->gdef),
282 has_glyph_classes (gdef.has_glyph_classes ()), 287 has_glyph_classes (gdef.has_glyph_classes ()),
283 debug_depth (0) {} 288 debug_depth (0) {}
284 289
285 void set_recurse_func (recurse_func_t func) { recurse_func = func; } 290 inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
286 void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_pro ps_; } 291 inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = loo kup_props_; }
287 void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } 292 inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
288 293
289 struct mark_skipping_forward_iterator_t 294 struct matcher_t
290 { 295 {
291 inline mark_skipping_forward_iterator_t (hb_apply_context_t *c_, 296 inline matcher_t (void) :
292 » » » » » unsigned int start_index_, 297 » lookup_props (0),
293 » » » » » unsigned int num_items_, 298 » ignore_zwnj (false),
294 » » » » » bool context_match = false) 299 » ignore_zwj (false),
295 { 300 » mask (-1),
296 c = c_; 301 #define arg1(arg) (arg) /* Remove the macro to see why it's needed! */
297 idx = start_index_; 302 » syllable arg1(0),
298 num_items = num_items_; 303 #undef arg1
299 mask = context_match ? -1 : c->lookup_mask; 304 » match_func (NULL),
300 syllable = context_match ? 0 : c->buffer->cur().syllable (); 305 » match_data (NULL) {};
301 end = c->buffer->len; 306
302 } 307 typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
303 inline bool has_no_chance (void) const 308
304 { 309 inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_ ; }
305 return unlikely (num_items && idx + num_items >= end); 310 inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
306 } 311 inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = l ookup_props_; }
307 inline void reject (void) 312 inline void set_mask (hb_mask_t mask_) { mask = mask_; }
308 { 313 inline void set_syllable (uint8_t syllable_) { syllable = syllable_; }
309 num_items++; 314 inline void set_match_func (match_func_t match_func_,
310 } 315 » » » » const void *match_data_)
311 inline bool next (unsigned int *property_out, 316 { match_func = match_func_; match_data = match_data_; }
312 » » unsigned int lookup_props) 317
318 enum may_match_t {
319 MATCH_NO,
320 MATCH_YES,
321 MATCH_MAYBE
322 };
323
324 inline may_match_t may_match (const hb_glyph_info_t &info,
325 » » » » const USHORT *glyph_data) const
326 {
327 if (!(info.mask & mask) ||
328 » (syllable && syllable != info.syllable ()))
329 » return MATCH_NO;
330
331 if (match_func)
332 return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
333
334 return MATCH_MAYBE;
335 }
336
337 enum may_skip_t {
338 SKIP_NO,
339 SKIP_YES,
340 SKIP_MAYBE
341 };
342
343 inline may_skip_t
344 may_skip (const hb_apply_context_t *c,
345 » const hb_glyph_info_t &info) const
346 {
347 unsigned int property;
348
349 property = info.glyph_props();
350
351 if (!c->match_properties (info.codepoint, property, lookup_props))
352 » return SKIP_YES;
353
354 if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
355 » » (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
356 » » (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
357 » » !is_a_ligature (info)))
358 » return SKIP_MAYBE;
359
360 return SKIP_NO;
361 }
362
363 protected:
364 unsigned int lookup_props;
365 bool ignore_zwnj;
366 bool ignore_zwj;
367 hb_mask_t mask;
368 uint8_t syllable;
369 match_func_t match_func;
370 const void *match_data;
371 };
372
373 struct skipping_forward_iterator_t
374 {
375 inline skipping_forward_iterator_t (hb_apply_context_t *c_,
376 » » » » » unsigned int start_index_,
377 » » » » » unsigned int num_items_,
378 » » » » » bool context_match = false) :
379 » » » » » idx (start_index_),
380 » » » » » c (c_),
381 » » » » » match_glyph_data (NULL),
382 » » » » » num_items (num_items_),
383 » » » » » end (c->buffer->len)
384 {
385 matcher.set_lookup_props (c->lookup_props);
386 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
387 matcher.set_ignore_zwnj (context_match || c->table_index == 1);
388 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask ed to. */
389 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw j);
390 if (!context_match)
391 » matcher.set_mask (c->lookup_mask);
392 matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().sy llable () : 0);
393 }
394 inline void set_lookup_props (unsigned int lookup_props) { matcher.set_looku p_props (lookup_props); }
395 inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syl lable); }
396 inline void set_match_func (matcher_t::match_func_t match_func,
397 » » » » const void *match_data,
398 » » » » const USHORT glyph_data[])
399 {
400 matcher.set_match_func (match_func, match_data);
401 match_glyph_data = glyph_data;
402 }
403
404 inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); }
405 inline void reject (void) { num_items++; match_glyph_data--; }
406 inline bool next (void)
313 { 407 {
314 assert (num_items > 0); 408 assert (num_items > 0);
315 do 409 while (!has_no_chance ())
316 { 410 {
317 » if (has_no_chance ()) 411 » idx++;
412 » const hb_glyph_info_t &info = c->buffer->info[idx];
413
414 » matcher_t::may_skip_t skip = matcher.may_skip (c, info);
415 » if (unlikely (skip == matcher_t::SKIP_YES))
416 » continue;
417
418 » matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data );
419 » if (match == matcher_t::MATCH_YES ||
420 » (match == matcher_t::MATCH_MAYBE &&
421 » skip == matcher_t::SKIP_NO))
422 » {
423 » num_items--;
424 » match_glyph_data++;
425 » return true;
426 » }
427
428 » if (skip == matcher_t::SKIP_NO)
318 return false; 429 return false;
319 » idx++; 430 }
320 } while (c->should_skip_mark (&c->buffer->info[idx], lookup_props, propert y_out)); 431 return false;
321 num_items--;
322 return (c->buffer->info[idx].mask & mask) && (!syllable || syllable == c-> buffer->info[idx].syllable ());
323 }
324 inline bool next (unsigned int *property_out = NULL)
325 {
326 return next (property_out, c->lookup_props);
327 } 432 }
328 433
329 unsigned int idx; 434 unsigned int idx;
330 protected: 435 protected:
331 hb_apply_context_t *c; 436 hb_apply_context_t *c;
437 matcher_t matcher;
438 const USHORT *match_glyph_data;
439
332 unsigned int num_items; 440 unsigned int num_items;
333 hb_mask_t mask;
334 uint8_t syllable;
335 unsigned int end; 441 unsigned int end;
336 }; 442 };
337 443
338 struct mark_skipping_backward_iterator_t 444 struct skipping_backward_iterator_t
339 { 445 {
340 inline mark_skipping_backward_iterator_t (hb_apply_context_t *c_, 446 inline skipping_backward_iterator_t (hb_apply_context_t *c_,
341 » » » » » unsigned int start_index_, 447 » » » » » unsigned int start_index_,
342 » » » » » unsigned int num_items_, 448 » » » » » unsigned int num_items_,
343 » » » » » hb_mask_t mask_ = 0, 449 » » » » » bool context_match = false) :
344 » » » » » bool match_syllable_ = true) 450 » » » » » idx (start_index_),
345 { 451 » » » » » c (c_),
346 c = c_; 452 » » » » » match_glyph_data (NULL),
347 idx = start_index_; 453 » » » » » num_items (num_items_)
348 num_items = num_items_; 454 {
349 mask = mask_ ? mask_ : c->lookup_mask; 455 matcher.set_lookup_props (c->lookup_props);
350 syllable = match_syllable_ ? c->buffer->cur().syllable () : 0; 456 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
351 } 457 matcher.set_ignore_zwnj (context_match || c->table_index == 1);
352 inline bool has_no_chance (void) const 458 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask ed to. */
353 { 459 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw j);
354 return unlikely (idx < num_items); 460 if (!context_match)
355 } 461 » matcher.set_mask (c->lookup_mask);
356 inline void reject (void) 462 matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().sy llable () : 0);
357 { 463 }
358 num_items++; 464 inline void set_lookup_props (unsigned int lookup_props) { matcher.set_looku p_props (lookup_props); }
359 } 465 inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syl lable); }
360 inline bool prev (unsigned int *property_out, 466 inline void set_match_func (matcher_t::match_func_t match_func,
361 » » unsigned int lookup_props) 467 » » » » const void *match_data,
468 » » » » const USHORT glyph_data[])
469 {
470 matcher.set_match_func (match_func, match_data);
471 match_glyph_data = glyph_data;
472 }
473
474 inline bool has_no_chance (void) const { return unlikely (idx < num_items); }
475 inline void reject (void) { num_items++; }
476 inline bool prev (void)
362 { 477 {
363 assert (num_items > 0); 478 assert (num_items > 0);
364 do 479 while (!has_no_chance ())
365 { 480 {
366 » if (has_no_chance ()) 481 » idx--;
482 » const hb_glyph_info_t &info = c->buffer->out_info[idx];
483
484 » matcher_t::may_skip_t skip = matcher.may_skip (c, info);
485
486 » if (unlikely (skip == matcher_t::SKIP_YES))
487 » continue;
488
489 » matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data );
490 » if (match == matcher_t::MATCH_YES ||
491 » (match == matcher_t::MATCH_MAYBE &&
492 » skip == matcher_t::SKIP_NO))
493 » {
494 » num_items--;
495 » match_glyph_data++;
496 » return true;
497 » }
498
499 » if (skip == matcher_t::SKIP_NO)
367 return false; 500 return false;
368 » idx--; 501 }
369 } while (c->should_skip_mark (&c->buffer->out_info[idx], lookup_props, pro perty_out)); 502 return false;
370 num_items--;
371 return (c->buffer->out_info[idx].mask & mask) && (!syllable || syllable == c->buffer->out_info[idx].syllable ());
372 }
373 inline bool prev (unsigned int *property_out = NULL)
374 {
375 return prev (property_out, c->lookup_props);
376 } 503 }
377 504
378 unsigned int idx; 505 unsigned int idx;
379 protected: 506 protected:
380 hb_apply_context_t *c; 507 hb_apply_context_t *c;
508 matcher_t matcher;
509 const USHORT *match_glyph_data;
510
381 unsigned int num_items; 511 unsigned int num_items;
382 hb_mask_t mask;
383 uint8_t syllable;
384 }; 512 };
385 513
386 inline bool 514 inline bool
387 match_properties_mark (hb_codepoint_t glyph, 515 match_properties_mark (hb_codepoint_t glyph,
388 unsigned int glyph_props, 516 unsigned int glyph_props,
389 unsigned int lookup_props) const 517 unsigned int lookup_props) const
390 { 518 {
391 /* If using mark filtering sets, the high short of 519 /* If using mark filtering sets, the high short of
392 * lookup_props has the set index. 520 * lookup_props has the set index.
393 */ 521 */
(...skipping 22 matching lines...) Expand all
416 return false; 544 return false;
417 545
418 if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) 546 if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
419 return match_properties_mark (glyph, glyph_props, lookup_props); 547 return match_properties_mark (glyph, glyph_props, lookup_props);
420 548
421 return true; 549 return true;
422 } 550 }
423 551
424 inline bool 552 inline bool
425 check_glyph_property (hb_glyph_info_t *info, 553 check_glyph_property (hb_glyph_info_t *info,
426 » » » unsigned int lookup_props, 554 » » » unsigned int lookup_props) const
427 » » » unsigned int *property_out) const
428 { 555 {
429 unsigned int property; 556 unsigned int property;
430 557
431 property = info->glyph_props(); 558 property = info->glyph_props();
432 *property_out = property;
433 559
434 return match_properties (info->codepoint, property, lookup_props); 560 return match_properties (info->codepoint, property, lookup_props);
435 } 561 }
436 562
437 inline bool
438 should_skip_mark (hb_glyph_info_t *info,
439 unsigned int lookup_props,
440 unsigned int *property_out) const
441 {
442 unsigned int property;
443
444 property = info->glyph_props();
445 if (property_out)
446 *property_out = property;
447
448 /* If it's a mark, skip it if we don't accept it. */
449 if (unlikely (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
450 return !match_properties (info->codepoint, property, lookup_props);
451
452 /* If not a mark, don't skip. */
453 return false;
454 }
455
456
457 inline bool should_mark_skip_current_glyph (void) const
458 {
459 return should_skip_mark (&buffer->cur(), lookup_props, NULL);
460 }
461
462 inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) c onst 563 inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) c onst
463 { 564 {
464 if (likely (has_glyph_classes)) 565 if (likely (has_glyph_classes))
465 buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index); 566 buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
466 else if (class_guess) 567 else if (class_guess)
467 buffer->cur().glyph_props() = class_guess; 568 buffer->cur().glyph_props() = class_guess;
468 } 569 }
469 570
470 inline void output_glyph (hb_codepoint_t glyph_index, 571 inline void output_glyph (hb_codepoint_t glyph_index,
471 unsigned int class_guess = 0) const 572 unsigned int class_guess = 0) const
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 unsigned int count, /* Including the first glyph (not matched) */ 696 unsigned int count, /* Including the first glyph (not matched) */
596 const USHORT input[], /* Array of input values-- start with second glyph */ 697 const USHORT input[], /* Array of input values-- start with second glyph */
597 match_func_t match_func, 698 match_func_t match_func,
598 const void *match_data, 699 const void *match_data,
599 unsigned int *end_offset = NULL, 700 unsigned int *end_offset = NULL,
600 bool *p_is_mark_ligature = NULL, 701 bool *p_is_mark_ligature = NULL,
601 unsigned int *p_total_component_count = NULL) 702 unsigned int *p_total_component_count = NULL)
602 { 703 {
603 TRACE_APPLY (NULL); 704 TRACE_APPLY (NULL);
604 705
605 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer ->idx, count - 1); 706 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1);
707 skippy_iter.set_match_func (match_func, match_data, input);
606 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); 708 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
607 709
608 /* 710 /*
609 * This is perhaps the trickiest part of OpenType... Remarks: 711 * This is perhaps the trickiest part of OpenType... Remarks:
610 * 712 *
611 * - If all components of the ligature were marks, we call this a mark ligatur e. 713 * - If all components of the ligature were marks, we call this a mark ligatur e.
612 * 714 *
613 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori ze 715 * - If there is no GDEF, and the ligature is NOT a mark ligature, we categori ze
614 * it as a ligature glyph. 716 * it as a ligature glyph.
615 * 717 *
616 * - Ligatures cannot be formed across glyphs attached to different components 718 * - Ligatures cannot be formed across glyphs attached to different components
617 * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and 719 * of previous ligatures. Eg. the sequence is LAM,SHADDA,LAM,FATHA,HEH, and
618 * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother. 720 * LAM,LAM,HEH form a ligature, leaving SHADDA,FATHA next to eachother.
619 * However, it would be wrong to ligate that SHADDA,FATHA sequence.o 721 * However, it would be wrong to ligate that SHADDA,FATHA sequence.o
620 * There is an exception to this: If a ligature tries ligating with marks th at 722 * There is an exception to this: If a ligature tries ligating with marks th at
621 * belong to it itself, go ahead, assuming that the font designer knows what 723 * belong to it itself, go ahead, assuming that the font designer knows what
622 * they are doing (otherwise it can break Indic stuff when a matra wants to 724 * they are doing (otherwise it can break Indic stuff when a matra wants to
623 * ligate with a conjunct...) 725 * ligate with a conjunct...)
624 */ 726 */
625 727
626 bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK); 728 bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH _PROPS_MARK);
627 729
628 unsigned int total_component_count = 0; 730 unsigned int total_component_count = 0;
629 total_component_count += get_lig_num_comps (c->buffer->cur()); 731 total_component_count += get_lig_num_comps (c->buffer->cur());
630 732
631 unsigned int first_lig_id = get_lig_id (c->buffer->cur()); 733 unsigned int first_lig_id = get_lig_id (c->buffer->cur());
632 unsigned int first_lig_comp = get_lig_comp (c->buffer->cur()); 734 unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
633 735
634 for (unsigned int i = 1; i < count; i++) 736 for (unsigned int i = 1; i < count; i++)
635 { 737 {
636 unsigned int property; 738 if (!skippy_iter.next ()) return TRACE_RETURN (false);
637
638 if (!skippy_iter.next (&property)) return TRACE_RETURN (false);
639
640 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, input[i - 1], match_data))) return TRACE_RETURN (false);
641 739
642 unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]); 740 unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
643 unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]) ; 741 unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]) ;
644 742
645 if (first_lig_id && first_lig_comp) { 743 if (first_lig_id && first_lig_comp) {
646 /* If first component was attached to a previous ligature component, 744 /* If first component was attached to a previous ligature component,
647 * all subsequent components should be attached to the same ligature 745 * all subsequent components should be attached to the same ligature
648 * component, otherwise we shouldn't ligate them. */ 746 * component, otherwise we shouldn't ligate them. */
649 if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) 747 if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
650 return TRACE_RETURN (false); 748 return TRACE_RETURN (false);
651 } else { 749 } else {
652 /* If first component was NOT attached to a previous ligature component, 750 /* If first component was NOT attached to a previous ligature component,
653 * all subsequent components should also NOT be attached to any ligature 751 * all subsequent components should also NOT be attached to any ligature
654 * component, unless they are attached to the first component itself! */ 752 * component, unless they are attached to the first component itself! */
655 if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) 753 if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id))
656 return TRACE_RETURN (false); 754 return TRACE_RETURN (false);
657 } 755 }
658 756
659 is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_PROPS_ MARK); 757 is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].gly ph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
660 total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx] ); 758 total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx] );
661 } 759 }
662 760
663 if (end_offset) 761 if (end_offset)
664 *end_offset = skippy_iter.idx - c->buffer->idx + 1; 762 *end_offset = skippy_iter.idx - c->buffer->idx + 1;
665 763
666 if (p_is_mark_ligature) 764 if (p_is_mark_ligature)
667 *p_is_mark_ligature = is_mark_ligature; 765 *p_is_mark_ligature = is_mark_ligature;
668 766
669 if (p_total_component_count) 767 if (p_total_component_count)
670 *p_total_component_count = total_component_count; 768 *p_total_component_count = total_component_count;
671 769
672 return TRACE_RETURN (true); 770 return TRACE_RETURN (true);
673 } 771 }
674 static inline void ligate_input (hb_apply_context_t *c, 772 static inline void ligate_input (hb_apply_context_t *c,
675 unsigned int count, /* Including the first glyp h (not matched) */ 773 unsigned int count, /* Including the first glyp h (not matched) */
676 » » » » const USHORT input[] HB_UNUSED, /* Array of inp ut values--start with second glyph */ 774 » » » » const USHORT input[], /* Array of input values- -start with second glyph */
775 » » » » match_func_t match_func,
776 » » » » const void *match_data,
677 hb_codepoint_t lig_glyph, 777 hb_codepoint_t lig_glyph,
678 match_func_t match_func HB_UNUSED,
679 const void *match_data HB_UNUSED,
680 bool is_mark_ligature, 778 bool is_mark_ligature,
681 unsigned int total_component_count) 779 unsigned int total_component_count)
682 { 780 {
781 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1);
782 skippy_iter.set_match_func (match_func, match_data, input);
783 if (skippy_iter.has_no_chance ()) return;
784
683 /* 785 /*
684 * - If it *is* a mark ligature, we don't allocate a new ligature id, and leav e 786 * - If it *is* a mark ligature, we don't allocate a new ligature id, and leav e
685 * the ligature to keep its old ligature id. This will allow it to attach t o 787 * the ligature to keep its old ligature id. This will allow it to attach t o
686 * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HE H, 788 * a base ligature in GPOS. Eg. if the sequence is: LAM,LAM,SHADDA,FATHA,HE H,
687 * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a 789 * and LAM,LAM,HEH for a ligature, they will leave SHADDA and FATHA wit a
688 * ligature id and component value of 2. Then if SHADDA,FATHA form a ligatu re 790 * ligature id and component value of 2. Then if SHADDA,FATHA form a ligatu re
689 * later, we don't want them to lose their ligature id/component, otherwise 791 * later, we don't want them to lose their ligature id/component, otherwise
690 * GPOS will fail to correctly position the mark ligature on top of the 792 * GPOS will fail to correctly position the mark ligature on top of the
691 * LAM,LAM,HEH ligature. See: 793 * LAM,LAM,HEH ligature. See:
692 * https://bugzilla.gnome.org/show_bug.cgi?id=676343 794 * https://bugzilla.gnome.org/show_bug.cgi?id=676343
(...skipping 20 matching lines...) Expand all
713 unsigned int last_lig_id = get_lig_id (c->buffer->cur()); 815 unsigned int last_lig_id = get_lig_id (c->buffer->cur());
714 unsigned int last_num_components = get_lig_num_comps (c->buffer->cur()); 816 unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
715 unsigned int components_so_far = last_num_components; 817 unsigned int components_so_far = last_num_components;
716 818
717 if (!is_mark_ligature) 819 if (!is_mark_ligature)
718 set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count) ; 820 set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count) ;
719 c->replace_glyph (lig_glyph, klass); 821 c->replace_glyph (lig_glyph, klass);
720 822
721 for (unsigned int i = 1; i < count; i++) 823 for (unsigned int i = 1; i < count; i++)
722 { 824 {
723 while (c->should_mark_skip_current_glyph ()) 825 if (!skippy_iter.next ()) return;
826
827 while (c->buffer->idx < skippy_iter.idx)
724 { 828 {
725 if (!is_mark_ligature) { 829 if (!is_mark_ligature) {
726 unsigned int new_lig_comp = components_so_far - last_num_components + 830 unsigned int new_lig_comp = components_so_far - last_num_components +
727 MIN (MAX (get_lig_comp (c->buffer->cur()), 1 u), last_num_components); 831 MIN (MAX (get_lig_comp (c->buffer->cur()), 1 u), last_num_components);
728 set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp); 832 set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
729 } 833 }
730 c->buffer->next_glyph (); 834 c->buffer->next_glyph ();
731 } 835 }
732 836
733 last_lig_id = get_lig_id (c->buffer->cur()); 837 last_lig_id = get_lig_id (c->buffer->cur());
(...skipping 18 matching lines...) Expand all
752 } 856 }
753 857
754 static inline bool match_backtrack (hb_apply_context_t *c, 858 static inline bool match_backtrack (hb_apply_context_t *c,
755 unsigned int count, 859 unsigned int count,
756 const USHORT backtrack[], 860 const USHORT backtrack[],
757 match_func_t match_func, 861 match_func_t match_func,
758 const void *match_data) 862 const void *match_data)
759 { 863 {
760 TRACE_APPLY (NULL); 864 TRACE_APPLY (NULL);
761 865
762 hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffe r->backtrack_len (), count, true); 866 hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->ba cktrack_len (), count, true);
763 if (skippy_iter.has_no_chance ()) 867 skippy_iter.set_match_func (match_func, match_data, backtrack);
764 return TRACE_RETURN (false); 868 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
765 869
766 for (unsigned int i = 0; i < count; i++) 870 for (unsigned int i = 0; i < count; i++)
767 {
768 if (!skippy_iter.prev ()) 871 if (!skippy_iter.prev ())
769 return TRACE_RETURN (false); 872 return TRACE_RETURN (false);
770 873
771 if (likely (!match_func (c->buffer->out_info[skippy_iter.idx].codepoint, bac ktrack[i], match_data)))
772 return TRACE_RETURN (false);
773 }
774
775 return TRACE_RETURN (true); 874 return TRACE_RETURN (true);
776 } 875 }
777 876
778 static inline bool match_lookahead (hb_apply_context_t *c, 877 static inline bool match_lookahead (hb_apply_context_t *c,
779 unsigned int count, 878 unsigned int count,
780 const USHORT lookahead[], 879 const USHORT lookahead[],
781 match_func_t match_func, 880 match_func_t match_func,
782 const void *match_data, 881 const void *match_data,
783 unsigned int offset) 882 unsigned int offset)
784 { 883 {
785 TRACE_APPLY (NULL); 884 TRACE_APPLY (NULL);
786 885
787 hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer ->idx + offset - 1, count, true); 886 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
788 if (skippy_iter.has_no_chance ()) 887 skippy_iter.set_match_func (match_func, match_data, lookahead);
789 return TRACE_RETURN (false); 888 if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
790 889
791 for (unsigned int i = 0; i < count; i++) 890 for (unsigned int i = 0; i < count; i++)
792 {
793 if (!skippy_iter.next ()) 891 if (!skippy_iter.next ())
794 return TRACE_RETURN (false); 892 return TRACE_RETURN (false);
795 893
796 if (likely (!match_func (c->buffer->info[skippy_iter.idx].codepoint, lookahe ad[i], match_data)))
797 return TRACE_RETURN (false);
798 }
799
800 return TRACE_RETURN (true); 894 return TRACE_RETURN (true);
801 } 895 }
802 896
803 897
804 898
805 struct LookupRecord 899 struct LookupRecord
806 { 900 {
807 inline bool sanitize (hb_sanitize_context_t *c) { 901 inline bool sanitize (hb_sanitize_context_t *c) {
808 TRACE_SANITIZE (this); 902 TRACE_SANITIZE (this);
809 return TRACE_RETURN (c->check_struct (this)); 903 return TRACE_RETURN (c->check_struct (this));
(...skipping 12 matching lines...) Expand all
822 static inline void recurse_lookups (context_t *c, 916 static inline void recurse_lookups (context_t *c,
823 unsigned int lookupCount, 917 unsigned int lookupCount,
824 const LookupRecord lookupRecord[] /* Array o f LookupRecords--in design order */) 918 const LookupRecord lookupRecord[] /* Array o f LookupRecords--in design order */)
825 { 919 {
826 for (unsigned int i = 0; i < lookupCount; i++) 920 for (unsigned int i = 0; i < lookupCount; i++)
827 c->recurse (lookupRecord->lookupListIndex); 921 c->recurse (lookupRecord->lookupListIndex);
828 } 922 }
829 923
830 static inline bool apply_lookup (hb_apply_context_t *c, 924 static inline bool apply_lookup (hb_apply_context_t *c,
831 unsigned int count, /* Including the first glyp h */ 925 unsigned int count, /* Including the first glyp h */
926 const USHORT input[], /* Array of input values- -start with second glyph */
927 match_func_t match_func,
928 const void *match_data,
832 unsigned int lookupCount, 929 unsigned int lookupCount,
833 const LookupRecord lookupRecord[] /* Array of L ookupRecords--in design order */) 930 const LookupRecord lookupRecord[] /* Array of L ookupRecords--in design order */)
834 { 931 {
835 TRACE_APPLY (NULL); 932 TRACE_APPLY (NULL);
836 933
837 unsigned int end = c->buffer->len; 934 unsigned int end = c->buffer->len;
838 if (unlikely (count == 0 || c->buffer->idx + count > end)) 935 if (unlikely (count == 0 || c->buffer->idx + count > end))
839 return TRACE_RETURN (false); 936 return TRACE_RETURN (false);
840 937
841 /* TODO We don't support lookupRecord arrays that are not increasing: 938 /* TODO We don't support lookupRecord arrays that are not increasing:
842 * Should be easy for in_place ones at least. */ 939 * Should be easy for in_place ones at least. */
843 940
844 /* Note: If sublookup is reverse, it will underflow after the first loop 941 /* Note: If sublookup is reverse, it will underflow after the first loop
845 * and we jump out of it. Not entirely disastrous. So we don't check 942 * and we jump out of it. Not entirely disastrous. So we don't check
846 * for reverse lookup here. 943 * for reverse lookup here.
847 */ 944 */
848 for (unsigned int i = 0; i < count; /* NOP */) 945
946 hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx , count - 1);
947 skippy_iter.set_match_func (match_func, match_data, input);
948 uint8_t syllable = c->buffer->cur().syllable();
949
950 unsigned int i = 0;
951 if (lookupCount && 0 == lookupRecord->sequenceIndex)
849 { 952 {
850 if (unlikely (c->buffer->idx == end)) 953 unsigned int old_pos = c->buffer->idx;
851 return TRACE_RETURN (true); 954
852 while (c->should_mark_skip_current_glyph ()) 955 /* Apply a lookup */
956 bool done = c->recurse (lookupRecord->lookupListIndex);
957
958 lookupRecord++;
959 lookupCount--;
960 /* Err, this is wrong if the lookup jumped over some glyphs */
961 i += c->buffer->idx - old_pos;
962
963 if (!done)
964 goto not_applied;
965 else
853 { 966 {
854 /* No lookup applied for this index */ 967 /* Reinitialize iterator. */
968 hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1 , count - i);
969 tmp.set_syllable (syllable);
970 skippy_iter = tmp;
971 }
972 }
973 else
974 {
975 not_applied:
976 /* No lookup applied for this index */
977 c->buffer->next_glyph ();
978 i++;
979 }
980 while (i < count)
981 {
982 if (!skippy_iter.next ()) return TRACE_RETURN (true);
983 while (c->buffer->idx < skippy_iter.idx)
855 c->buffer->next_glyph (); 984 c->buffer->next_glyph ();
856 if (unlikely (c->buffer->idx == end))
857 return TRACE_RETURN (true);
858 }
859 985
860 if (lookupCount && i == lookupRecord->sequenceIndex) 986 if (lookupCount && i == lookupRecord->sequenceIndex)
861 { 987 {
862 unsigned int old_pos = c->buffer->idx; 988 unsigned int old_pos = c->buffer->idx;
863 989
864 /* Apply a lookup */ 990 /* Apply a lookup */
865 bool done = c->recurse (lookupRecord->lookupListIndex); 991 bool done = c->recurse (lookupRecord->lookupListIndex);
866 992
867 lookupRecord++; 993 lookupRecord++;
868 lookupCount--; 994 lookupCount--;
869 /* Err, this is wrong if the lookup jumped over some glyphs */ 995 /* Err, this is wrong if the lookup jumped over some glyphs */
870 i += c->buffer->idx - old_pos; 996 i += c->buffer->idx - old_pos;
871 if (unlikely (c->buffer->idx == end))
872 return TRACE_RETURN (true);
873 997
874 if (!done) 998 if (!done)
875 » goto not_applied; 999 » goto not_applied2;
1000 else
1001 {
1002 /* Reinitialize iterator. */
1003 » hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
1004 » tmp.set_syllable (syllable);
1005 » skippy_iter = tmp;
1006 }
876 } 1007 }
877 else 1008 else
878 { 1009 {
879 not_applied: 1010 not_applied2:
880 /* No lookup applied for this index */ 1011 /* No lookup applied for this index */
881 c->buffer->next_glyph (); 1012 c->buffer->next_glyph ();
882 i++; 1013 i++;
883 } 1014 }
884 } 1015 }
885 1016
886 return TRACE_RETURN (true); 1017 return TRACE_RETURN (true);
887 } 1018 }
888 1019
889 1020
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 unsigned int inputCount, /* Including t he first glyph (not matched) */ 1082 unsigned int inputCount, /* Including t he first glyph (not matched) */
952 const USHORT input[], /* Array of input values--start with second glyph */ 1083 const USHORT input[], /* Array of input values--start with second glyph */
953 unsigned int lookupCount, 1084 unsigned int lookupCount,
954 const LookupRecord lookupRecord[], 1085 const LookupRecord lookupRecord[],
955 ContextApplyLookupContext &lookup_conte xt) 1086 ContextApplyLookupContext &lookup_conte xt)
956 { 1087 {
957 return match_input (c, 1088 return match_input (c,
958 inputCount, input, 1089 inputCount, input,
959 lookup_context.funcs.match, lookup_context.match_data) 1090 lookup_context.funcs.match, lookup_context.match_data)
960 && apply_lookup (c, 1091 && apply_lookup (c,
961 » » inputCount, 1092 » » inputCount, input,
1093 » » lookup_context.funcs.match, lookup_context.match_data,
962 lookupCount, lookupRecord); 1094 lookupCount, lookupRecord);
963 } 1095 }
964 1096
965 struct Rule 1097 struct Rule
966 { 1098 {
967 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo kup_context) const 1099 inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &loo kup_context) const
968 { 1100 {
969 TRACE_CLOSURE (this); 1101 TRACE_CLOSURE (this);
970 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp ut[0].static_size * (inputCount ? inputCount - 1 : 0)); 1102 const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, inp ut[0].static_size * (inputCount ? inputCount - 1 : 0));
971 context_closure_lookup (c, 1103 context_closure_lookup (c,
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 * table in glyph sequence order */ 1478 * table in glyph sequence order */
1347 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in 1479 LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
1348 * design order */ 1480 * design order */
1349 public: 1481 public:
1350 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX); 1482 DEFINE_SIZE_ARRAY2 (6, coverage, lookupRecordX);
1351 }; 1483 };
1352 1484
1353 struct Context 1485 struct Context
1354 { 1486 {
1355 template <typename context_t> 1487 template <typename context_t>
1356 inline typename context_t::return_t process (context_t *c) const 1488 inline typename context_t::return_t dispatch (context_t *c) const
1357 { 1489 {
1358 TRACE_PROCESS (this); 1490 TRACE_DISPATCH (this);
1359 switch (u.format) { 1491 switch (u.format) {
1360 case 1: return TRACE_RETURN (c->process (u.format1)); 1492 case 1: return TRACE_RETURN (c->dispatch (u.format1));
1361 case 2: return TRACE_RETURN (c->process (u.format2)); 1493 case 2: return TRACE_RETURN (c->dispatch (u.format2));
1362 case 3: return TRACE_RETURN (c->process (u.format3)); 1494 case 3: return TRACE_RETURN (c->dispatch (u.format3));
1363 default:return TRACE_RETURN (c->default_return_value ()); 1495 default:return TRACE_RETURN (c->default_return_value ());
1364 } 1496 }
1365 } 1497 }
1366 1498
1367 inline bool sanitize (hb_sanitize_context_t *c) { 1499 inline bool sanitize (hb_sanitize_context_t *c) {
1368 TRACE_SANITIZE (this); 1500 TRACE_SANITIZE (this);
1369 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 1501 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
1370 switch (u.format) { 1502 switch (u.format) {
1371 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 1503 case 1: return TRACE_RETURN (u.format1.sanitize (c));
1372 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 1504 case 2: return TRACE_RETURN (u.format2.sanitize (c));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 lookup_context.funcs.match, lookup_context.match_data[1], 1619 lookup_context.funcs.match, lookup_context.match_data[1],
1488 &lookahead_offset) 1620 &lookahead_offset)
1489 && match_backtrack (c, 1621 && match_backtrack (c,
1490 backtrackCount, backtrack, 1622 backtrackCount, backtrack,
1491 lookup_context.funcs.match, lookup_context.match_data[ 0]) 1623 lookup_context.funcs.match, lookup_context.match_data[ 0])
1492 && match_lookahead (c, 1624 && match_lookahead (c,
1493 lookaheadCount, lookahead, 1625 lookaheadCount, lookahead,
1494 lookup_context.funcs.match, lookup_context.match_data[ 2], 1626 lookup_context.funcs.match, lookup_context.match_data[ 2],
1495 lookahead_offset) 1627 lookahead_offset)
1496 && apply_lookup (c, 1628 && apply_lookup (c,
1497 » » inputCount, 1629 » » inputCount, input,
1630 » » lookup_context.funcs.match, lookup_context.match_data[1],
1498 lookupCount, lookupRecord); 1631 lookupCount, lookupRecord);
1499 } 1632 }
1500 1633
1501 struct ChainRule 1634 struct ChainRule
1502 { 1635 {
1503 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const 1636 inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
1504 { 1637 {
1505 TRACE_CLOSURE (this); 1638 TRACE_CLOSURE (this);
1506 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); 1639 const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
1507 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); 1640 const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1961 ArrayOf<LookupRecord> 2094 ArrayOf<LookupRecord>
1962 lookupX; /* Array of LookupRecords--in 2095 lookupX; /* Array of LookupRecords--in
1963 * design order) */ 2096 * design order) */
1964 public: 2097 public:
1965 DEFINE_SIZE_MIN (10); 2098 DEFINE_SIZE_MIN (10);
1966 }; 2099 };
1967 2100
1968 struct ChainContext 2101 struct ChainContext
1969 { 2102 {
1970 template <typename context_t> 2103 template <typename context_t>
1971 inline typename context_t::return_t process (context_t *c) const 2104 inline typename context_t::return_t dispatch (context_t *c) const
1972 { 2105 {
1973 TRACE_PROCESS (this); 2106 TRACE_DISPATCH (this);
1974 switch (u.format) { 2107 switch (u.format) {
1975 case 1: return TRACE_RETURN (c->process (u.format1)); 2108 case 1: return TRACE_RETURN (c->dispatch (u.format1));
1976 case 2: return TRACE_RETURN (c->process (u.format2)); 2109 case 2: return TRACE_RETURN (c->dispatch (u.format2));
1977 case 3: return TRACE_RETURN (c->process (u.format3)); 2110 case 3: return TRACE_RETURN (c->dispatch (u.format3));
1978 default:return TRACE_RETURN (c->default_return_value ()); 2111 default:return TRACE_RETURN (c->default_return_value ());
1979 } 2112 }
1980 } 2113 }
1981 2114
1982 inline bool sanitize (hb_sanitize_context_t *c) { 2115 inline bool sanitize (hb_sanitize_context_t *c) {
1983 TRACE_SANITIZE (this); 2116 TRACE_SANITIZE (this);
1984 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 2117 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
1985 switch (u.format) { 2118 switch (u.format) {
1986 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 2119 case 1: return TRACE_RETURN (u.format1.sanitize (c));
1987 case 2: return TRACE_RETURN (u.format2.sanitize (c)); 2120 case 2: return TRACE_RETURN (u.format2.sanitize (c));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 2174
2042 template <typename X> 2175 template <typename X>
2043 inline const X& get_subtable (void) const 2176 inline const X& get_subtable (void) const
2044 { 2177 {
2045 unsigned int offset = get_offset (); 2178 unsigned int offset = get_offset ();
2046 if (unlikely (!offset)) return Null(typename T::LookupSubTable); 2179 if (unlikely (!offset)) return Null(typename T::LookupSubTable);
2047 return StructAtOffset<typename T::LookupSubTable> (this, offset); 2180 return StructAtOffset<typename T::LookupSubTable> (this, offset);
2048 } 2181 }
2049 2182
2050 template <typename context_t> 2183 template <typename context_t>
2051 inline typename context_t::return_t process (context_t *c) const 2184 inline typename context_t::return_t dispatch (context_t *c) const
2052 { 2185 {
2053 return get_subtable<typename T::LookupSubTable> ().process (c, get_type ()); 2186 return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()) ;
2054 } 2187 }
2055 2188
2056 inline bool sanitize_self (hb_sanitize_context_t *c) { 2189 inline bool sanitize_self (hb_sanitize_context_t *c) {
2057 TRACE_SANITIZE (this); 2190 TRACE_SANITIZE (this);
2058 if (!u.format.sanitize (c)) return TRACE_RETURN (false); 2191 if (!u.format.sanitize (c)) return TRACE_RETURN (false);
2059 switch (u.format) { 2192 switch (u.format) {
2060 case 1: return TRACE_RETURN (u.format1.sanitize (c)); 2193 case 1: return TRACE_RETURN (u.format1.sanitize (c));
2061 default:return TRACE_RETURN (true); 2194 default:return TRACE_RETURN (true);
2062 } 2195 }
2063 } 2196 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 lookupList; /* LookupList table */ 2270 lookupList; /* LookupList table */
2138 public: 2271 public:
2139 DEFINE_SIZE_STATIC (10); 2272 DEFINE_SIZE_STATIC (10);
2140 }; 2273 };
2141 2274
2142 2275
2143 } /* namespace OT */ 2276 } /* namespace OT */
2144 2277
2145 2278
2146 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ 2279 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698