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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 | 52 |
53 static hb_tag_t horizontal_features[] = { | 53 static hb_tag_t horizontal_features[] = { |
54 HB_TAG('c','a','l','t'), | 54 HB_TAG('c','a','l','t'), |
55 HB_TAG('c','l','i','g'), | 55 HB_TAG('c','l','i','g'), |
56 HB_TAG('c','u','r','s'), | 56 HB_TAG('c','u','r','s'), |
57 HB_TAG('k','e','r','n'), | 57 HB_TAG('k','e','r','n'), |
58 HB_TAG('r','c','l','t'), | 58 HB_TAG('r','c','l','t'), |
59 }; | 59 }; |
60 | 60 |
61 /* Note: | |
62 * Technically speaking, vrt2 and vert are mutually exclusive. | |
63 * According to the spec, valt and vpal are also mutually exclusive. | |
64 * But we apply them all for now. | |
65 */ | |
66 static hb_tag_t vertical_features[] = { | 61 static hb_tag_t vertical_features[] = { |
67 HB_TAG('v','a','l','t'), | |
68 HB_TAG('v','e','r','t'), | 62 HB_TAG('v','e','r','t'), |
69 HB_TAG('v','k','r','n'), | |
70 HB_TAG('v','p','a','l'), | |
71 HB_TAG('v','r','t','2'), | |
72 }; | 63 }; |
73 | 64 |
74 | 65 |
75 | 66 |
76 static void | 67 static void |
77 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, | 68 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, |
78 const hb_segment_properties_t *props, | 69 const hb_segment_properties_t *props, |
79 const hb_feature_t *user_features, | 70 const hb_feature_t *user_features, |
80 unsigned int num_user_features) | 71 unsigned int num_user_features) |
81 { | 72 { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 283 |
293 | 284 |
294 /* Substitute */ | 285 /* Substitute */ |
295 | 286 |
296 static inline void | 287 static inline void |
297 hb_ot_mirror_chars (hb_ot_shape_context_t *c) | 288 hb_ot_mirror_chars (hb_ot_shape_context_t *c) |
298 { | 289 { |
299 if (HB_DIRECTION_IS_FORWARD (c->target_direction)) | 290 if (HB_DIRECTION_IS_FORWARD (c->target_direction)) |
300 return; | 291 return; |
301 | 292 |
302 hb_unicode_funcs_t *unicode = c->buffer->unicode; | 293 hb_buffer_t *buffer = c->buffer; |
| 294 hb_unicode_funcs_t *unicode = buffer->unicode; |
303 hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m')); | 295 hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m')); |
304 | 296 |
305 unsigned int count = c->buffer->len; | 297 unsigned int count = buffer->len; |
| 298 hb_glyph_info_t *info = buffer->info; |
306 for (unsigned int i = 0; i < count; i++) { | 299 for (unsigned int i = 0; i < count; i++) { |
307 hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint)
; | 300 hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); |
308 if (likely (codepoint == c->buffer->info[i].codepoint)) | 301 if (likely (codepoint == info[i].codepoint)) |
309 c->buffer->info[i].mask |= rtlm_mask; | 302 info[i].mask |= rtlm_mask; |
310 else | 303 else |
311 c->buffer->info[i].codepoint = codepoint; | 304 info[i].codepoint = codepoint; |
312 } | 305 } |
313 } | 306 } |
314 | 307 |
315 static inline void | 308 static inline void |
316 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) | 309 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) |
317 { | 310 { |
318 hb_ot_map_t *map = &c->plan->map; | 311 hb_ot_map_t *map = &c->plan->map; |
| 312 hb_buffer_t *buffer = c->buffer; |
319 | 313 |
320 hb_mask_t global_mask = map->get_global_mask (); | 314 hb_mask_t global_mask = map->get_global_mask (); |
321 c->buffer->reset_masks (global_mask); | 315 buffer->reset_masks (global_mask); |
322 | 316 |
323 if (c->plan->shaper->setup_masks) | 317 if (c->plan->shaper->setup_masks) |
324 c->plan->shaper->setup_masks (c->plan, c->buffer, c->font); | 318 c->plan->shaper->setup_masks (c->plan, buffer, c->font); |
325 | 319 |
326 for (unsigned int i = 0; i < c->num_user_features; i++) | 320 for (unsigned int i = 0; i < c->num_user_features; i++) |
327 { | 321 { |
328 const hb_feature_t *feature = &c->user_features[i]; | 322 const hb_feature_t *feature = &c->user_features[i]; |
329 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { | 323 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { |
330 unsigned int shift; | 324 unsigned int shift; |
331 hb_mask_t mask = map->get_mask (feature->tag, &shift); | 325 hb_mask_t mask = map->get_mask (feature->tag, &shift); |
332 c->buffer->set_masks (feature->value << shift, mask, feature->start, featu
re->end); | 326 buffer->set_masks (feature->value << shift, mask, feature->start, feature-
>end); |
333 } | 327 } |
334 } | 328 } |
335 } | 329 } |
336 | 330 |
337 static inline void | 331 static inline void |
338 hb_ot_map_glyphs_fast (hb_buffer_t *buffer) | 332 hb_ot_map_glyphs_fast (hb_buffer_t *buffer) |
339 { | 333 { |
340 /* Normalization process sets up glyph_index(), we just copy it. */ | 334 /* Normalization process sets up glyph_index(), we just copy it. */ |
341 unsigned int count = buffer->len; | 335 unsigned int count = buffer->len; |
342 for (unsigned int i = 0; i < count; i++) | 336 for (unsigned int i = 0; i < count; i++) |
343 buffer->info[i].codepoint = buffer->info[i].glyph_index(); | 337 buffer->info[i].codepoint = buffer->info[i].glyph_index(); |
344 } | 338 } |
345 | 339 |
346 static inline void | 340 static inline void |
347 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) | 341 hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) |
348 { | 342 { |
349 unsigned int count = c->buffer->len; | 343 unsigned int count = c->buffer->len; |
| 344 hb_glyph_info_t *info = c->buffer->info; |
350 for (unsigned int i = 0; i < count; i++) | 345 for (unsigned int i = 0; i < count; i++) |
351 c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->
buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ? | 346 _hb_glyph_info_set_glyph_props (&info[i], |
352 » » » » HB_OT_LAYOUT_GLYPH_PROPS_MARK : | 347 » » » » _hb_glyph_info_get_general_category (&info[i
]) |
353 » » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH; | 348 » » » » == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_M
ARK ? |
| 349 » » » » HB_OT_LAYOUT_GLYPH_PROPS_MARK : |
| 350 » » » » HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH); |
354 } | 351 } |
355 | 352 |
356 static inline void | 353 static inline void |
357 hb_ot_substitute_default (hb_ot_shape_context_t *c) | 354 hb_ot_substitute_default (hb_ot_shape_context_t *c) |
358 { | 355 { |
| 356 hb_buffer_t *buffer = c->buffer; |
| 357 |
359 if (c->plan->shaper->preprocess_text) | 358 if (c->plan->shaper->preprocess_text) |
360 c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); | 359 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); |
361 | 360 |
362 hb_ot_mirror_chars (c); | 361 hb_ot_mirror_chars (c); |
363 | 362 |
364 HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index); | 363 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); |
365 | 364 |
366 _hb_ot_shape_normalize (c->plan, c->buffer, c->font); | 365 _hb_ot_shape_normalize (c->plan, buffer, c->font); |
367 | 366 |
368 hb_ot_shape_setup_masks (c); | 367 hb_ot_shape_setup_masks (c); |
369 | 368 |
370 /* This is unfortunate to go here, but necessary... */ | 369 /* This is unfortunate to go here, but necessary... */ |
371 if (!hb_ot_layout_has_positioning (c->face)) | 370 if (!hb_ot_layout_has_positioning (c->face)) |
372 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buff
er); | 371 _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer)
; |
373 | 372 |
374 hb_ot_map_glyphs_fast (c->buffer); | 373 hb_ot_map_glyphs_fast (buffer); |
375 | 374 |
376 HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index); | 375 HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index); |
377 } | 376 } |
378 | 377 |
379 static inline void | 378 static inline void |
380 hb_ot_substitute_complex (hb_ot_shape_context_t *c) | 379 hb_ot_substitute_complex (hb_ot_shape_context_t *c) |
381 { | 380 { |
382 hb_ot_layout_substitute_start (c->font, c->buffer); | 381 hb_buffer_t *buffer = c->buffer; |
| 382 |
| 383 hb_ot_layout_substitute_start (c->font, buffer); |
383 | 384 |
384 if (!hb_ot_layout_has_glyph_classes (c->face)) | 385 if (!hb_ot_layout_has_glyph_classes (c->face)) |
385 hb_synthesize_glyph_classes (c); | 386 hb_synthesize_glyph_classes (c); |
386 | 387 |
387 c->plan->substitute (c->font, c->buffer); | 388 c->plan->substitute (c->font, buffer); |
388 | 389 |
389 hb_ot_layout_substitute_finish (c->font, c->buffer); | 390 hb_ot_layout_substitute_finish (c->font, buffer); |
390 | 391 |
391 return; | 392 return; |
392 } | 393 } |
393 | 394 |
394 static inline void | 395 static inline void |
395 hb_ot_substitute (hb_ot_shape_context_t *c) | 396 hb_ot_substitute (hb_ot_shape_context_t *c) |
396 { | 397 { |
397 hb_ot_substitute_default (c); | 398 hb_ot_substitute_default (c); |
398 hb_ot_substitute_complex (c); | 399 hb_ot_substitute_complex (c); |
399 } | 400 } |
(...skipping 10 matching lines...) Expand all Loading... |
410 buffer->pos[i].x_advance = 0; | 411 buffer->pos[i].x_advance = 0; |
411 buffer->pos[i].y_advance = 0; | 412 buffer->pos[i].y_advance = 0; |
412 } | 413 } |
413 } | 414 } |
414 | 415 |
415 static inline void | 416 static inline void |
416 zero_mark_widths_by_gdef (hb_buffer_t *buffer) | 417 zero_mark_widths_by_gdef (hb_buffer_t *buffer) |
417 { | 418 { |
418 unsigned int count = buffer->len; | 419 unsigned int count = buffer->len; |
419 for (unsigned int i = 0; i < count; i++) | 420 for (unsigned int i = 0; i < count; i++) |
420 if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) | 421 if (_hb_glyph_info_is_mark (&buffer->info[i])) |
421 { | 422 { |
422 buffer->pos[i].x_advance = 0; | 423 buffer->pos[i].x_advance = 0; |
423 buffer->pos[i].y_advance = 0; | 424 buffer->pos[i].y_advance = 0; |
424 } | 425 } |
425 } | 426 } |
426 | 427 |
427 static inline void | 428 static inline void |
428 hb_ot_position_default (hb_ot_shape_context_t *c) | 429 hb_ot_position_default (hb_ot_shape_context_t *c) |
429 { | 430 { |
430 hb_ot_layout_position_start (c->font, c->buffer); | 431 hb_direction_t direction = c->buffer->props.direction; |
431 | |
432 unsigned int count = c->buffer->len; | 432 unsigned int count = c->buffer->len; |
| 433 hb_glyph_info_t *info = c->buffer->info; |
| 434 hb_glyph_position_t *pos = c->buffer->pos; |
433 for (unsigned int i = 0; i < count; i++) | 435 for (unsigned int i = 0; i < count; i++) |
434 { | 436 { |
435 c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint, | 437 c->font->get_glyph_advance_for_direction (info[i].codepoint, |
436 » » » » » c->buffer->props.direction, | 438 » » » » » direction, |
437 » » » » » &c->buffer->pos[i].x_advance, | 439 » » » » » &pos[i].x_advance, |
438 » » » » » &c->buffer->pos[i].y_advance); | 440 » » » » » &pos[i].y_advance); |
439 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint, | 441 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, |
440 » » » » » » c->buffer->props.direction, | 442 » » » » » » direction, |
441 » » » » » » &c->buffer->pos[i].x_offset, | 443 » » » » » » &pos[i].x_offset, |
442 » » » » » » &c->buffer->pos[i].y_offset); | 444 » » » » » » &pos[i].y_offset); |
443 | 445 |
444 } | 446 } |
| 447 } |
| 448 |
| 449 static inline bool |
| 450 hb_ot_position_complex (hb_ot_shape_context_t *c) |
| 451 { |
| 452 bool ret = false; |
| 453 unsigned int count = c->buffer->len; |
445 | 454 |
446 switch (c->plan->shaper->zero_width_marks) | 455 switch (c->plan->shaper->zero_width_marks) |
447 { | 456 { |
448 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 457 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
449 zero_mark_widths_by_gdef (c->buffer); | 458 zero_mark_widths_by_gdef (c->buffer); |
450 break; | 459 break; |
451 | 460 |
452 /* Not currently used for any shaper: | 461 /* Not currently used for any shaper: |
453 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | 462 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: |
454 zero_mark_widths_by_unicode (c->buffer); | 463 zero_mark_widths_by_unicode (c->buffer); |
455 break; | 464 break; |
456 */ | 465 */ |
457 | 466 |
458 default: | 467 default: |
459 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 468 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
460 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 469 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
461 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 470 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
462 break; | 471 break; |
463 } | 472 } |
464 } | |
465 | |
466 static inline bool | |
467 hb_ot_position_complex (hb_ot_shape_context_t *c) | |
468 { | |
469 bool ret = false; | |
470 unsigned int count = c->buffer->len; | |
471 | 473 |
472 if (hb_ot_layout_has_positioning (c->face)) | 474 if (hb_ot_layout_has_positioning (c->face)) |
473 { | 475 { |
| 476 hb_glyph_info_t *info = c->buffer->info; |
| 477 hb_glyph_position_t *pos = c->buffer->pos; |
| 478 |
474 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ | 479 /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ |
475 | 480 |
476 for (unsigned int i = 0; i < count; i++) { | 481 for (unsigned int i = 0; i < count; i++) { |
477 c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint, | 482 c->font->add_glyph_origin_for_direction (info[i].codepoint, |
478 HB_DIRECTION_LTR, | 483 HB_DIRECTION_LTR, |
479 » » » » » &c->buffer->pos[i].x_offset, | 484 » » » » » &pos[i].x_offset, |
480 » » » » » &c->buffer->pos[i].y_offset); | 485 » » » » » &pos[i].y_offset); |
481 } | 486 } |
482 | 487 |
483 c->plan->position (c->font, c->buffer); | 488 c->plan->position (c->font, c->buffer); |
484 | 489 |
485 for (unsigned int i = 0; i < count; i++) { | 490 for (unsigned int i = 0; i < count; i++) { |
486 c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint
, | 491 c->font->subtract_glyph_origin_for_direction (info[i].codepoint, |
487 HB_DIRECTION_LTR, | 492 HB_DIRECTION_LTR, |
488 » » » » » » &c->buffer->pos[i].x_offset, | 493 » » » » » » &pos[i].x_offset, |
489 » » » » » » &c->buffer->pos[i].y_offset)
; | 494 » » » » » » &pos[i].y_offset); |
490 } | 495 } |
491 | 496 |
492 ret = true; | 497 ret = true; |
493 } | 498 } |
494 | 499 |
495 switch (c->plan->shaper->zero_width_marks) | 500 switch (c->plan->shaper->zero_width_marks) |
496 { | 501 { |
497 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: | 502 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: |
498 zero_mark_widths_by_unicode (c->buffer); | 503 zero_mark_widths_by_unicode (c->buffer); |
499 break; | 504 break; |
500 | 505 |
501 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: | 506 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: |
502 zero_mark_widths_by_gdef (c->buffer); | 507 zero_mark_widths_by_gdef (c->buffer); |
503 break; | 508 break; |
504 | 509 |
505 default: | 510 default: |
506 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: | 511 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: |
507 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: | 512 //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: |
508 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: | 513 case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: |
509 break; | 514 break; |
510 } | 515 } |
511 | 516 |
512 hb_ot_layout_position_finish (c->font, c->buffer); | |
513 | |
514 return ret; | 517 return ret; |
515 } | 518 } |
516 | 519 |
517 static inline void | 520 static inline void |
518 hb_ot_position (hb_ot_shape_context_t *c) | 521 hb_ot_position (hb_ot_shape_context_t *c) |
519 { | 522 { |
| 523 hb_ot_layout_position_start (c->font, c->buffer); |
| 524 |
520 hb_ot_position_default (c); | 525 hb_ot_position_default (c); |
521 | 526 |
522 hb_bool_t fallback = !hb_ot_position_complex (c); | 527 hb_bool_t fallback = !hb_ot_position_complex (c); |
523 | 528 |
| 529 hb_ot_layout_position_finish (c->font, c->buffer); |
| 530 |
524 if (fallback && c->plan->shaper->fallback_position) | 531 if (fallback && c->plan->shaper->fallback_position) |
525 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); | 532 _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); |
526 | 533 |
527 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) | 534 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) |
528 hb_buffer_reverse (c->buffer); | 535 hb_buffer_reverse (c->buffer); |
529 | 536 |
530 /* Visual fallback goes here. */ | 537 /* Visual fallback goes here. */ |
531 | 538 |
532 if (fallback) | 539 if (fallback) |
533 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); | 540 _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); |
534 } | 541 } |
535 | 542 |
536 | 543 |
537 /* Post-process */ | 544 /* Post-process */ |
538 | 545 |
539 static void | 546 static void |
540 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) | 547 hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) |
541 { | 548 { |
542 if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) | 549 if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) |
543 return; | 550 return; |
544 | 551 |
545 hb_codepoint_t space = 0; | 552 hb_codepoint_t space; |
| 553 enum { |
| 554 SPACE_DONT_KNOW, |
| 555 SPACE_AVAILABLE, |
| 556 SPACE_UNAVAILABLE |
| 557 } space_status = SPACE_DONT_KNOW; |
546 | 558 |
547 unsigned int count = c->buffer->len; | 559 unsigned int count = c->buffer->len; |
| 560 hb_glyph_info_t *info = c->buffer->info; |
| 561 hb_glyph_position_t *pos = c->buffer->pos; |
| 562 unsigned int j = 0; |
548 for (unsigned int i = 0; i < count; i++) | 563 for (unsigned int i = 0; i < count; i++) |
549 if (unlikely (!is_a_ligature (c->buffer->info[i]) && | 564 { |
550 » » _hb_glyph_info_is_default_ignorable (&c->buffer->info[i]))) | 565 if (unlikely (!_hb_glyph_info_ligated (&info[i]) && |
| 566 » » _hb_glyph_info_is_default_ignorable (&info[i]))) |
551 { | 567 { |
552 if (!space) { | 568 if (space_status == SPACE_DONT_KNOW) |
553 /* We assume that the space glyph is not gid0. */ | 569 » space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : S
PACE_UNAVAILABLE; |
554 if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space) | 570 |
555 » return; /* No point! */ | 571 if (space_status == SPACE_AVAILABLE) |
| 572 { |
| 573 » info[i].codepoint = space; |
| 574 » pos[i].x_advance = 0; |
| 575 » pos[i].y_advance = 0; |
556 } | 576 } |
557 c->buffer->info[i].codepoint = space; | 577 else |
558 c->buffer->pos[i].x_advance = 0; | 578 » continue; /* Delete it. */ |
559 c->buffer->pos[i].y_advance = 0; | |
560 } | 579 } |
| 580 if (j != i) |
| 581 { |
| 582 info[j] = info[i]; |
| 583 pos[j] = pos[i]; |
| 584 } |
| 585 j++; |
| 586 } |
| 587 c->buffer->len = j; |
561 } | 588 } |
562 | 589 |
563 | 590 |
564 /* Pull it all together! */ | 591 /* Pull it all together! */ |
565 | 592 |
566 static void | 593 static void |
567 hb_ot_shape_internal (hb_ot_shape_context_t *c) | 594 hb_ot_shape_internal (hb_ot_shape_context_t *c) |
568 { | 595 { |
569 c->buffer->deallocate_var_all (); | 596 c->buffer->deallocate_var_all (); |
570 | 597 |
571 /* Save the original direction, we use it later. */ | 598 /* Save the original direction, we use it later. */ |
572 c->target_direction = c->buffer->props.direction; | 599 c->target_direction = c->buffer->props.direction; |
573 | 600 |
574 HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0); | 601 _hb_buffer_allocate_unicode_vars (c->buffer); |
575 HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1); | |
576 | 602 |
577 c->buffer->clear_output (); | 603 c->buffer->clear_output (); |
578 | 604 |
579 hb_set_unicode_props (c->buffer); | 605 hb_set_unicode_props (c->buffer); |
580 hb_insert_dotted_circle (c->buffer, c->font); | 606 hb_insert_dotted_circle (c->buffer, c->font); |
581 hb_form_clusters (c->buffer); | 607 hb_form_clusters (c->buffer); |
582 | 608 |
583 hb_ensure_native_direction (c->buffer); | 609 hb_ensure_native_direction (c->buffer); |
584 | 610 |
585 hb_ot_substitute (c); | 611 hb_ot_substitute (c); |
586 hb_ot_position (c); | 612 hb_ot_position (c); |
587 | 613 |
588 hb_ot_hide_default_ignorables (c); | 614 hb_ot_hide_default_ignorables (c); |
589 | 615 |
590 HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1); | 616 _hb_buffer_deallocate_unicode_vars (c->buffer); |
591 HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0); | |
592 | 617 |
593 c->buffer->props.direction = c->target_direction; | 618 c->buffer->props.direction = c->target_direction; |
594 | 619 |
595 c->buffer->deallocate_var_all (); | 620 c->buffer->deallocate_var_all (); |
596 } | 621 } |
597 | 622 |
598 | 623 |
599 hb_bool_t | 624 hb_bool_t |
600 _hb_ot_shape (hb_shape_plan_t *shape_plan, | 625 _hb_ot_shape (hb_shape_plan_t *shape_plan, |
601 hb_font_t *font, | 626 hb_font_t *font, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 hb_set_t copy; | 692 hb_set_t copy; |
668 copy.init (); | 693 copy.init (); |
669 do { | 694 do { |
670 copy.set (glyphs); | 695 copy.set (glyphs); |
671 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 696 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
672 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 697 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
673 } while (!copy.is_equal (glyphs)); | 698 } while (!copy.is_equal (glyphs)); |
674 | 699 |
675 hb_shape_plan_destroy (shape_plan); | 700 hb_shape_plan_destroy (shape_plan); |
676 } | 701 } |
OLD | NEW |