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

Side by Side Diff: third_party/harfbuzz-ng/src/hb-ot-shape.cc

Issue 396393005: Roll HarfBuzz to 0.9.32 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Another cherry-pick Created 6 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright © 2009,2010 Red Hat, Inc. 2 * Copyright © 2009,2010 Red Hat, Inc.
3 * Copyright © 2010,2011,2012 Google, Inc. 3 * Copyright © 2010,2011,2012 Google, Inc.
4 * 4 *
5 * This is part of HarfBuzz, a text shaping library. 5 * This is part of HarfBuzz, a text shaping library.
6 * 6 *
7 * Permission is hereby granted, without written agreement and without 7 * Permission is hereby granted, without written agreement and without
8 * license or royalty fees, to use, copy, modify, and distribute this 8 * license or royalty fees, to use, copy, modify, and distribute this
9 * software and its documentation for any purpose, provided that the 9 * software and its documentation for any purpose, provided that the
10 * above copyright notice and the following two paragraphs appear in 10 * above copyright notice and the following two paragraphs appear in
(...skipping 19 matching lines...) Expand all
30 #define hb_ot_shaper_face_data_t hb_ot_layout_t 30 #define hb_ot_shaper_face_data_t hb_ot_layout_t
31 #define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t 31 #define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
32 #include "hb-shaper-impl-private.hh" 32 #include "hb-shaper-impl-private.hh"
33 33
34 #include "hb-ot-shape-private.hh" 34 #include "hb-ot-shape-private.hh"
35 #include "hb-ot-shape-complex-private.hh" 35 #include "hb-ot-shape-complex-private.hh"
36 #include "hb-ot-shape-fallback-private.hh" 36 #include "hb-ot-shape-fallback-private.hh"
37 #include "hb-ot-shape-normalize-private.hh" 37 #include "hb-ot-shape-normalize-private.hh"
38 38
39 #include "hb-ot-layout-private.hh" 39 #include "hb-ot-layout-private.hh"
40 #include "hb-unicode-private.hh"
40 #include "hb-set-private.hh" 41 #include "hb-set-private.hh"
41 42
42 43
43 static hb_tag_t common_features[] = { 44 static hb_tag_t common_features[] = {
44 HB_TAG('c','c','m','p'), 45 HB_TAG('c','c','m','p'),
45 HB_TAG('l','i','g','a'), 46 HB_TAG('l','i','g','a'),
46 HB_TAG('l','o','c','l'), 47 HB_TAG('l','o','c','l'),
47 HB_TAG('m','a','r','k'), 48 HB_TAG('m','a','r','k'),
48 HB_TAG('m','k','m','k'), 49 HB_TAG('m','k','m','k'),
49 HB_TAG('r','l','i','g'), 50 HB_TAG('r','l','i','g'),
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 220
220 /* Main shaper */ 221 /* Main shaper */
221 222
222 223
223 /* Prepare */ 224 /* Prepare */
224 225
225 static void 226 static void
226 hb_set_unicode_props (hb_buffer_t *buffer) 227 hb_set_unicode_props (hb_buffer_t *buffer)
227 { 228 {
228 unsigned int count = buffer->len; 229 unsigned int count = buffer->len;
230 hb_glyph_info_t *info = buffer->info;
229 for (unsigned int i = 0; i < count; i++) 231 for (unsigned int i = 0; i < count; i++)
230 _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode); 232 _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode);
231 } 233 }
232 234
233 static void 235 static void
234 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) 236 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
235 { 237 {
236 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || 238 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
237 _hb_glyph_info_get_general_category (&buffer->info[0]) != 239 _hb_glyph_info_get_general_category (&buffer->info[0]) !=
238 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 240 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
239 return; 241 return;
240 242
241 if (!font->has_glyph (0x25CC)) 243 if (!font->has_glyph (0x25CCu))
242 return; 244 return;
243 245
244 hb_glyph_info_t dottedcircle; 246 hb_glyph_info_t dottedcircle;
245 dottedcircle.codepoint = 0x25CC; 247 dottedcircle.codepoint = 0x25CCu;
246 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); 248 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
247 249
248 buffer->clear_output (); 250 buffer->clear_output ();
249 251
250 buffer->idx = 0; 252 buffer->idx = 0;
251 hb_glyph_info_t info = dottedcircle; 253 hb_glyph_info_t info = dottedcircle;
252 info.cluster = buffer->cur().cluster; 254 info.cluster = buffer->cur().cluster;
253 info.mask = buffer->cur().mask; 255 info.mask = buffer->cur().mask;
254 buffer->output_info (info); 256 buffer->output_info (info);
255 while (buffer->idx < buffer->len) 257 while (buffer->idx < buffer->len)
256 buffer->next_glyph (); 258 buffer->next_glyph ();
257 259
258 buffer->swap_buffers (); 260 buffer->swap_buffers ();
259 } 261 }
260 262
261 static void 263 static void
262 hb_form_clusters (hb_buffer_t *buffer) 264 hb_form_clusters (hb_buffer_t *buffer)
263 { 265 {
264 unsigned int count = buffer->len; 266 unsigned int count = buffer->len;
267 hb_glyph_info_t *info = buffer->info;
265 for (unsigned int i = 1; i < count; i++) 268 for (unsigned int i = 1; i < count; i++)
266 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i]))) 269 if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
267 buffer->merge_clusters (i - 1, i + 1); 270 buffer->merge_clusters (i - 1, i + 1);
268 } 271 }
269 272
270 static void 273 static void
271 hb_ensure_native_direction (hb_buffer_t *buffer) 274 hb_ensure_native_direction (hb_buffer_t *buffer)
272 { 275 {
273 hb_direction_t direction = buffer->props.direction; 276 hb_direction_t direction = buffer->props.direction;
274 277
275 /* TODO vertical: 278 /* TODO vertical:
276 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope nType 279 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope nType
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 if (!c->plan->has_frac) 317 if (!c->plan->has_frac)
315 return; 318 return;
316 319
317 hb_buffer_t *buffer = c->buffer; 320 hb_buffer_t *buffer = c->buffer;
318 321
319 /* TODO look in pre/post context text also. */ 322 /* TODO look in pre/post context text also. */
320 unsigned int count = buffer->len; 323 unsigned int count = buffer->len;
321 hb_glyph_info_t *info = buffer->info; 324 hb_glyph_info_t *info = buffer->info;
322 for (unsigned int i = 0; i < count; i++) 325 for (unsigned int i = 0; i < count; i++)
323 { 326 {
324 if (info[i].codepoint == 0x2044) /* FRACTION SLASH */ 327 if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
325 { 328 {
326 unsigned int start = i, end = i + 1; 329 unsigned int start = i, end = i + 1;
327 while (start && 330 while (start &&
328 _hb_glyph_info_get_general_category (&info[start - 1]) == 331 _hb_glyph_info_get_general_category (&info[start - 1]) ==
329 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) 332 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
330 start--; 333 start--;
331 while (end < count && 334 while (end < count &&
332 _hb_glyph_info_get_general_category (&info[end]) == 335 _hb_glyph_info_get_general_category (&info[end]) ==
333 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) 336 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
334 end++; 337 end++;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 buffer->set_masks (feature->value << shift, mask, feature->start, feature- >end); 377 buffer->set_masks (feature->value << shift, mask, feature->start, feature- >end);
375 } 378 }
376 } 379 }
377 } 380 }
378 381
379 static inline void 382 static inline void
380 hb_ot_map_glyphs_fast (hb_buffer_t *buffer) 383 hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
381 { 384 {
382 /* Normalization process sets up glyph_index(), we just copy it. */ 385 /* Normalization process sets up glyph_index(), we just copy it. */
383 unsigned int count = buffer->len; 386 unsigned int count = buffer->len;
387 hb_glyph_info_t *info = buffer->info;
384 for (unsigned int i = 0; i < count; i++) 388 for (unsigned int i = 0; i < count; i++)
385 buffer->info[i].codepoint = buffer->info[i].glyph_index(); 389 info[i].codepoint = info[i].glyph_index();
386 } 390 }
387 391
388 static inline void 392 static inline void
389 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) 393 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
390 { 394 {
391 unsigned int count = c->buffer->len; 395 unsigned int count = c->buffer->len;
392 hb_glyph_info_t *info = c->buffer->info; 396 hb_glyph_info_t *info = c->buffer->info;
393 for (unsigned int i = 0; i < count; i++) 397 for (unsigned int i = 0; i < count; i++)
394 _hb_glyph_info_set_glyph_props (&info[i], 398 {
395 » » » » _hb_glyph_info_get_general_category (&info[i ]) 399 hb_ot_layout_glyph_class_mask_t klass;
396 » » » » == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_M ARK ? 400
397 » » » » HB_OT_LAYOUT_GLYPH_PROPS_MARK : 401 /* Never mark default-ignorables as marks.
398 » » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); 402 * They won't get in the way of lookups anyway,
403 * but having them as mark will cause them to be skipped
404 * over if the lookup-flag says so, but at least for the
405 * Mongolian variation selectors, looks like Uniscribe
406 * marks them as non-mark. Some Mongolian fonts without
407 * GDEF rely on this. Another notable character that
408 * this applies to is COMBINING GRAPHEME JOINER. */
409 klass = (_hb_glyph_info_get_general_category (&info[i]) !=
410 » HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
411 » _hb_glyph_info_is_default_ignorable (&info[i])) ?
412 » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
413 » HB_OT_LAYOUT_GLYPH_PROPS_MARK;
414 _hb_glyph_info_set_glyph_props (&info[i], klass);
415 }
399 } 416 }
400 417
401 static inline void 418 static inline void
402 hb_ot_substitute_default (hb_ot_shape_context_t *c) 419 hb_ot_substitute_default (hb_ot_shape_context_t *c)
403 { 420 {
404 hb_buffer_t *buffer = c->buffer; 421 hb_buffer_t *buffer = c->buffer;
405 422
406 if (c->plan->shaper->preprocess_text) 423 if (c->plan->shaper->preprocess_text)
407 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); 424 c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
408 425
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 static inline void 462 static inline void
446 hb_ot_substitute (hb_ot_shape_context_t *c) 463 hb_ot_substitute (hb_ot_shape_context_t *c)
447 { 464 {
448 hb_ot_substitute_default (c); 465 hb_ot_substitute_default (c);
449 hb_ot_substitute_complex (c); 466 hb_ot_substitute_complex (c);
450 } 467 }
451 468
452 /* Position */ 469 /* Position */
453 470
454 static inline void 471 static inline void
455 zero_mark_widths_by_unicode (hb_buffer_t *buffer) 472 adjust_mark_offsets (hb_glyph_position_t *pos)
473 {
474 pos->x_offset -= pos->x_advance;
475 pos->y_offset -= pos->y_advance;
476 }
477
478 static inline void
479 zero_mark_width (hb_glyph_position_t *pos)
480 {
481 pos->x_advance = 0;
482 pos->y_advance = 0;
483 }
484
485 static inline void
486 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
456 { 487 {
457 unsigned int count = buffer->len; 488 unsigned int count = buffer->len;
489 hb_glyph_info_t *info = buffer->info;
458 for (unsigned int i = 0; i < count; i++) 490 for (unsigned int i = 0; i < count; i++)
459 if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GEN ERAL_CATEGORY_NON_SPACING_MARK) 491 if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CAT EGORY_NON_SPACING_MARK)
460 { 492 {
461 buffer->pos[i].x_advance = 0; 493 if (adjust_offsets)
462 buffer->pos[i].y_advance = 0; 494 adjust_mark_offsets (&buffer->pos[i]);
495 zero_mark_width (&buffer->pos[i]);
463 } 496 }
464 } 497 }
465 498
466 static inline void 499 static inline void
467 zero_mark_widths_by_gdef (hb_buffer_t *buffer) 500 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
468 { 501 {
469 unsigned int count = buffer->len; 502 unsigned int count = buffer->len;
503 hb_glyph_info_t *info = buffer->info;
470 for (unsigned int i = 0; i < count; i++) 504 for (unsigned int i = 0; i < count; i++)
471 if (_hb_glyph_info_is_mark (&buffer->info[i])) 505 if (_hb_glyph_info_is_mark (&info[i]))
472 { 506 {
473 buffer->pos[i].x_advance = 0; 507 if (adjust_offsets)
474 buffer->pos[i].y_advance = 0; 508 adjust_mark_offsets (&buffer->pos[i]);
509 zero_mark_width (&buffer->pos[i]);
475 } 510 }
476 } 511 }
477 512
478 static inline void 513 static inline void
479 hb_ot_position_default (hb_ot_shape_context_t *c) 514 hb_ot_position_default (hb_ot_shape_context_t *c)
480 { 515 {
481 hb_direction_t direction = c->buffer->props.direction; 516 hb_direction_t direction = c->buffer->props.direction;
482 unsigned int count = c->buffer->len; 517 unsigned int count = c->buffer->len;
483 hb_glyph_info_t *info = c->buffer->info; 518 hb_glyph_info_t *info = c->buffer->info;
484 hb_glyph_position_t *pos = c->buffer->pos; 519 hb_glyph_position_t *pos = c->buffer->pos;
485 for (unsigned int i = 0; i < count; i++) 520 for (unsigned int i = 0; i < count; i++)
486 { 521 {
487 c->font->get_glyph_advance_for_direction (info[i].codepoint, 522 c->font->get_glyph_advance_for_direction (info[i].codepoint,
488 direction, 523 direction,
489 &pos[i].x_advance, 524 &pos[i].x_advance,
490 &pos[i].y_advance); 525 &pos[i].y_advance);
491 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 526 c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
492 direction, 527 direction,
493 &pos[i].x_offset, 528 &pos[i].x_offset,
494 &pos[i].y_offset); 529 &pos[i].y_offset);
495 530
496 } 531 }
497 } 532 }
498 533
499 static inline bool 534 static inline bool
500 hb_ot_position_complex (hb_ot_shape_context_t *c) 535 hb_ot_position_complex (hb_ot_shape_context_t *c)
501 { 536 {
502 bool ret = false; 537 bool ret = false;
503 unsigned int count = c->buffer->len; 538 unsigned int count = c->buffer->len;
539 bool has_positioning = hb_ot_layout_has_positioning (c->face);
540 /* If the font has no GPOS, AND, no fallback positioning will
541 * happen, AND, direction is forward, then when zeroing mark
542 * widths, we shift the mark with it, such that the mark
543 * is positioned hanging over the previous glyph. When
544 * direction is backward we don't shift and it will end up
545 * hanging over the next glyph after the final reordering.
546 * If fallback positinoing happens or GPOS is present, we don't
547 * care.
548 */
549 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb ack_position ||
550 HB_DIRECTION_IS_BACKWARD (c->buffer->prop s.direction));
504 551
505 switch (c->plan->shaper->zero_width_marks) 552 switch (c->plan->shaper->zero_width_marks)
506 { 553 {
507 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 554 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
508 zero_mark_widths_by_gdef (c->buffer); 555 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
509 break; 556 break;
510 557
511 /* Not currently used for any shaper: 558 /* Not currently used for any shaper:
512 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 559 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
513 zero_mark_widths_by_unicode (c->buffer); 560 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
514 break; 561 break;
515 */ 562 */
516 563
517 default: 564 default:
518 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 565 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
519 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 566 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
520 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 567 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
521 break; 568 break;
522 } 569 }
523 570
524 if (hb_ot_layout_has_positioning (c->face)) 571 if (has_positioning)
525 { 572 {
526 hb_glyph_info_t *info = c->buffer->info; 573 hb_glyph_info_t *info = c->buffer->info;
527 hb_glyph_position_t *pos = c->buffer->pos; 574 hb_glyph_position_t *pos = c->buffer->pos;
528 575
529 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ 576 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
530 577
531 for (unsigned int i = 0; i < count; i++) { 578 for (unsigned int i = 0; i < count; i++) {
532 c->font->add_glyph_origin_for_direction (info[i].codepoint, 579 c->font->add_glyph_origin_for_direction (info[i].codepoint,
533 HB_DIRECTION_LTR, 580 HB_DIRECTION_LTR,
534 &pos[i].x_offset, 581 &pos[i].x_offset,
535 &pos[i].y_offset); 582 &pos[i].y_offset);
536 } 583 }
537 584
538 c->plan->position (c->font, c->buffer); 585 c->plan->position (c->font, c->buffer);
539 586
540 for (unsigned int i = 0; i < count; i++) { 587 for (unsigned int i = 0; i < count; i++) {
541 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 588 c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
542 HB_DIRECTION_LTR, 589 HB_DIRECTION_LTR,
543 &pos[i].x_offset, 590 &pos[i].x_offset,
544 &pos[i].y_offset); 591 &pos[i].y_offset);
545 } 592 }
546 593
547 ret = true; 594 ret = true;
548 } 595 }
549 596
550 switch (c->plan->shaper->zero_width_marks) 597 switch (c->plan->shaper->zero_width_marks)
551 { 598 {
552 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 599 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
553 zero_mark_widths_by_unicode (c->buffer); 600 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
554 break; 601 break;
555 602
556 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 603 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
557 zero_mark_widths_by_gdef (c->buffer); 604 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
558 break; 605 break;
559 606
560 default: 607 default:
561 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 608 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
562 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 609 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
563 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 610 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
564 break; 611 break;
565 } 612 }
566 613
567 return ret; 614 return ret;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 { 771 {
725 hb_ot_shape_plan_t plan; 772 hb_ot_shape_plan_t plan;
726 773
727 const char *shapers[] = {"ot", NULL}; 774 const char *shapers[] = {"ot", NULL};
728 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer ->props, 775 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer ->props,
729 features, num_featu res, shapers); 776 features, num_featu res, shapers);
730 777
731 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_ DIRECTION_RTL; 778 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_ DIRECTION_RTL;
732 779
733 unsigned int count = buffer->len; 780 unsigned int count = buffer->len;
781 hb_glyph_info_t *info = buffer->info;
734 for (unsigned int i = 0; i < count; i++) 782 for (unsigned int i = 0; i < count; i++)
735 add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs); 783 add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
736 784
737 hb_set_t lookups; 785 hb_set_t lookups;
738 lookups.init (); 786 lookups.init ();
739 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups); 787 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
740 788
741 /* And find transitive closure. */ 789 /* And find transitive closure. */
742 hb_set_t copy; 790 hb_set_t copy;
743 copy.init (); 791 copy.init ();
744 do { 792 do {
745 copy.set (glyphs); 793 copy.set (glyphs);
746 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;) 794 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;)
747 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); 795 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
748 } while (!copy.is_equal (glyphs)); 796 } while (!copy.is_equal (glyphs));
749 797
750 hb_shape_plan_destroy (shape_plan); 798 hb_shape_plan_destroy (shape_plan);
751 } 799 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698