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

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: 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 232 }
232 233
233 static void 234 static void
234 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) 235 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
235 { 236 {
236 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || 237 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
237 _hb_glyph_info_get_general_category (&buffer->info[0]) != 238 _hb_glyph_info_get_general_category (&buffer->info[0]) !=
238 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) 239 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
239 return; 240 return;
240 241
241 if (!font->has_glyph (0x25CC)) 242 if (!font->has_glyph (0x25CCu))
242 return; 243 return;
243 244
244 hb_glyph_info_t dottedcircle; 245 hb_glyph_info_t dottedcircle;
245 dottedcircle.codepoint = 0x25CC; 246 dottedcircle.codepoint = 0x25CCu;
246 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); 247 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
247 248
248 buffer->clear_output (); 249 buffer->clear_output ();
249 250
250 buffer->idx = 0; 251 buffer->idx = 0;
251 hb_glyph_info_t info = dottedcircle; 252 hb_glyph_info_t info = dottedcircle;
252 info.cluster = buffer->cur().cluster; 253 info.cluster = buffer->cur().cluster;
253 info.mask = buffer->cur().mask; 254 info.mask = buffer->cur().mask;
254 buffer->output_info (info); 255 buffer->output_info (info);
255 while (buffer->idx < buffer->len) 256 while (buffer->idx < buffer->len)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 if (!c->plan->has_frac) 315 if (!c->plan->has_frac)
315 return; 316 return;
316 317
317 hb_buffer_t *buffer = c->buffer; 318 hb_buffer_t *buffer = c->buffer;
318 319
319 /* TODO look in pre/post context text also. */ 320 /* TODO look in pre/post context text also. */
320 unsigned int count = buffer->len; 321 unsigned int count = buffer->len;
321 hb_glyph_info_t *info = buffer->info; 322 hb_glyph_info_t *info = buffer->info;
322 for (unsigned int i = 0; i < count; i++) 323 for (unsigned int i = 0; i < count; i++)
323 { 324 {
324 if (info[i].codepoint == 0x2044) /* FRACTION SLASH */ 325 if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
325 { 326 {
326 unsigned int start = i, end = i + 1; 327 unsigned int start = i, end = i + 1;
327 while (start && 328 while (start &&
328 _hb_glyph_info_get_general_category (&info[start - 1]) == 329 _hb_glyph_info_get_general_category (&info[start - 1]) ==
329 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) 330 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
330 start--; 331 start--;
331 while (end < count && 332 while (end < count &&
332 _hb_glyph_info_get_general_category (&info[end]) == 333 _hb_glyph_info_get_general_category (&info[end]) ==
333 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) 334 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
334 end++; 335 end++;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 for (unsigned int i = 0; i < count; i++) 385 for (unsigned int i = 0; i < count; i++)
385 buffer->info[i].codepoint = buffer->info[i].glyph_index(); 386 buffer->info[i].codepoint = buffer->info[i].glyph_index();
386 } 387 }
387 388
388 static inline void 389 static inline void
389 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) 390 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
390 { 391 {
391 unsigned int count = c->buffer->len; 392 unsigned int count = c->buffer->len;
392 hb_glyph_info_t *info = c->buffer->info; 393 hb_glyph_info_t *info = c->buffer->info;
393 for (unsigned int i = 0; i < count; i++) 394 for (unsigned int i = 0; i < count; i++)
394 _hb_glyph_info_set_glyph_props (&info[i], 395 {
395 » » » » _hb_glyph_info_get_general_category (&info[i ]) 396 hb_ot_layout_glyph_class_mask_t klass;
396 » » » » == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_M ARK ? 397
397 » » » » HB_OT_LAYOUT_GLYPH_PROPS_MARK : 398 /* Never mark default-ignorables as marks.
398 » » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); 399 * They won't get in the way of lookups anyway,
400 * but having them as mark will cause them to be skipped
401 * over if the lookup-flag says so, but at least for the
402 * Mongolian variation selectors, looks like Uniscribe
403 * marks them as non-mark. Some Mongolian fonts without
404 * GDEF rely on this. Another notable character that
405 * this applies to is COMBINING GRAPHEME JOINER. */
406 klass = (_hb_glyph_info_get_general_category (&info[i]) !=
407 » HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
408 » _hb_glyph_info_is_default_ignorable (&info[i])) ?
409 » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
410 » HB_OT_LAYOUT_GLYPH_PROPS_MARK;
411 _hb_glyph_info_set_glyph_props (&info[i], klass);
412 }
399 } 413 }
400 414
401 static inline void 415 static inline void
402 hb_ot_substitute_default (hb_ot_shape_context_t *c) 416 hb_ot_substitute_default (hb_ot_shape_context_t *c)
403 { 417 {
404 hb_buffer_t *buffer = c->buffer; 418 hb_buffer_t *buffer = c->buffer;
405 419
406 if (c->plan->shaper->preprocess_text) 420 if (c->plan->shaper->preprocess_text)
407 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); 421 c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
408 422
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 static inline void 459 static inline void
446 hb_ot_substitute (hb_ot_shape_context_t *c) 460 hb_ot_substitute (hb_ot_shape_context_t *c)
447 { 461 {
448 hb_ot_substitute_default (c); 462 hb_ot_substitute_default (c);
449 hb_ot_substitute_complex (c); 463 hb_ot_substitute_complex (c);
450 } 464 }
451 465
452 /* Position */ 466 /* Position */
453 467
454 static inline void 468 static inline void
455 zero_mark_widths_by_unicode (hb_buffer_t *buffer) 469 adjust_mark_offsets (hb_glyph_position_t *pos)
470 {
471 pos->x_offset -= pos->x_advance;
472 pos->y_offset -= pos->y_advance;
473 }
474
475 static inline void
476 zero_mark_width (hb_glyph_position_t *pos)
477 {
478 pos->x_advance = 0;
479 pos->y_advance = 0;
480 }
481
482 static inline void
483 zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
456 { 484 {
457 unsigned int count = buffer->len; 485 unsigned int count = buffer->len;
458 for (unsigned int i = 0; i < count; i++) 486 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) 487 if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GEN ERAL_CATEGORY_NON_SPACING_MARK)
460 { 488 {
461 buffer->pos[i].x_advance = 0; 489 if (adjust_offsets)
462 buffer->pos[i].y_advance = 0; 490 adjust_mark_offsets (&buffer->pos[i]);
491 zero_mark_width (&buffer->pos[i]);
463 } 492 }
464 } 493 }
465 494
466 static inline void 495 static inline void
467 zero_mark_widths_by_gdef (hb_buffer_t *buffer) 496 zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
468 { 497 {
469 unsigned int count = buffer->len; 498 unsigned int count = buffer->len;
470 for (unsigned int i = 0; i < count; i++) 499 for (unsigned int i = 0; i < count; i++)
471 if (_hb_glyph_info_is_mark (&buffer->info[i])) 500 if (_hb_glyph_info_is_mark (&buffer->info[i]))
472 { 501 {
473 buffer->pos[i].x_advance = 0; 502 if (adjust_offsets)
474 buffer->pos[i].y_advance = 0; 503 adjust_mark_offsets (&buffer->pos[i]);
504 zero_mark_width (&buffer->pos[i]);
475 } 505 }
476 } 506 }
477 507
478 static inline void 508 static inline void
479 hb_ot_position_default (hb_ot_shape_context_t *c) 509 hb_ot_position_default (hb_ot_shape_context_t *c)
480 { 510 {
481 hb_direction_t direction = c->buffer->props.direction; 511 hb_direction_t direction = c->buffer->props.direction;
482 unsigned int count = c->buffer->len; 512 unsigned int count = c->buffer->len;
483 hb_glyph_info_t *info = c->buffer->info; 513 hb_glyph_info_t *info = c->buffer->info;
484 hb_glyph_position_t *pos = c->buffer->pos; 514 hb_glyph_position_t *pos = c->buffer->pos;
485 for (unsigned int i = 0; i < count; i++) 515 for (unsigned int i = 0; i < count; i++)
486 { 516 {
487 c->font->get_glyph_advance_for_direction (info[i].codepoint, 517 c->font->get_glyph_advance_for_direction (info[i].codepoint,
488 direction, 518 direction,
489 &pos[i].x_advance, 519 &pos[i].x_advance,
490 &pos[i].y_advance); 520 &pos[i].y_advance);
491 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 521 c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
492 direction, 522 direction,
493 &pos[i].x_offset, 523 &pos[i].x_offset,
494 &pos[i].y_offset); 524 &pos[i].y_offset);
495 525
496 } 526 }
497 } 527 }
498 528
499 static inline bool 529 static inline bool
500 hb_ot_position_complex (hb_ot_shape_context_t *c) 530 hb_ot_position_complex (hb_ot_shape_context_t *c)
501 { 531 {
502 bool ret = false; 532 bool ret = false;
503 unsigned int count = c->buffer->len; 533 unsigned int count = c->buffer->len;
534 bool has_positioning = hb_ot_layout_has_positioning (c->face);
535 /* If the font has no GPOS, AND, no fallback positioning will
536 * happen, AND, direction is forward, then when zeroing mark
537 * widths, we shift the mark with it, such that the mark
538 * is positioned hanging over the previous glyph. When
539 * direction is backward we don't shift and it will end up
540 * hanging over the next glyph after the final reordering.
541 * If fallback positinoing happens or GPOS is present, we don't
542 * care.
543 */
544 bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallb ack_position ||
545 HB_DIRECTION_IS_BACKWARD (c->buffer->prop s.direction));
504 546
505 switch (c->plan->shaper->zero_width_marks) 547 switch (c->plan->shaper->zero_width_marks)
506 { 548 {
507 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 549 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
508 zero_mark_widths_by_gdef (c->buffer); 550 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
509 break; 551 break;
510 552
511 /* Not currently used for any shaper: 553 /* Not currently used for any shaper:
512 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 554 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
513 zero_mark_widths_by_unicode (c->buffer); 555 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
514 break; 556 break;
515 */ 557 */
516 558
517 default: 559 default:
518 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 560 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
519 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 561 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
520 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 562 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
521 break; 563 break;
522 } 564 }
523 565
524 if (hb_ot_layout_has_positioning (c->face)) 566 if (has_positioning)
525 { 567 {
526 hb_glyph_info_t *info = c->buffer->info; 568 hb_glyph_info_t *info = c->buffer->info;
527 hb_glyph_position_t *pos = c->buffer->pos; 569 hb_glyph_position_t *pos = c->buffer->pos;
528 570
529 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ 571 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
530 572
531 for (unsigned int i = 0; i < count; i++) { 573 for (unsigned int i = 0; i < count; i++) {
532 c->font->add_glyph_origin_for_direction (info[i].codepoint, 574 c->font->add_glyph_origin_for_direction (info[i].codepoint,
533 HB_DIRECTION_LTR, 575 HB_DIRECTION_LTR,
534 &pos[i].x_offset, 576 &pos[i].x_offset,
535 &pos[i].y_offset); 577 &pos[i].y_offset);
536 } 578 }
537 579
538 c->plan->position (c->font, c->buffer); 580 c->plan->position (c->font, c->buffer);
539 581
540 for (unsigned int i = 0; i < count; i++) { 582 for (unsigned int i = 0; i < count; i++) {
541 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, 583 c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
542 HB_DIRECTION_LTR, 584 HB_DIRECTION_LTR,
543 &pos[i].x_offset, 585 &pos[i].x_offset,
544 &pos[i].y_offset); 586 &pos[i].y_offset);
545 } 587 }
546 588
547 ret = true; 589 ret = true;
548 } 590 }
549 591
550 switch (c->plan->shaper->zero_width_marks) 592 switch (c->plan->shaper->zero_width_marks)
551 { 593 {
552 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: 594 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
553 zero_mark_widths_by_unicode (c->buffer); 595 zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
554 break; 596 break;
555 597
556 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: 598 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
557 zero_mark_widths_by_gdef (c->buffer); 599 zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
558 break; 600 break;
559 601
560 default: 602 default:
561 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: 603 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
562 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: 604 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
563 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: 605 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
564 break; 606 break;
565 } 607 }
566 608
567 return ret; 609 return ret;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 hb_set_t copy; 784 hb_set_t copy;
743 copy.init (); 785 copy.init ();
744 do { 786 do {
745 copy.set (glyphs); 787 copy.set (glyphs);
746 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;) 788 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); 789 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
748 } while (!copy.is_equal (glyphs)); 790 } while (!copy.is_equal (glyphs));
749 791
750 hb_shape_plan_destroy (shape_plan); 792 hb_shape_plan_destroy (shape_plan);
751 } 793 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698