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

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

Issue 10510004: Roll harfbuzz-ng 3b8fd9c48f4bde368bf2d465c148b9743a9216ee (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 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 Google, Inc. 3 * Copyright © 2010,2011 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
11 * all copies of this software. 11 * all copies of this software.
12 * 12 *
13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17 * DAMAGE. 17 * DAMAGE.
18 * 18 *
19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
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 #include "hb-ot-shape-private.hh" 29 #include "hb-ot-shape-private.hh"
30 #include "hb-ot-shape-complex-private.hh" 30 #include "hb-ot-shape-normalize-private.hh"
31 31
32 #include "hb-font-private.hh" 32 #include "hb-font-private.hh"
33 #include "hb-set-private.hh"
33 34
34 35
35 36
36 hb_tag_t common_features[] = { 37 hb_tag_t common_features[] = {
37 HB_TAG('c','c','m','p'), 38 HB_TAG('c','c','m','p'),
39 HB_TAG('l','i','g','a'),
38 HB_TAG('l','o','c','l'), 40 HB_TAG('l','o','c','l'),
39 HB_TAG('m','a','r','k'), 41 HB_TAG('m','a','r','k'),
40 HB_TAG('m','k','m','k'), 42 HB_TAG('m','k','m','k'),
41 HB_TAG('r','l','i','g'), 43 HB_TAG('r','l','i','g'),
42 }; 44 };
43 45
46
44 hb_tag_t horizontal_features[] = { 47 hb_tag_t horizontal_features[] = {
45 HB_TAG('c','a','l','t'), 48 HB_TAG('c','a','l','t'),
46 HB_TAG('c','l','i','g'), 49 HB_TAG('c','l','i','g'),
47 HB_TAG('c','u','r','s'), 50 HB_TAG('c','u','r','s'),
48 HB_TAG('k','e','r','n'), 51 HB_TAG('k','e','r','n'),
49 HB_TAG('l','i','g','a'),
50 }; 52 };
51 53
52 /* Note: 54 /* Note:
53 * Technically speaking, vrt2 and vert are mutually exclusive. 55 * Technically speaking, vrt2 and vert are mutually exclusive.
54 * According to the spec, valt and vpal are also mutually exclusive. 56 * According to the spec, valt and vpal are also mutually exclusive.
55 * But we apply them all for now. 57 * But we apply them all for now.
56 */ 58 */
57 hb_tag_t vertical_features[] = { 59 hb_tag_t vertical_features[] = {
58 HB_TAG('v','a','l','t'), 60 HB_TAG('v','a','l','t'),
59 HB_TAG('v','e','r','t'), 61 HB_TAG('v','e','r','t'),
60 HB_TAG('v','k','r','n'), 62 HB_TAG('v','k','r','n'),
61 HB_TAG('v','p','a','l'), 63 HB_TAG('v','p','a','l'),
62 HB_TAG('v','r','t','2'), 64 HB_TAG('v','r','t','2'),
63 }; 65 };
64 66
67
68
69 struct hb_ot_shape_planner_t
70 {
71 hb_ot_map_builder_t map;
72 hb_ot_complex_shaper_t shaper;
73
74 hb_ot_shape_planner_t (void) : map () {}
75 ~hb_ot_shape_planner_t (void) { map.finish (); }
76
77 inline void compile (hb_face_t *face,
78 const hb_segment_properties_t *props,
79 struct hb_ot_shape_plan_t &plan)
80 {
81 plan.shaper = shaper;
82 map.compile (face, props, plan.map);
83 }
84
85 private:
86 NO_COPY (hb_ot_shape_planner_t);
87 };
88
65 static void 89 static void
66 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, 90 hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
67 const hb_segment_properties_t *props, 91 const hb_segment_properties_t *props,
68 const hb_feature_t *user_features, 92 const hb_feature_t *user_features,
69 unsigned int num_user_features) 93 unsigned int num_user_features)
70 { 94 {
71 switch (props->direction) { 95 switch (props->direction) {
72 case HB_DIRECTION_LTR: 96 case HB_DIRECTION_LTR:
73 planner->map.add_bool_feature (HB_TAG ('l','t','r','a')); 97 planner->map.add_bool_feature (HB_TAG ('l','t','r','a'));
74 planner->map.add_bool_feature (HB_TAG ('l','t','r','m')); 98 planner->map.add_bool_feature (HB_TAG ('l','t','r','m'));
(...skipping 26 matching lines...) Expand all
101 125
102 #undef ADD_FEATURES 126 #undef ADD_FEATURES
103 127
104 for (unsigned int i = 0; i < num_user_features; i++) { 128 for (unsigned int i = 0; i < num_user_features; i++) {
105 const hb_feature_t *feature = &user_features[i]; 129 const hb_feature_t *feature = &user_features[i];
106 planner->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1)); 130 planner->map.add_feature (feature->tag, feature->value, (feature->start == 0 && feature->end == (unsigned int) -1));
107 } 131 }
108 } 132 }
109 133
110 134
135 struct hb_ot_shape_context_t
136 {
137 /* Input to hb_ot_shape_execute() */
138 hb_ot_shape_plan_t *plan;
139 hb_font_t *font;
140 hb_face_t *face;
141 hb_buffer_t *buffer;
142 const hb_feature_t *user_features;
143 unsigned int num_user_features;
144
145 /* Transient stuff */
146 hb_direction_t target_direction;
147 hb_bool_t applied_position_complex;
148 };
149
111 static void 150 static void
112 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) 151 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
113 { 152 {
114 hb_mask_t global_mask = c->plan->map.get_global_mask (); 153 hb_mask_t global_mask = c->plan->map.get_global_mask ();
115 c->buffer->reset_masks (global_mask); 154 c->buffer->reset_masks (global_mask);
116 155
117 hb_ot_shape_complex_setup_masks (c->plan->shaper, &c->plan->map, c->buffer); 156 hb_ot_shape_complex_setup_masks (c->plan->shaper, &c->plan->map, c->buffer, c- >font);
118 157
119 for (unsigned int i = 0; i < c->num_user_features; i++) 158 for (unsigned int i = 0; i < c->num_user_features; i++)
120 { 159 {
121 const hb_feature_t *feature = &c->user_features[i]; 160 const hb_feature_t *feature = &c->user_features[i];
122 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { 161 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
123 unsigned int shift; 162 unsigned int shift;
124 hb_mask_t mask = c->plan->map.get_mask (feature->tag, &shift); 163 hb_mask_t mask = c->plan->map.get_mask (feature->tag, &shift);
125 c->buffer->set_masks (feature->value << shift, mask, feature->start, featu re->end); 164 c->buffer->set_masks (feature->value << shift, mask, feature->start, featu re->end);
126 } 165 }
127 } 166 }
128 } 167 }
129 168
130 169
131 /* Main shaper */ 170 /* Main shaper */
132 171
133 /* Prepare */ 172 /* Prepare */
134 173
135 void 174 static void
136 _hb_set_unicode_props (hb_buffer_t *buffer) 175 hb_set_unicode_props (hb_buffer_t *buffer)
137 { 176 {
138 unsigned int count = buffer->len; 177 unsigned int count = buffer->len;
139 for (unsigned int i = 1; i < count; i++) 178 for (unsigned int i = 0; i < count; i++)
140 hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode); 179 _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
141 } 180 }
142 181
143 static void 182 static void
144 hb_form_clusters (hb_buffer_t *buffer) 183 hb_form_clusters (hb_buffer_t *buffer)
145 { 184 {
146 unsigned int count = buffer->len; 185 unsigned int count = buffer->len;
147 for (unsigned int i = 1; i < count; i++) 186 for (unsigned int i = 1; i < count; i++)
148 if (FLAG (buffer->info[i].general_category()) & 187 if (FLAG (_hb_glyph_info_get_general_category (&buffer->info[i])) &
149 (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | 188 (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) |
150 FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | 189 FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
151 FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) 190 FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
152 buffer->info[i].cluster = buffer->info[i - 1].cluster; 191 buffer->info[i].cluster = buffer->info[i - 1].cluster; /* XXX do the min() here */
153 } 192 }
154 193
155 static void 194 static void
156 hb_ensure_native_direction (hb_buffer_t *buffer) 195 hb_ensure_native_direction (hb_buffer_t *buffer)
157 { 196 {
158 hb_direction_t direction = buffer->props.direction; 197 hb_direction_t direction = buffer->props.direction;
159 198
160 /* TODO vertical: 199 /* TODO vertical:
161 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope nType 200 * The only BTT vertical script is Ogham, but it's not clear to me whether Ope nType
162 * Ogham fonts are supposed to be implemented BTT or not. Need to research th at 201 * Ogham fonts are supposed to be implemented BTT or not. Need to research th at
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 { 237 {
199 hb_codepoint_t glyph; 238 hb_codepoint_t glyph;
200 239
201 if (unlikely (!buffer->len)) 240 if (unlikely (!buffer->len))
202 return; 241 return;
203 242
204 buffer->clear_output (); 243 buffer->clear_output ();
205 244
206 unsigned int count = buffer->len - 1; 245 unsigned int count = buffer->len - 1;
207 for (buffer->idx = 0; buffer->idx < count;) { 246 for (buffer->idx = 0; buffer->idx < count;) {
208 if (unlikely (is_variation_selector (buffer->info[buffer->idx + 1].codepoint ))) { 247 if (unlikely (_hb_unicode_is_variation_selector (buffer->cur(+1).codepoint)) ) {
209 hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, buffer->info [buffer->idx + 1].codepoint, &glyph); 248 hb_font_get_glyph (font, buffer->cur().codepoint, buffer->cur(+1).codepoin t, &glyph);
210 buffer->replace_glyph (glyph); 249 buffer->replace_glyphs (2, 1, &glyph);
211 buffer->skip_glyph ();
212 } else { 250 } else {
213 hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, 0, &glyph); 251 hb_font_get_glyph (font, buffer->cur().codepoint, 0, &glyph);
214 buffer->replace_glyph (glyph); 252 buffer->replace_glyph (glyph);
215 } 253 }
216 } 254 }
217 if (likely (buffer->idx < buffer->len)) { 255 if (likely (buffer->idx < buffer->len)) {
218 hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, 0, &glyph); 256 hb_font_get_glyph (font, buffer->cur().codepoint, 0, &glyph);
219 buffer->replace_glyph (glyph); 257 buffer->replace_glyph (glyph);
220 } 258 }
221 buffer->swap_buffers (); 259 buffer->swap_buffers ();
222 } 260 }
223 261
224 static void 262 static void
225 hb_substitute_default (hb_ot_shape_context_t *c) 263 hb_substitute_default (hb_ot_shape_context_t *c)
226 { 264 {
227 hb_ot_layout_substitute_start (c->buffer); 265 hb_ot_layout_substitute_start (c->buffer);
228 266
229 hb_mirror_chars (c); 267 hb_mirror_chars (c);
230 268
231 hb_map_glyphs (c->font, c->buffer); 269 hb_map_glyphs (c->font, c->buffer);
232 } 270 }
233 271
234 static void 272 static void
235 hb_ot_substitute_complex (hb_ot_shape_context_t *c) 273 hb_ot_substitute_complex (hb_ot_shape_context_t *c)
236 { 274 {
237 if (hb_ot_layout_has_substitution (c->face)) { 275 if (hb_ot_layout_has_substitution (c->face)) {
238 c->plan->map.substitute (c->face, c->buffer); 276 c->plan->map.substitute (c->face, c->buffer);
239 c->applied_substitute_complex = TRUE;
240 } 277 }
241 278
242 hb_ot_layout_substitute_finish (c->buffer); 279 hb_ot_layout_substitute_finish (c->buffer);
243 280
244 return; 281 return;
245 } 282 }
246 283
247 static void
248 hb_substitute_complex_fallback (hb_ot_shape_context_t *c HB_UNUSED)
249 {
250 /* TODO Arabic */
251 }
252
253 284
254 /* Position */ 285 /* Position */
255 286
256 static void 287 static void
257 hb_position_default (hb_ot_shape_context_t *c) 288 hb_position_default (hb_ot_shape_context_t *c)
258 { 289 {
259 hb_ot_layout_position_start (c->buffer); 290 hb_ot_layout_position_start (c->buffer);
260 291
261 unsigned int count = c->buffer->len; 292 unsigned int count = c->buffer->len;
262 for (unsigned int i = 0; i < count; i++) { 293 for (unsigned int i = 0; i < count; i++) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 c->buffer->pos[i].y_offset += kern2; 366 c->buffer->pos[i].y_offset += kern2;
336 } 367 }
337 } 368 }
338 369
339 static void 370 static void
340 hb_position_complex_fallback_visual (hb_ot_shape_context_t *c) 371 hb_position_complex_fallback_visual (hb_ot_shape_context_t *c)
341 { 372 {
342 hb_truetype_kern (c); 373 hb_truetype_kern (c);
343 } 374 }
344 375
376 static void
377 hb_hide_zerowidth (hb_ot_shape_context_t *c)
378 {
379 /* TODO Save the space character in the font? */
380 hb_codepoint_t space;
381 if (!hb_font_get_glyph (c->font, ' ', 0, &space))
382 return; /* No point! */
383
384 unsigned int count = c->buffer->len;
385 for (unsigned int i = 0; i < count; i++)
386 if (unlikely (_hb_glyph_info_is_zero_width (&c->buffer->info[i]))) {
387 c->buffer->info[i].codepoint = space;
388 c->buffer->pos[i].x_advance = 0;
389 c->buffer->pos[i].y_advance = 0;
390 }
391 }
392
345 393
346 /* Do it! */ 394 /* Do it! */
347 395
348 static void 396 static void
349 hb_ot_shape_execute_internal (hb_ot_shape_context_t *c) 397 hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
350 { 398 {
351 c->buffer->deallocate_var_all (); 399 c->buffer->deallocate_var_all ();
352 400
353 /* Save the original direction, we use it later. */ 401 /* Save the original direction, we use it later. */
354 c->target_direction = c->buffer->props.direction; 402 c->target_direction = c->buffer->props.direction;
355 403
356 HB_BUFFER_ALLOCATE_VAR (c->buffer, general_category); 404 HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
357 HB_BUFFER_ALLOCATE_VAR (c->buffer, combining_class); 405 HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
358 406
359 _hb_set_unicode_props (c->buffer); /* BUFFER: Set general_category and combini ng_class */ 407 hb_set_unicode_props (c->buffer);
360 408
361 hb_form_clusters (c->buffer); 409 hb_form_clusters (c->buffer);
362 410
363 hb_ensure_native_direction (c->buffer); 411 hb_ensure_native_direction (c->buffer);
364 412
365 _hb_ot_shape_normalize (c); 413 _hb_ot_shape_normalize (c->font, c->buffer, hb_ot_shape_complex_normalization_ preference (c->plan->shaper));
366 414
367 hb_ot_shape_setup_masks (c); 415 hb_ot_shape_setup_masks (c);
368 416
369 /* SUBSTITUTE */ 417 /* SUBSTITUTE */
370 { 418 {
371 hb_substitute_default (c); 419 hb_substitute_default (c);
372 420
373 hb_ot_substitute_complex (c); 421 hb_ot_substitute_complex (c);
374
375 if (!c->applied_substitute_complex)
376 hb_substitute_complex_fallback (c);
377 } 422 }
378 423
379 /* POSITION */ 424 /* POSITION */
380 { 425 {
381 hb_position_default (c); 426 hb_position_default (c);
382 427
383 hb_ot_position_complex (c); 428 hb_ot_position_complex (c);
384 429
385 hb_bool_t position_fallback = !c->applied_position_complex; 430 hb_bool_t position_fallback = !c->applied_position_complex;
386 if (position_fallback) 431 if (position_fallback)
387 hb_position_complex_fallback (c); 432 hb_position_complex_fallback (c);
388 433
389 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) 434 if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
390 hb_buffer_reverse (c->buffer); 435 hb_buffer_reverse (c->buffer);
391 436
392 if (position_fallback) 437 if (position_fallback)
393 hb_position_complex_fallback_visual (c); 438 hb_position_complex_fallback_visual (c);
394 } 439 }
395 440
396 HB_BUFFER_DEALLOCATE_VAR (c->buffer, combining_class); 441 hb_hide_zerowidth (c);
397 HB_BUFFER_DEALLOCATE_VAR (c->buffer, general_category); 442
443 HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
444 HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
398 445
399 c->buffer->props.direction = c->target_direction; 446 c->buffer->props.direction = c->target_direction;
400 447
401 c->buffer->deallocate_var_all (); 448 c->buffer->deallocate_var_all ();
402 } 449 }
403 450
404 static void 451 static void
405 hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan, 452 hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan,
406 hb_face_t *face, 453 hb_face_t *face,
407 const hb_segment_properties_t *props, 454 const hb_segment_properties_t *props,
408 const hb_feature_t *user_features, 455 const hb_feature_t *user_features,
409 unsigned int num_user_features) 456 unsigned int num_user_features)
410 { 457 {
411 hb_ot_shape_planner_t planner; 458 hb_ot_shape_planner_t planner;
412 459
460 assert (HB_DIRECTION_IS_VALID (props->direction));
461
413 planner.shaper = hb_ot_shape_complex_categorize (props); 462 planner.shaper = hb_ot_shape_complex_categorize (props);
414 463
415 hb_ot_shape_collect_features (&planner, props, user_features, num_user_feature s); 464 hb_ot_shape_collect_features (&planner, props, user_features, num_user_feature s);
416 465
417 planner.compile (face, props, *plan); 466 planner.compile (face, props, *plan);
418 } 467 }
419 468
420 static void 469 static void
421 hb_ot_shape_execute (hb_ot_shape_plan_t *plan, 470 hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
422 hb_font_t *font, 471 hb_font_t *font,
423 hb_buffer_t *buffer, 472 hb_buffer_t *buffer,
424 const hb_feature_t *user_features, 473 const hb_feature_t *user_features,
425 unsigned int num_user_features) 474 unsigned int num_user_features)
426 { 475 {
427 hb_ot_shape_context_t c = {plan, font, font->face, buffer, user_features, num_ user_features}; 476 hb_ot_shape_context_t c = {plan, font, font->face, buffer, user_features, num_ user_features};
428 hb_ot_shape_execute_internal (&c); 477 hb_ot_shape_execute_internal (&c);
429 } 478 }
430 479
431 hb_bool_t 480 hb_bool_t
432 hb_ot_shape (hb_font_t *font, 481 _hb_ot_shape (hb_font_t *font,
433 » hb_buffer_t *buffer, 482 » hb_buffer_t *buffer,
434 » const hb_feature_t *features, 483 » const hb_feature_t *features,
435 » unsigned int num_features, 484 » unsigned int num_features)
436 » const char * const *shaper_options)
437 { 485 {
438 hb_ot_shape_plan_t plan; 486 hb_ot_shape_plan_t plan;
439 487
440 buffer->guess_properties (); 488 buffer->guess_properties ();
441 489
442 hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_fe atures); 490 hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_fe atures);
443 hb_ot_shape_execute (&plan, font, buffer, features, num_features); 491 hb_ot_shape_execute (&plan, font, buffer, features, num_features);
444 492
445 return TRUE; 493 return TRUE;
446 } 494 }
447 495
448 496
497 void
498 hb_ot_shape_glyphs_closure (hb_font_t *font,
499 hb_buffer_t *buffer,
500 const hb_feature_t *features,
501 unsigned int num_features,
502 hb_set_t *glyphs)
503 {
504 hb_ot_shape_plan_t plan;
505
506 buffer->guess_properties ();
507
508 hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_fe atures);
509
510 /* TODO: normalization? have shapers do closure()? */
511 /* TODO: Deal with mirrored chars? */
512 hb_map_glyphs (font, buffer);
513
514 /* Seed it. It's user's responsibility to have cleard glyphs
515 * if that's what they desire. */
516 unsigned int count = buffer->len;
517 for (unsigned int i = 0; i < count; i++)
518 hb_set_add (glyphs, buffer->info[i].codepoint);
519
520 /* And find transitive closure. */
521 hb_set_t copy;
522 copy.init ();
523
524 do {
525 copy.set (glyphs);
526 plan.map.substitute_closure (font->face, glyphs);
527 } while (!copy.equal (glyphs));
528 }
OLDNEW
« no previous file with comments | « third_party/harfbuzz-ng/src/hb-ot-shape.h ('k') | third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698