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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 uint8_t syllable; | 335 uint8_t syllable; |
336 match_func_t match_func; | 336 match_func_t match_func; |
337 const void *match_data; | 337 const void *match_data; |
338 }; | 338 }; |
339 | 339 |
340 struct skipping_iterator_t | 340 struct skipping_iterator_t |
341 { | 341 { |
342 inline void init (hb_apply_context_t *c_, bool context_match = false) | 342 inline void init (hb_apply_context_t *c_, bool context_match = false) |
343 { | 343 { |
344 c = c_; | 344 c = c_; |
345 match_glyph_data = NULL, | 345 match_glyph_data = NULL; |
346 matcher.set_match_func (NULL, NULL); | 346 matcher.set_match_func (NULL, NULL); |
347 matcher.set_lookup_props (c->lookup_props); | 347 matcher.set_lookup_props (c->lookup_props); |
348 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ | 348 /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ |
349 matcher.set_ignore_zwnj (context_match || c->table_index == 1); | 349 matcher.set_ignore_zwnj (context_match || c->table_index == 1); |
350 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask
ed to. */ | 350 /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if ask
ed to. */ |
351 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw
j); | 351 matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zw
j); |
352 matcher.set_mask (context_match ? -1 : c->lookup_mask); | 352 matcher.set_mask (context_match ? -1 : c->lookup_mask); |
353 } | 353 } |
354 inline void set_lookup_props (unsigned int lookup_props) | 354 inline void set_lookup_props (unsigned int lookup_props) |
355 { | 355 { |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 static inline bool apply_lookup (hb_apply_context_t *c, | 952 static inline bool apply_lookup (hb_apply_context_t *c, |
953 unsigned int count, /* Including the first glyp
h */ | 953 unsigned int count, /* Including the first glyp
h */ |
954 unsigned int match_positions[HB_MAX_CONTEXT_LEN
GTH], /* Including the first glyph */ | 954 unsigned int match_positions[HB_MAX_CONTEXT_LEN
GTH], /* Including the first glyph */ |
955 unsigned int lookupCount, | 955 unsigned int lookupCount, |
956 const LookupRecord lookupRecord[], /* Array of
LookupRecords--in design order */ | 956 const LookupRecord lookupRecord[], /* Array of
LookupRecords--in design order */ |
957 unsigned int match_length) | 957 unsigned int match_length) |
958 { | 958 { |
959 TRACE_APPLY (NULL); | 959 TRACE_APPLY (NULL); |
960 | 960 |
961 hb_buffer_t *buffer = c->buffer; | 961 hb_buffer_t *buffer = c->buffer; |
962 unsigned int end; | 962 int end; |
963 | 963 |
964 /* All positions are distance from beginning of *output* buffer. | 964 /* All positions are distance from beginning of *output* buffer. |
965 * Adjust. */ | 965 * Adjust. */ |
966 { | 966 { |
967 unsigned int bl = buffer->backtrack_len (); | 967 unsigned int bl = buffer->backtrack_len (); |
968 end = bl + match_length; | 968 end = bl + match_length; |
969 | 969 |
970 int delta = bl - buffer->idx; | 970 int delta = bl - buffer->idx; |
971 /* Convert positions to new indexing. */ | 971 /* Convert positions to new indexing. */ |
972 for (unsigned int j = 0; j < count; j++) | 972 for (unsigned int j = 0; j < count; j++) |
(...skipping 16 matching lines...) Expand all Loading... |
989 unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); | 989 unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); |
990 if (!c->recurse (lookupRecord[i].lookupListIndex)) | 990 if (!c->recurse (lookupRecord[i].lookupListIndex)) |
991 continue; | 991 continue; |
992 | 992 |
993 unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); | 993 unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len (); |
994 int delta = new_len - orig_len; | 994 int delta = new_len - orig_len; |
995 | 995 |
996 if (!delta) | 996 if (!delta) |
997 continue; | 997 continue; |
998 | 998 |
999 /* Recursed lookup changed buffer len. Adjust. */ | 999 /* Recursed lookup changed buffer len. Adjust. |
| 1000 * |
| 1001 * TODO: |
| 1002 * |
| 1003 * Right now, if buffer length increased by n, we assume n new glyphs |
| 1004 * were added right after the current position, and if buffer length |
| 1005 * was decreased by n, we assume n match positions after the current |
| 1006 * one where removed. The former (buffer length increased) case is |
| 1007 * fine, but the decrease case can be improved in at least two ways, |
| 1008 * both of which are significant: |
| 1009 * |
| 1010 * - If recursed-to lookup is MultipleSubst and buffer length |
| 1011 * decreased, then it's current match position that was deleted, |
| 1012 * NOT the one after it. |
| 1013 * |
| 1014 * - If buffer length was decreased by n, it does not necessarily |
| 1015 * mean that n match positions where removed, as there might |
| 1016 * have been marks and default-ignorables in the sequence. We |
| 1017 * should instead drop match positions between current-position |
| 1018 * and current-position + n instead. |
| 1019 * |
| 1020 * It should be possible to construct tests for both of these cases. |
| 1021 */ |
1000 | 1022 |
1001 end = int (end) + delta; | 1023 end += delta; |
1002 if (end <= match_positions[idx]) | 1024 if (end <= int (match_positions[idx])) |
1003 { | 1025 { |
1004 /* End might end up being smaller than match_positions[idx] if the recurse
d | 1026 /* End might end up being smaller than match_positions[idx] if the recurse
d |
1005 * lookup ended up removing many items, more than we have had matched. | 1027 * lookup ended up removing many items, more than we have had matched. |
1006 * Just never rewind end back and get out of here. | 1028 * Just never rewind end back and get out of here. |
1007 * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */ | 1029 * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */ |
1008 end = match_positions[idx]; | 1030 end = match_positions[idx]; |
1009 /* There can't be any further changes. */ | 1031 /* There can't be any further changes. */ |
1010 break; | 1032 break; |
1011 } | 1033 } |
1012 | 1034 |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2320 * in version 0x00010001. */ | 2342 * in version 0x00010001. */ |
2321 public: | 2343 public: |
2322 DEFINE_SIZE_MIN (10); | 2344 DEFINE_SIZE_MIN (10); |
2323 }; | 2345 }; |
2324 | 2346 |
2325 | 2347 |
2326 } /* namespace OT */ | 2348 } /* namespace OT */ |
2327 | 2349 |
2328 | 2350 |
2329 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ | 2351 #endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */ |
OLD | NEW |