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,2013 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
11 * all copies of this software. | 11 * all copies of this software. |
12 * | 12 * |
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 unsigned int count = substitute.len; | 265 unsigned int count = substitute.len; |
266 for (unsigned int i = 0; i < count; i++) | 266 for (unsigned int i = 0; i < count; i++) |
267 c->output->add (substitute[i]); | 267 c->output->add (substitute[i]); |
268 } | 268 } |
269 | 269 |
270 inline bool apply (hb_apply_context_t *c) const | 270 inline bool apply (hb_apply_context_t *c) const |
271 { | 271 { |
272 TRACE_APPLY (this); | 272 TRACE_APPLY (this); |
273 if (unlikely (!substitute.len)) return TRACE_RETURN (false); | 273 if (unlikely (!substitute.len)) return TRACE_RETURN (false); |
274 | 274 |
275 unsigned int klass = c->buffer->cur().glyph_props() & | 275 unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? |
276 » » » HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_
PROPS_BASE_GLYPH : 0; | 276 » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; |
277 unsigned int count = substitute.len; | 277 unsigned int count = substitute.len; |
278 if (count == 1) /* Special-case to make it in-place. */ | 278 if (count == 1) /* Special-case to make it in-place. */ |
279 { | 279 { |
280 c->replace_glyph (substitute.array[0]); | 280 c->replace_glyph (substitute.array[0]); |
281 } | 281 } |
282 else | 282 else |
283 { | 283 { |
284 for (unsigned int i = 0; i < count; i++) { | 284 for (unsigned int i = 0; i < count; i++) { |
285 » set_lig_props_for_component (c->buffer->cur(), i); | 285 » _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i); |
286 c->output_glyph (substitute.array[i], klass); | 286 c->output_glyph (substitute.array[i], klass); |
287 } | 287 } |
288 c->buffer->skip_glyph (); | 288 c->buffer->skip_glyph (); |
289 } | 289 } |
290 | 290 |
291 return TRACE_RETURN (true); | 291 return TRACE_RETURN (true); |
292 } | 292 } |
293 | 293 |
294 inline bool serialize (hb_serialize_context_t *c, | 294 inline bool serialize (hb_serialize_context_t *c, |
295 Supplier<GlyphID> &glyphs, | 295 Supplier<GlyphID> &glyphs, |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 | 619 |
620 return TRACE_RETURN (true); | 620 return TRACE_RETURN (true); |
621 } | 621 } |
622 | 622 |
623 inline bool apply (hb_apply_context_t *c) const | 623 inline bool apply (hb_apply_context_t *c) const |
624 { | 624 { |
625 TRACE_APPLY (this); | 625 TRACE_APPLY (this); |
626 unsigned int count = component.len; | 626 unsigned int count = component.len; |
627 if (unlikely (count < 1)) return TRACE_RETURN (false); | 627 if (unlikely (count < 1)) return TRACE_RETURN (false); |
628 | 628 |
629 unsigned int end_offset = 0; | |
630 bool is_mark_ligature = false; | 629 bool is_mark_ligature = false; |
631 unsigned int total_component_count = 0; | 630 unsigned int total_component_count = 0; |
632 | 631 |
| 632 unsigned int match_length = 0; |
| 633 unsigned int match_positions[MAX_CONTEXT_LENGTH]; |
| 634 |
633 if (likely (!match_input (c, count, | 635 if (likely (!match_input (c, count, |
634 &component[1], | 636 &component[1], |
635 match_glyph, | 637 match_glyph, |
636 NULL, | 638 NULL, |
637 » » » &end_offset, | 639 » » » &match_length, |
| 640 » » » match_positions, |
638 &is_mark_ligature, | 641 &is_mark_ligature, |
639 &total_component_count))) | 642 &total_component_count))) |
640 return TRACE_RETURN (false); | 643 return TRACE_RETURN (false); |
641 | 644 |
642 /* Deal, we are forming the ligature. */ | |
643 c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset); | |
644 | |
645 ligate_input (c, | 645 ligate_input (c, |
646 count, | 646 count, |
647 » » &component[1], | 647 » » match_positions, |
648 » » match_glyph, | 648 » » match_length, |
649 » » NULL, | |
650 ligGlyph, | 649 ligGlyph, |
651 is_mark_ligature, | 650 is_mark_ligature, |
652 total_component_count); | 651 total_component_count); |
653 | 652 |
654 return TRACE_RETURN (true); | 653 return TRACE_RETURN (true); |
655 } | 654 } |
656 | 655 |
657 inline bool serialize (hb_serialize_context_t *c, | 656 inline bool serialize (hb_serialize_context_t *c, |
658 GlyphID ligature, | 657 GlyphID ligature, |
659 Supplier<GlyphID> &components, /* Starting from second
*/ | 658 Supplier<GlyphID> &components, /* Starting from second
*/ |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 | 981 |
983 if (match_backtrack (c, | 982 if (match_backtrack (c, |
984 backtrack.len, (USHORT *) backtrack.array, | 983 backtrack.len, (USHORT *) backtrack.array, |
985 match_coverage, this) && | 984 match_coverage, this) && |
986 match_lookahead (c, | 985 match_lookahead (c, |
987 lookahead.len, (USHORT *) lookahead.array, | 986 lookahead.len, (USHORT *) lookahead.array, |
988 match_coverage, this, | 987 match_coverage, this, |
989 1)) | 988 1)) |
990 { | 989 { |
991 c->replace_glyph_inplace (substitute[index]); | 990 c->replace_glyph_inplace (substitute[index]); |
992 c->buffer->idx--; /* Reverse! */ | 991 /* Note: We DON'T decrease buffer->idx. The main loop does it |
| 992 * for us. This is useful for preventing surprises if someone |
| 993 * calls us through a Context lookup. */ |
993 return TRACE_RETURN (true); | 994 return TRACE_RETURN (true); |
994 } | 995 } |
995 | 996 |
996 return TRACE_RETURN (false); | 997 return TRACE_RETURN (false); |
997 } | 998 } |
998 | 999 |
999 inline bool sanitize (hb_sanitize_context_t *c) { | 1000 inline bool sanitize (hb_sanitize_context_t *c) { |
1000 TRACE_SANITIZE (this); | 1001 TRACE_SANITIZE (this); |
1001 if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) | 1002 if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) |
1002 return TRACE_RETURN (false); | 1003 return TRACE_RETURN (false); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1145 return lookup_type_is_reverse (type); | 1146 return lookup_type_is_reverse (type); |
1146 } | 1147 } |
1147 | 1148 |
1148 inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const | 1149 inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const |
1149 { | 1150 { |
1150 TRACE_CLOSURE (this); | 1151 TRACE_CLOSURE (this); |
1151 c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); | 1152 c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); |
1152 return TRACE_RETURN (dispatch (c)); | 1153 return TRACE_RETURN (dispatch (c)); |
1153 } | 1154 } |
1154 | 1155 |
1155 inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect
_glyphs_context_t *c) const | 1156 inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs
_context_t *c) const |
1156 { | 1157 { |
1157 TRACE_COLLECT_GLYPHS (this); | 1158 TRACE_COLLECT_GLYPHS (this); |
1158 c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); | 1159 c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); |
1159 return TRACE_RETURN (dispatch (c)); | 1160 return TRACE_RETURN (dispatch (c)); |
1160 } | 1161 } |
1161 | 1162 |
1162 template <typename set_t> | 1163 template <typename set_t> |
1163 inline void add_coverage (set_t *glyphs) const | 1164 inline void add_coverage (set_t *glyphs) const |
1164 { | 1165 { |
1165 hb_get_coverage_context_t c; | 1166 hb_get_coverage_context_t c; |
(...skipping 18 matching lines...) Expand all Loading... |
1184 | 1185 |
1185 inline bool apply_once (hb_apply_context_t *c) const | 1186 inline bool apply_once (hb_apply_context_t *c) const |
1186 { | 1187 { |
1187 TRACE_APPLY (this); | 1188 TRACE_APPLY (this); |
1188 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) | 1189 if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) |
1189 return TRACE_RETURN (false); | 1190 return TRACE_RETURN (false); |
1190 return TRACE_RETURN (dispatch (c)); | 1191 return TRACE_RETURN (dispatch (c)); |
1191 } | 1192 } |
1192 | 1193 |
1193 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); | 1194 static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_ind
ex); |
1194 inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest
) const | |
1195 { | |
1196 bool ret = false; | |
1197 | |
1198 if (unlikely (!c->buffer->len || !c->lookup_mask)) | |
1199 return false; | |
1200 | |
1201 c->set_recurse_func (apply_recurse_func); | |
1202 c->set_lookup (*this); | |
1203 | |
1204 if (likely (!is_reverse ())) | |
1205 { | |
1206 /* in/out forward substitution */ | |
1207 c->buffer->clear_output (); | |
1208 c->buffer->idx = 0; | |
1209 | |
1210 while (c->buffer->idx < c->buffer->len) | |
1211 { | |
1212 if (digest->may_have (c->buffer->cur().codepoint) && | |
1213 (c->buffer->cur().mask & c->lookup_mask) && | |
1214 apply_once (c)) | |
1215 ret = true; | |
1216 else | |
1217 c->buffer->next_glyph (); | |
1218 } | |
1219 if (ret) | |
1220 c->buffer->swap_buffers (); | |
1221 } | |
1222 else | |
1223 { | |
1224 /* in-place backward substitution */ | |
1225 c->buffer->remove_output (); | |
1226 c->buffer->idx = c->buffer->len - 1; | |
1227 do | |
1228 { | |
1229 if (digest->may_have (c->buffer->cur().codepoint) && | |
1230 (c->buffer->cur().mask & c->lookup_mask) && | |
1231 apply_once (c)) | |
1232 ret = true; | |
1233 else | |
1234 c->buffer->idx--; | |
1235 | |
1236 } | |
1237 while ((int) c->buffer->idx >= 0); | |
1238 } | |
1239 | |
1240 return ret; | |
1241 } | |
1242 | 1195 |
1243 inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, | 1196 inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, |
1244 unsigned int i) | 1197 unsigned int i) |
1245 { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c
, this); } | 1198 { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c
, this); } |
1246 | 1199 |
1247 inline bool serialize_single (hb_serialize_context_t *c, | 1200 inline bool serialize_single (hb_serialize_context_t *c, |
1248 uint32_t lookup_props, | 1201 uint32_t lookup_props, |
1249 Supplier<GlyphID> &glyphs, | 1202 Supplier<GlyphID> &glyphs, |
1250 Supplier<GlyphID> &substitutes, | 1203 Supplier<GlyphID> &substitutes, |
1251 unsigned int num_glyphs) | 1204 unsigned int num_glyphs) |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 }; | 1289 }; |
1337 | 1290 |
1338 typedef OffsetListOf<SubstLookup> SubstLookupList; | 1291 typedef OffsetListOf<SubstLookup> SubstLookupList; |
1339 | 1292 |
1340 /* | 1293 /* |
1341 * GSUB -- The Glyph Substitution Table | 1294 * GSUB -- The Glyph Substitution Table |
1342 */ | 1295 */ |
1343 | 1296 |
1344 struct GSUB : GSUBGPOS | 1297 struct GSUB : GSUBGPOS |
1345 { | 1298 { |
1346 static const hb_tag_t Tag» = HB_OT_TAG_GSUB; | 1299 static const hb_tag_t tableTag» = HB_OT_TAG_GSUB; |
1347 | 1300 |
1348 inline const SubstLookup& get_lookup (unsigned int i) const | 1301 inline const SubstLookup& get_lookup (unsigned int i) const |
1349 { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); } | 1302 { return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); } |
1350 | 1303 |
1351 static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); | 1304 static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); |
1352 static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); | 1305 static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); |
1353 | 1306 |
1354 inline bool sanitize (hb_sanitize_context_t *c) { | 1307 inline bool sanitize (hb_sanitize_context_t *c) { |
1355 TRACE_SANITIZE (this); | 1308 TRACE_SANITIZE (this); |
1356 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); | 1309 if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); |
1357 OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupL
ist); | 1310 OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupL
ist); |
1358 return TRACE_RETURN (list.sanitize (c, this)); | 1311 return TRACE_RETURN (list.sanitize (c, this)); |
1359 } | 1312 } |
1360 public: | 1313 public: |
1361 DEFINE_SIZE_STATIC (10); | 1314 DEFINE_SIZE_STATIC (10); |
1362 }; | 1315 }; |
1363 | 1316 |
1364 | 1317 |
1365 void | 1318 void |
1366 GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) | 1319 GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) |
1367 { | 1320 { |
1368 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props); | 1321 _hb_buffer_allocate_gsubgpos_vars (buffer); |
1369 HB_BUFFER_ALLOCATE_VAR (buffer, lig_props); | |
1370 HB_BUFFER_ALLOCATE_VAR (buffer, syllable); | |
1371 | 1322 |
1372 const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef; | 1323 const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef; |
1373 unsigned int count = buffer->len; | 1324 unsigned int count = buffer->len; |
1374 for (unsigned int i = 0; i < count; i++) { | 1325 for (unsigned int i = 0; i < count; i++) |
1375 buffer->info[i].lig_props() = buffer->info[i].syllable() = 0; | 1326 { |
1376 buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepo
int); | 1327 _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buff
er->info[i].codepoint)); |
| 1328 _hb_glyph_info_clear_lig_props (&buffer->info[i]); |
| 1329 buffer->info[i].syllable() = 0; |
1377 } | 1330 } |
1378 } | 1331 } |
1379 | 1332 |
1380 void | 1333 void |
1381 GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE
D) | 1334 GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE
D) |
1382 { | 1335 { |
1383 } | 1336 } |
1384 | 1337 |
1385 | 1338 |
1386 /* Out-of-class implementation for methods recursing */ | 1339 /* Out-of-class implementation for methods recursing */ |
(...skipping 23 matching lines...) Expand all Loading... |
1410 bool ret = l.apply_once (c); | 1363 bool ret = l.apply_once (c); |
1411 c->lookup_props = saved_lookup_props; | 1364 c->lookup_props = saved_lookup_props; |
1412 return ret; | 1365 return ret; |
1413 } | 1366 } |
1414 | 1367 |
1415 | 1368 |
1416 } /* namespace OT */ | 1369 } /* namespace OT */ |
1417 | 1370 |
1418 | 1371 |
1419 #endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */ | 1372 #endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */ |
OLD | NEW |