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

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

Powered by Google App Engine
This is Rietveld 408576698