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

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

Issue 12438036: Update harfbuzz-ng to 0.9.14 from 0.9.10 (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 static void 76 static void
77 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, 77 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
78 const hb_segment_properties_t *props, 78 const hb_segment_properties_t *props,
79 const hb_feature_t *user_features, 79 const hb_feature_t *user_features,
80 unsigned int num_user_features) 80 unsigned int num_user_features)
81 { 81 {
82 hb_ot_map_builder_t *map = &planner->map; 82 hb_ot_map_builder_t *map = &planner->map;
83 83
84 switch (props->direction) { 84 switch (props->direction) {
85 case HB_DIRECTION_LTR: 85 case HB_DIRECTION_LTR:
86 map->add_bool_feature (HB_TAG ('l','t','r','a')); 86 map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
87 map->add_bool_feature (HB_TAG ('l','t','r','m')); 87 map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
88 break; 88 break;
89 case HB_DIRECTION_RTL: 89 case HB_DIRECTION_RTL:
90 map->add_bool_feature (HB_TAG ('r','t','l','a')); 90 map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
91 map->add_bool_feature (HB_TAG ('r','t','l','m'), false); 91 map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
92 break; 92 break;
93 case HB_DIRECTION_TTB: 93 case HB_DIRECTION_TTB:
94 case HB_DIRECTION_BTT: 94 case HB_DIRECTION_BTT:
95 case HB_DIRECTION_INVALID: 95 case HB_DIRECTION_INVALID:
96 default: 96 default:
97 break; 97 break;
98 } 98 }
99 99
100 #define ADD_FEATURES(array) \
101 HB_STMT_START { \
102 for (unsigned int i = 0; i < ARRAY_LENGTH (array); i++) \
103 map->add_bool_feature (array[i]); \
104 } HB_STMT_END
105
106 if (planner->shaper->collect_features) 100 if (planner->shaper->collect_features)
107 planner->shaper->collect_features (planner); 101 planner->shaper->collect_features (planner);
108 102
109 ADD_FEATURES (common_features); 103 for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
104 map->add_global_bool_feature (common_features[i]);
110 105
111 if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) 106 if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
112 ADD_FEATURES (horizontal_features); 107 for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
108 map->add_feature (horizontal_features[i], 1, F_GLOBAL |
109 » » » (horizontal_features[i] == HB_TAG('k','e','r','n') ?
110 » » » F_HAS_FALLBACK : F_NONE));
113 else 111 else
114 ADD_FEATURES (vertical_features); 112 for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
113 map->add_feature (vertical_features[i], 1, F_GLOBAL |
114 » » » (vertical_features[i] == HB_TAG('v','k','r','n') ?
115 » » » F_HAS_FALLBACK : F_NONE));
115 116
116 if (planner->shaper->override_features) 117 if (planner->shaper->override_features)
117 planner->shaper->override_features (planner); 118 planner->shaper->override_features (planner);
118 119
119 #undef ADD_FEATURES
120
121 for (unsigned int i = 0; i < num_user_features; i++) { 120 for (unsigned int i = 0; i < num_user_features; i++) {
122 const hb_feature_t *feature = &user_features[i]; 121 const hb_feature_t *feature = &user_features[i];
123 map->add_feature (feature->tag, feature->value, (feature->start == 0 && feat ure->end == (unsigned int) -1)); 122 map->add_feature (feature->tag, feature->value,
123 » » (feature->start == 0 && feature->end == (unsigned int) -1) ?
124 » » F_GLOBAL : F_NONE);
124 } 125 }
125 } 126 }
126 127
127 128
128 /* 129 /*
129 * shaper face data 130 * shaper face data
130 */ 131 */
131 132
132 hb_ot_shaper_face_data_t * 133 hb_ot_shaper_face_data_t *
133 _hb_ot_shaper_face_data_create (hb_face_t *face) 134 _hb_ot_shaper_face_data_create (hb_face_t *face)
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 399 }
399 400
400 /* Position */ 401 /* Position */
401 402
402 static inline void 403 static inline void
403 hb_ot_position_default (hb_ot_shape_context_t *c) 404 hb_ot_position_default (hb_ot_shape_context_t *c)
404 { 405 {
405 hb_ot_layout_position_start (c->font, c->buffer); 406 hb_ot_layout_position_start (c->font, c->buffer);
406 407
407 unsigned int count = c->buffer->len; 408 unsigned int count = c->buffer->len;
408 for (unsigned int i = 0; i < count; i++) { 409 for (unsigned int i = 0; i < count; i++)
410 {
409 c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint, 411 c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
410 c->buffer->props.direction, 412 c->buffer->props.direction,
411 &c->buffer->pos[i].x_advance, 413 &c->buffer->pos[i].x_advance,
412 &c->buffer->pos[i].y_advance); 414 &c->buffer->pos[i].y_advance);
413 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint, 415 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
414 c->buffer->props.direction, 416 c->buffer->props.direction,
415 &c->buffer->pos[i].x_offset, 417 &c->buffer->pos[i].x_offset,
416 &c->buffer->pos[i].y_offset); 418 &c->buffer->pos[i].y_offset);
419
420 }
421
422 /* Zero'ing mark widths by GDEF (as used in Myanmar spec) happens
423 * *before* GPOS. */
424 switch (c->plan->shaper->zero_width_marks)
425 {
426 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF:
427 for (unsigned int i = 0; i < count; i++)
428 if ((c->buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
429 {
430 c->buffer->pos[i].x_advance = 0;
431 c->buffer->pos[i].y_advance = 0;
432 }
433 break;
434
435 default:
436 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
437 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE:
438 break;
417 } 439 }
418 } 440 }
419 441
420 static inline bool 442 static inline bool
421 hb_ot_position_complex (hb_ot_shape_context_t *c) 443 hb_ot_position_complex (hb_ot_shape_context_t *c)
422 { 444 {
423 bool ret = false; 445 bool ret = false;
446 unsigned int count = c->buffer->len;
424 447
425 if (hb_ot_layout_has_positioning (c->face)) 448 if (hb_ot_layout_has_positioning (c->face))
426 { 449 {
427 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ 450 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
428 451
429 unsigned int count = c->buffer->len;
430 for (unsigned int i = 0; i < count; i++) { 452 for (unsigned int i = 0; i < count; i++) {
431 c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint, 453 c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
432 HB_DIRECTION_LTR, 454 HB_DIRECTION_LTR,
433 &c->buffer->pos[i].x_offset, 455 &c->buffer->pos[i].x_offset,
434 &c->buffer->pos[i].y_offset); 456 &c->buffer->pos[i].y_offset);
435 } 457 }
436 458
437 c->plan->position (c->font, c->buffer); 459 c->plan->position (c->font, c->buffer);
438 460
439 for (unsigned int i = 0; i < count; i++) { 461 for (unsigned int i = 0; i < count; i++) {
440 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint , 462 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint ,
441 HB_DIRECTION_LTR, 463 HB_DIRECTION_LTR,
442 &c->buffer->pos[i].x_offset, 464 &c->buffer->pos[i].x_offset,
443 &c->buffer->pos[i].y_offset) ; 465 &c->buffer->pos[i].y_offset) ;
444 } 466 }
445 467
446 ret = true; 468 ret = true;
447 } 469 }
448 470
449 hb_ot_layout_position_finish (c->font, c->buffer, c->plan->shaper->zero_width_ attached_marks); 471 /* Zero'ing mark widths by Unicode happens
472 * *after* GPOS. */
473 switch (c->plan->shaper->zero_width_marks)
474 {
475 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE:
476 for (unsigned int i = 0; i < count; i++)
477 » if (_hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNIC ODE_GENERAL_CATEGORY_NON_SPACING_MARK)
478 » {
479 » c->buffer->pos[i].x_advance = 0;
480 » c->buffer->pos[i].y_advance = 0;
481 » }
482 break;
483
484 default:
485 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
486 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF:
487 break;
488 }
489
490 hb_ot_layout_position_finish (c->font, c->buffer);
450 491
451 return ret; 492 return ret;
452 } 493 }
453 494
454 static inline void 495 static inline void
455 hb_ot_truetype_kern (hb_ot_shape_context_t *c)
456 {
457 /* TODO Check for kern=0 */
458 unsigned int count = c->buffer->len;
459 for (unsigned int i = 1; i < count; i++) {
460 hb_position_t x_kern, y_kern, kern1, kern2;
461 c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
462 c->buffer->props.direction,
463 &x_kern, &y_kern);
464
465 kern1 = x_kern >> 1;
466 kern2 = x_kern - kern1;
467 c->buffer->pos[i - 1].x_advance += kern1;
468 c->buffer->pos[i].x_advance += kern2;
469 c->buffer->pos[i].x_offset += kern2;
470
471 kern1 = y_kern >> 1;
472 kern2 = y_kern - kern1;
473 c->buffer->pos[i - 1].y_advance += kern1;
474 c->buffer->pos[i].y_advance += kern2;
475 c->buffer->pos[i].y_offset += kern2;
476 }
477 }
478
479 static inline void
480 hb_ot_position (hb_ot_shape_context_t *c) 496 hb_ot_position (hb_ot_shape_context_t *c)
481 { 497 {
482 hb_ot_position_default (c); 498 hb_ot_position_default (c);
483 499
484 hb_bool_t fallback = !hb_ot_position_complex (c); 500 hb_bool_t fallback = !hb_ot_position_complex (c);
485 501
486 if (fallback && c->plan->shaper->fallback_position) 502 if (fallback && c->plan->shaper->fallback_position)
487 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); 503 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
488 504
489 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) 505 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
490 hb_buffer_reverse (c->buffer); 506 hb_buffer_reverse (c->buffer);
491 507
492 /* Visual fallback goes here. */ 508 /* Visual fallback goes here. */
493 509
494 if (fallback) 510 if (fallback)
495 hb_ot_truetype_kern (c); 511 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
496 } 512 }
497 513
498 514
499 /* Post-process */ 515 /* Post-process */
500 516
501 static void 517 static void
502 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) 518 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
503 { 519 {
504 if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) 520 if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
505 return; 521 return;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 620
605 void 621 void
606 hb_ot_shape_glyphs_closure (hb_font_t *font, 622 hb_ot_shape_glyphs_closure (hb_font_t *font,
607 hb_buffer_t *buffer, 623 hb_buffer_t *buffer,
608 const hb_feature_t *features, 624 const hb_feature_t *features,
609 unsigned int num_features, 625 unsigned int num_features,
610 hb_set_t *glyphs) 626 hb_set_t *glyphs)
611 { 627 {
612 hb_ot_shape_plan_t plan; 628 hb_ot_shape_plan_t plan;
613 629
614 buffer->guess_segment_properties ();
615
616 const char *shapers[] = {"ot", NULL}; 630 const char *shapers[] = {"ot", NULL};
617 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer ->props, 631 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer ->props,
618 features, num_featu res, shapers); 632 features, num_featu res, shapers);
619 633
620 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_ DIRECTION_RTL; 634 bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_ DIRECTION_RTL;
621 635
622 unsigned int count = buffer->len; 636 unsigned int count = buffer->len;
623 for (unsigned int i = 0; i < count; i++) 637 for (unsigned int i = 0; i < count; i++)
624 add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs); 638 add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
625 639
626 hb_set_t lookups; 640 hb_set_t lookups;
627 lookups.init (); 641 lookups.init ();
628 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups); 642 hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
629 643
630 /* And find transitive closure. */ 644 /* And find transitive closure. */
631 hb_set_t copy; 645 hb_set_t copy;
632 copy.init (); 646 copy.init ();
633 do { 647 do {
634 copy.set (glyphs); 648 copy.set (glyphs);
635 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;) 649 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index) ;)
636 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); 650 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
637 } while (!copy.is_equal (glyphs)); 651 } while (!copy.is_equal (glyphs));
638 652
639 hb_shape_plan_destroy (shape_plan); 653 hb_shape_plan_destroy (shape_plan);
640 } 654 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698