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

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

Issue 1476763003: Roll HarfBuzz to 1.1.1 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: windows line height rebaseline Created 5 years 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 © 2010,2012 Google, Inc. 2 * Copyright © 2010,2012 Google, Inc.
3 * 3 *
4 * This is part of HarfBuzz, a text shaping library. 4 * This is part of HarfBuzz, a text shaping library.
5 * 5 *
6 * Permission is hereby granted, without written agreement and without 6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this 7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the 8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in 9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software. 10 * all copies of this software.
(...skipping 10 matching lines...) Expand all
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 * 23 *
24 * Google Author(s): Behdad Esfahbod 24 * Google Author(s): Behdad Esfahbod
25 */ 25 */
26 26
27 #include "hb-ot-shape-complex-arabic-private.hh" 27 #include "hb-ot-shape-complex-arabic-private.hh"
28 #include "hb-ot-shape-private.hh" 28 #include "hb-ot-shape-private.hh"
29 29
30 30
31 #ifndef HB_DEBUG_ARABIC
32 #define HB_DEBUG_ARABIC (HB_DEBUG+0)
33 #endif
34
35
31 /* buffer var allocations */ 36 /* buffer var allocations */
32 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ 37 #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
33 38
39 #define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0
40
41 /* See:
42 * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff5 7823d#commitcomment-14248516 */
43 #define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \
44 (FLAG_SAFE (gen_cat) & \
45 (FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \
46 FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \
47 /*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \
48 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \
49 FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \
50 /*FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |*/ \
51 /*FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |*/ \
52 FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
53 FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
54 FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
55 FLAG (HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | \
56 FLAG (HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER) | \
57 FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER) | \
58 FLAG (HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL) | \
59 FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL) | \
60 FLAG (HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL) | \
61 FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL)))
62
34 63
35 /* 64 /*
36 * Joining types: 65 * Joining types:
37 */ 66 */
38 67
39 /* 68 /*
40 * Bits used in the joining tables 69 * Bits used in the joining tables
41 */ 70 */
42 enum hb_arabic_joining_type_t { 71 enum hb_arabic_joining_type_t {
43 JOINING_TYPE_U = 0, 72 JOINING_TYPE_U = 0,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 HB_TAG('f','i','n','2'), 106 HB_TAG('f','i','n','2'),
78 HB_TAG('f','i','n','3'), 107 HB_TAG('f','i','n','3'),
79 HB_TAG('m','e','d','i'), 108 HB_TAG('m','e','d','i'),
80 HB_TAG('m','e','d','2'), 109 HB_TAG('m','e','d','2'),
81 HB_TAG('i','n','i','t'), 110 HB_TAG('i','n','i','t'),
82 HB_TAG_NONE 111 HB_TAG_NONE
83 }; 112 };
84 113
85 114
86 /* Same order as the feature array */ 115 /* Same order as the feature array */
87 enum { 116 enum arabic_action_t {
88 ISOL, 117 ISOL,
89 FINA, 118 FINA,
90 FIN2, 119 FIN2,
91 FIN3, 120 FIN3,
92 MEDI, 121 MEDI,
93 MED2, 122 MED2,
94 INIT, 123 INIT,
95 124
96 NONE, 125 NONE,
97 126
98 ARABIC_NUM_FEATURES = NONE 127 ARABIC_NUM_FEATURES = NONE,
128
129 /* We abuse the same byte for other things... */
130 STCH_FIXED,
131 STCH_REPEATING,
99 }; 132 };
100 133
101 static const struct arabic_state_table_entry { 134 static const struct arabic_state_table_entry {
102 uint8_t prev_action; 135 uint8_t prev_action;
103 uint8_t curr_action; 136 uint8_t curr_action;
104 uint16_t next_state; 137 uint16_t next_state;
105 } arabic_state_table[][NUM_STATE_MACHINE_COLS] = 138 } arabic_state_table[][NUM_STATE_MACHINE_COLS] =
106 { 139 {
107 /* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */ 140 /* jt_U, jt_L, jt_R, jt_D, jg_ALAPH, jg_DALATH_RISH */
108 141
(...skipping 24 matching lines...) Expand all
133 nuke_joiners (const hb_ot_shape_plan_t *plan, 166 nuke_joiners (const hb_ot_shape_plan_t *plan,
134 hb_font_t *font, 167 hb_font_t *font,
135 hb_buffer_t *buffer); 168 hb_buffer_t *buffer);
136 169
137 static void 170 static void
138 arabic_fallback_shape (const hb_ot_shape_plan_t *plan, 171 arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
139 hb_font_t *font, 172 hb_font_t *font,
140 hb_buffer_t *buffer); 173 hb_buffer_t *buffer);
141 174
142 static void 175 static void
176 record_stch (const hb_ot_shape_plan_t *plan,
177 hb_font_t *font,
178 hb_buffer_t *buffer);
179
180 static void
143 collect_features_arabic (hb_ot_shape_planner_t *plan) 181 collect_features_arabic (hb_ot_shape_planner_t *plan)
144 { 182 {
145 hb_ot_map_builder_t *map = &plan->map; 183 hb_ot_map_builder_t *map = &plan->map;
146 184
147 /* We apply features according to the Arabic spec, with pauses 185 /* We apply features according to the Arabic spec, with pauses
148 * in between most. 186 * in between most.
149 * 187 *
150 * The pause between init/medi/... and rlig is required. See eg: 188 * The pause between init/medi/... and rlig is required. See eg:
151 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184 189 * https://bugzilla.mozilla.org/show_bug.cgi?id=644184
152 * 190 *
153 * The pauses between init/medi/... themselves are not necessarily 191 * The pauses between init/medi/... themselves are not necessarily
154 * needed as only one of those features is applied to any character. 192 * needed as only one of those features is applied to any character.
155 * The only difference it makes is when fonts have contextual 193 * The only difference it makes is when fonts have contextual
156 * substitutions. We now follow the order of the spec, which makes 194 * substitutions. We now follow the order of the spec, which makes
157 * for better experience if that's what Uniscribe is doing. 195 * for better experience if that's what Uniscribe is doing.
158 * 196 *
159 * At least for Arabic, looks like Uniscribe has a pause between 197 * At least for Arabic, looks like Uniscribe has a pause between
160 * rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't 198 * rlig and calt. Otherwise the IranNastaliq's ALLAH ligature won't
161 * work. However, testing shows that rlig and calt are applied 199 * work. However, testing shows that rlig and calt are applied
162 * together for Mongolian in Uniscribe. As such, we only add a 200 * together for Mongolian in Uniscribe. As such, we only add a
163 * pause for Arabic, not other scripts. 201 * pause for Arabic, not other scripts.
164 */ 202 */
165 203
166 map->add_gsub_pause (nuke_joiners); 204 map->add_gsub_pause (nuke_joiners);
167 205
206 map->add_global_bool_feature (HB_TAG('s','t','c','h'));
207 map->add_gsub_pause (record_stch);
208
168 map->add_global_bool_feature (HB_TAG('c','c','m','p')); 209 map->add_global_bool_feature (HB_TAG('c','c','m','p'));
169 map->add_global_bool_feature (HB_TAG('l','o','c','l')); 210 map->add_global_bool_feature (HB_TAG('l','o','c','l'));
170 211
171 map->add_gsub_pause (NULL); 212 map->add_gsub_pause (NULL);
172 213
173 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) 214 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
174 { 215 {
175 bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SY RIAC (arabic_features[i]); 216 bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SY RIAC (arabic_features[i]);
176 map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_N ONE); 217 map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_N ONE);
177 map->add_gsub_pause (NULL); 218 map->add_gsub_pause (NULL);
(...skipping 23 matching lines...) Expand all
201 struct arabic_shape_plan_t 242 struct arabic_shape_plan_t
202 { 243 {
203 ASSERT_POD (); 244 ASSERT_POD ();
204 245
205 /* The "+ 1" in the next array is to accommodate for the "NONE" command, 246 /* The "+ 1" in the next array is to accommodate for the "NONE" command,
206 * which is not an OpenType feature, but this simplifies the code by not 247 * which is not an OpenType feature, but this simplifies the code by not
207 * having to do a "if (... < NONE) ..." and just rely on the fact that 248 * having to do a "if (... < NONE) ..." and just rely on the fact that
208 * mask_array[NONE] == 0. */ 249 * mask_array[NONE] == 0. */
209 hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; 250 hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1];
210 251
211 bool do_fallback;
212 arabic_fallback_plan_t *fallback_plan; 252 arabic_fallback_plan_t *fallback_plan;
253
254 unsigned int do_fallback : 1;
255 unsigned int has_stch : 1;
213 }; 256 };
214 257
215 void * 258 void *
216 data_create_arabic (const hb_ot_shape_plan_t *plan) 259 data_create_arabic (const hb_ot_shape_plan_t *plan)
217 { 260 {
218 arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof ( arabic_shape_plan_t)); 261 arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof ( arabic_shape_plan_t));
219 if (unlikely (!arabic_plan)) 262 if (unlikely (!arabic_plan))
220 return NULL; 263 return NULL;
221 264
222 arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC; 265 arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC;
266 arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h'));
223 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { 267 for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) {
224 arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); 268 arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]);
225 arabic_plan->do_fallback = arabic_plan->do_fallback && 269 arabic_plan->do_fallback = arabic_plan->do_fallback &&
226 (FEATURE_IS_SYRIAC (arabic_features[i]) || 270 (FEATURE_IS_SYRIAC (arabic_features[i]) ||
227 plan->map.needs_fallback (arabic_features[i])); 271 plan->map.needs_fallback (arabic_features[i]));
228 } 272 }
229 273
230 return arabic_plan; 274 return arabic_plan;
231 } 275 }
232 276
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); 357 HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
314 358
315 arabic_joining (buffer); 359 arabic_joining (buffer);
316 if (script == HB_SCRIPT_MONGOLIAN) 360 if (script == HB_SCRIPT_MONGOLIAN)
317 mongolian_variation_selectors (buffer); 361 mongolian_variation_selectors (buffer);
318 362
319 unsigned int count = buffer->len; 363 unsigned int count = buffer->len;
320 hb_glyph_info_t *info = buffer->info; 364 hb_glyph_info_t *info = buffer->info;
321 for (unsigned int i = 0; i < count; i++) 365 for (unsigned int i = 0; i < count; i++)
322 info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()]; 366 info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()];
323
324 HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
325 } 367 }
326 368
327 static void 369 static void
328 setup_masks_arabic (const hb_ot_shape_plan_t *plan, 370 setup_masks_arabic (const hb_ot_shape_plan_t *plan,
329 hb_buffer_t *buffer, 371 hb_buffer_t *buffer,
330 hb_font_t *font HB_UNUSED) 372 hb_font_t *font HB_UNUSED)
331 { 373 {
332 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d ata; 374 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d ata;
333 setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); 375 setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script);
334 } 376 }
(...skipping 29 matching lines...) Expand all
364 fallback_plan = arabic_fallback_plan_create (plan, font); 406 fallback_plan = arabic_fallback_plan_create (plan, font);
365 if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (a rabic_plan))->fallback_plan, NULL, fallback_plan))) { 407 if (unlikely (!hb_atomic_ptr_cmpexch (&(const_cast<arabic_shape_plan_t *> (a rabic_plan))->fallback_plan, NULL, fallback_plan))) {
366 arabic_fallback_plan_destroy (fallback_plan); 408 arabic_fallback_plan_destroy (fallback_plan);
367 goto retry; 409 goto retry;
368 } 410 }
369 } 411 }
370 412
371 arabic_fallback_plan_shape (fallback_plan, font, buffer); 413 arabic_fallback_plan_shape (fallback_plan, font, buffer);
372 } 414 }
373 415
416 /*
417 * Stretch feature: "stch".
418 * See example here:
419 * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm
420 * We implement this in a generic way, such that the Arabic subtending
421 * marks can use it as well.
422 */
423
424 static void
425 record_stch (const hb_ot_shape_plan_t *plan,
426 hb_font_t *font,
427 hb_buffer_t *buffer)
428 {
429 const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->d ata;
430 if (!arabic_plan->has_stch)
431 return;
432
433 /* 'stch' feature was just applied. Look for anything that multiplied,
434 * and record it for stch treatment later. Note that rtlm, frac, etc
435 * are applied before stch, but we assume that they didn't result in
436 * anything multiplying into 5 pieces, so it's safe-ish... */
437
438 unsigned int count = buffer->len;
439 hb_glyph_info_t *info = buffer->info;
440 for (unsigned int i = 0; i < count; i++)
441 if (unlikely (_hb_glyph_info_multiplied (&info[i])))
442 {
443 unsigned int comp = _hb_glyph_info_get_lig_comp (&info[i]);
444 info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED;
445 buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH;
446 }
447 }
448
449 static void
450 apply_stch (const hb_ot_shape_plan_t *plan,
451 hb_buffer_t *buffer,
452 hb_font_t *font)
453 {
454 if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)) )
455 return;
456
457 /* The Arabic shaper currently always processes in RTL mode, so we should
458 * stretch / position the stretched pieces to the left / preceding glyphs. */
459
460 /* We do a two pass implementation:
461 * First pass calculates the exact number of extra glyphs we need,
462 * We then enlarge buffer to have that much room,
463 * Second pass applies the stretch, copying things to the end of buffer.
464 */
465
466 /* 30 = 2048 / 70.
467 * https://www.microsoft.com/typography/cursivescriptguidelines.mspx */
468 hb_position_t overlap = font->x_scale / 30;
469 DEBUG_MSG (ARABIC, NULL, "overlap for stretching is %d", overlap);
470 int sign = font->x_scale < 0 ? -1 : +1;
471 unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT
472 typedef enum { MEASURE, CUT } step_t;
473
474 for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1))
475 {
476 unsigned int count = buffer->len;
477 hb_glyph_info_t *info = buffer->info;
478 hb_glyph_position_t *pos = buffer->pos;
479 unsigned int new_len = count + extra_glyphs_needed; // write head during CUT
480 unsigned int j = new_len;
481 for (unsigned int i = count; i; i--)
482 {
483 if (!hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXE D, STCH_REPEATING))
484 {
485 if (step == CUT)
486 {
487 --j;
488 info[j] = info[i - 1];
489 pos[j] = pos[i - 1];
490 }
491 continue;
492 }
493
494 /* Yay, justification! */
495
496 hb_position_t w_total = 0; // Total to be filled
497 hb_position_t w_fixed = 0; // Sum of fixed tiles
498 hb_position_t w_repeating = 0; // Sum of repeating tiles
499 int n_fixed = 0;
500 int n_repeating = 0;
501
502 unsigned int end = i;
503 while (i &&
504 hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FI XED, STCH_REPEATING))
505 {
506 i--;
507 hb_glyph_extents_t extents;
508 if (!font->get_glyph_extents (info[i].codepoint, &extents))
509 extents.width = 0;
510 extents.width -= overlap;
511 if (info[i].arabic_shaping_action() == STCH_FIXED)
512 {
513 w_fixed += extents.width;
514 n_fixed++;
515 }
516 else
517 {
518 w_repeating += extents.width;
519 n_repeating++;
520 }
521 }
522 unsigned int start = i;
523 unsigned int context = i;
524 while (context &&
525 !hb_in_range<unsigned> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) &&
526 (_hb_glyph_info_is_default_ignorable (&info[context - 1]) ||
527 HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_cat egory (&info[context - 1]))))
528 {
529 context--;
530 w_total += pos[context].x_advance;
531 }
532 i++; // Don't touch i again.
533
534 DEBUG_MSG (ARABIC, NULL, "%s stretch at (%d,%d,%d)",
535 step == MEASURE ? "measuring" : "cutting", context, start, end) ;
536 DEBUG_MSG (ARABIC, NULL, "rest of word: count=%d width %d", start - con text, w_total);
537 DEBUG_MSG (ARABIC, NULL, "fixed tiles: count=%d width=%d", n_fixed, w_ fixed);
538 DEBUG_MSG (ARABIC, NULL, "repeating tiles: count=%d width=%d", n_repeating , w_repeating);
539
540 /* Number of additional times to repeat each repeating tile. */
541 int n_copies = 0;
542
543 hb_position_t w_remaining = w_total - w_fixed - overlap;
544 if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0)
545 n_copies = (sign * w_remaining + sign * w_repeating / 4) / (sign * w_rep eating) - 1;
546
547 if (step == MEASURE)
548 {
549 extra_glyphs_needed += n_copies * n_repeating;
550 DEBUG_MSG (ARABIC, NULL, "will add extra %d copies of repeating tiles", n_copies);
551 }
552 else
553 {
554 hb_position_t x_offset = -overlap;
555 for (unsigned int k = end; k > start; k--)
556 {
557 hb_glyph_extents_t extents;
558 if (!font->get_glyph_extents (info[k - 1].codepoint, &extents))
559 extents.width = 0;
560 extents.width -= overlap;
561
562 unsigned int repeat = 1;
563 if (info[k - 1].arabic_shaping_action() == STCH_REPEATING)
564 repeat += n_copies;
565
566 DEBUG_MSG (ARABIC, NULL, "appending %d copies of glyph %d; j=%d",
567 repeat, info[k - 1].codepoint, j);
568 for (unsigned int n = 0; n < repeat; n++)
569 {
570 x_offset -= extents.width;
571 pos[k - 1].x_offset = x_offset;
572 /* Append copy. */
573 --j;
574 info[j] = info[k - 1];
575 pos[j] = pos[k - 1];
576 }
577 }
578 }
579 }
580
581 if (step == MEASURE)
582 {
583 if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
584 break;
585 }
586 else
587 {
588 assert (j == 0);
589 buffer->len = new_len;
590 }
591 }
592 }
593
594
595 static void
596 postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
597 hb_buffer_t *buffer,
598 hb_font_t *font)
599 {
600 apply_stch (plan, buffer, font);
601
602 HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
603 }
374 604
375 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = 605 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
376 { 606 {
377 "arabic", 607 "arabic",
378 collect_features_arabic, 608 collect_features_arabic,
379 NULL, /* override_features */ 609 NULL, /* override_features */
380 data_create_arabic, 610 data_create_arabic,
381 data_destroy_arabic, 611 data_destroy_arabic,
382 NULL, /* preprocess_text_arabic */ 612 NULL, /* preprocess_text */
613 postprocess_glyphs_arabic,
383 HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, 614 HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
384 NULL, /* decompose */ 615 NULL, /* decompose */
385 NULL, /* compose */ 616 NULL, /* compose */
386 setup_masks_arabic, 617 setup_masks_arabic,
387 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, 618 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
388 true, /* fallback_position */ 619 true, /* fallback_position */
389 }; 620 };
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-shape.cc ('k') | third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698