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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 map->add_global_bool_feature (HB_TAG ('r','t','l','a')); | 81 map->add_global_bool_feature (HB_TAG ('r','t','l','a')); |
82 map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); | 82 map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE); |
83 break; | 83 break; |
84 case HB_DIRECTION_TTB: | 84 case HB_DIRECTION_TTB: |
85 case HB_DIRECTION_BTT: | 85 case HB_DIRECTION_BTT: |
86 case HB_DIRECTION_INVALID: | 86 case HB_DIRECTION_INVALID: |
87 default: | 87 default: |
88 break; | 88 break; |
89 } | 89 } |
90 | 90 |
| 91 map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE); |
| 92 map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE); |
| 93 map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE); |
| 94 |
91 if (planner->shaper->collect_features) | 95 if (planner->shaper->collect_features) |
92 planner->shaper->collect_features (planner); | 96 planner->shaper->collect_features (planner); |
93 | 97 |
94 for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) | 98 for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) |
95 map->add_global_bool_feature (common_features[i]); | 99 map->add_global_bool_feature (common_features[i]); |
96 | 100 |
97 if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) | 101 if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) |
98 for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) | 102 for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) |
99 map->add_feature (horizontal_features[i], 1, F_GLOBAL | | 103 map->add_feature (horizontal_features[i], 1, F_GLOBAL | |
100 (horizontal_features[i] == HB_TAG('k','e','r','n') ? | 104 (horizontal_features[i] == HB_TAG('k','e','r','n') ? |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 } | 231 } |
228 | 232 |
229 static void | 233 static void |
230 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) | 234 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) |
231 { | 235 { |
232 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || | 236 if (!(buffer->flags & HB_BUFFER_FLAG_BOT) || |
233 _hb_glyph_info_get_general_category (&buffer->info[0]) != | 237 _hb_glyph_info_get_general_category (&buffer->info[0]) != |
234 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | 238 HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) |
235 return; | 239 return; |
236 | 240 |
237 hb_codepoint_t dottedcircle_glyph; | 241 if (!font->has_glyph (0x25CC)) |
238 if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph)) | |
239 return; | 242 return; |
240 | 243 |
241 hb_glyph_info_t dottedcircle; | 244 hb_glyph_info_t dottedcircle; |
242 dottedcircle.codepoint = 0x25CC; | 245 dottedcircle.codepoint = 0x25CC; |
243 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); | 246 _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); |
244 | 247 |
245 buffer->clear_output (); | 248 buffer->clear_output (); |
246 | 249 |
247 buffer->idx = 0; | 250 buffer->idx = 0; |
248 hb_glyph_info_t info = dottedcircle; | 251 hb_glyph_info_t info = dottedcircle; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 /* Substitute */ | 288 /* Substitute */ |
286 | 289 |
287 static inline void | 290 static inline void |
288 hb_ot_mirror_chars (hb_ot_shape_context_t *c) | 291 hb_ot_mirror_chars (hb_ot_shape_context_t *c) |
289 { | 292 { |
290 if (HB_DIRECTION_IS_FORWARD (c->target_direction)) | 293 if (HB_DIRECTION_IS_FORWARD (c->target_direction)) |
291 return; | 294 return; |
292 | 295 |
293 hb_buffer_t *buffer = c->buffer; | 296 hb_buffer_t *buffer = c->buffer; |
294 hb_unicode_funcs_t *unicode = buffer->unicode; | 297 hb_unicode_funcs_t *unicode = buffer->unicode; |
295 hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m')); | 298 hb_mask_t rtlm_mask = c->plan->rtlm_mask; |
296 | 299 |
297 unsigned int count = buffer->len; | 300 unsigned int count = buffer->len; |
298 hb_glyph_info_t *info = buffer->info; | 301 hb_glyph_info_t *info = buffer->info; |
299 for (unsigned int i = 0; i < count; i++) { | 302 for (unsigned int i = 0; i < count; i++) { |
300 hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); | 303 hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); |
301 if (likely (codepoint == info[i].codepoint)) | 304 if (likely (codepoint == info[i].codepoint)) |
302 info[i].mask |= rtlm_mask; | 305 info[i].mask |= rtlm_mask; |
303 else | 306 else |
304 info[i].codepoint = codepoint; | 307 info[i].codepoint = codepoint; |
305 } | 308 } |
306 } | 309 } |
307 | 310 |
308 static inline void | 311 static inline void |
| 312 hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) |
| 313 { |
| 314 if (!c->plan->has_frac) |
| 315 return; |
| 316 |
| 317 hb_buffer_t *buffer = c->buffer; |
| 318 |
| 319 /* TODO look in pre/post context text also. */ |
| 320 unsigned int count = buffer->len; |
| 321 hb_glyph_info_t *info = buffer->info; |
| 322 for (unsigned int i = 0; i < count; i++) |
| 323 { |
| 324 if (info[i].codepoint == 0x2044) /* FRACTION SLASH */ |
| 325 { |
| 326 unsigned int start = i, end = i + 1; |
| 327 while (start && |
| 328 _hb_glyph_info_get_general_category (&info[start - 1]) == |
| 329 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) |
| 330 start--; |
| 331 while (end < count && |
| 332 _hb_glyph_info_get_general_category (&info[end]) == |
| 333 HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) |
| 334 end++; |
| 335 |
| 336 for (unsigned int j = start; j < i; j++) |
| 337 info[j].mask |= c->plan->numr_mask | c->plan->frac_mask; |
| 338 info[i].mask |= c->plan->frac_mask; |
| 339 for (unsigned int j = i + 1; j < end; j++) |
| 340 info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask; |
| 341 |
| 342 i = end - 1; |
| 343 } |
| 344 } |
| 345 } |
| 346 |
| 347 static inline void |
| 348 hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) |
| 349 { |
| 350 hb_ot_map_t *map = &c->plan->map; |
| 351 hb_buffer_t *buffer = c->buffer; |
| 352 |
| 353 hb_mask_t global_mask = map->get_global_mask (); |
| 354 buffer->reset_masks (global_mask); |
| 355 } |
| 356 |
| 357 static inline void |
309 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) | 358 hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) |
310 { | 359 { |
311 hb_ot_map_t *map = &c->plan->map; | 360 hb_ot_map_t *map = &c->plan->map; |
312 hb_buffer_t *buffer = c->buffer; | 361 hb_buffer_t *buffer = c->buffer; |
313 | 362 |
314 hb_mask_t global_mask = map->get_global_mask (); | 363 hb_ot_shape_setup_masks_fraction (c); |
315 buffer->reset_masks (global_mask); | |
316 | 364 |
317 if (c->plan->shaper->setup_masks) | 365 if (c->plan->shaper->setup_masks) |
318 c->plan->shaper->setup_masks (c->plan, buffer, c->font); | 366 c->plan->shaper->setup_masks (c->plan, buffer, c->font); |
319 | 367 |
320 for (unsigned int i = 0; i < c->num_user_features; i++) | 368 for (unsigned int i = 0; i < c->num_user_features; i++) |
321 { | 369 { |
322 const hb_feature_t *feature = &c->user_features[i]; | 370 const hb_feature_t *feature = &c->user_features[i]; |
323 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { | 371 if (!(feature->start == 0 && feature->end == (unsigned int)-1)) { |
324 unsigned int shift; | 372 unsigned int shift; |
325 hb_mask_t mask = map->get_mask (feature->tag, &shift); | 373 hb_mask_t mask = map->get_mask (feature->tag, &shift); |
(...skipping 25 matching lines...) Expand all Loading... |
351 } | 399 } |
352 | 400 |
353 static inline void | 401 static inline void |
354 hb_ot_substitute_default (hb_ot_shape_context_t *c) | 402 hb_ot_substitute_default (hb_ot_shape_context_t *c) |
355 { | 403 { |
356 hb_buffer_t *buffer = c->buffer; | 404 hb_buffer_t *buffer = c->buffer; |
357 | 405 |
358 if (c->plan->shaper->preprocess_text) | 406 if (c->plan->shaper->preprocess_text) |
359 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); | 407 c->plan->shaper->preprocess_text (c->plan, buffer, c->font); |
360 | 408 |
| 409 hb_ot_shape_initialize_masks (c); |
| 410 |
361 hb_ot_mirror_chars (c); | 411 hb_ot_mirror_chars (c); |
362 | 412 |
363 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); | 413 HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); |
364 | 414 |
365 _hb_ot_shape_normalize (c->plan, buffer, c->font); | 415 _hb_ot_shape_normalize (c->plan, buffer, c->font); |
366 | 416 |
367 hb_ot_shape_setup_masks (c); | 417 hb_ot_shape_setup_masks (c); |
368 | 418 |
369 /* This is unfortunate to go here, but necessary... */ | 419 /* This is unfortunate to go here, but necessary... */ |
370 if (!hb_ot_layout_has_positioning (c->face)) | 420 if (!hb_ot_layout_has_positioning (c->face)) |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 hb_set_t copy; | 742 hb_set_t copy; |
693 copy.init (); | 743 copy.init (); |
694 do { | 744 do { |
695 copy.set (glyphs); | 745 copy.set (glyphs); |
696 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) | 746 for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index)
;) |
697 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); | 747 hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); |
698 } while (!copy.is_equal (glyphs)); | 748 } while (!copy.is_equal (glyphs)); |
699 | 749 |
700 hb_shape_plan_destroy (shape_plan); | 750 hb_shape_plan_destroy (shape_plan); |
701 } | 751 } |
OLD | NEW |