| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |