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