OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2011,2012 Google, Inc. | 2 * Copyright © 2011,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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 { | 217 { |
218 case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: | 218 case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: |
219 case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: | 219 case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: |
220 if (buffer->props.direction == HB_DIRECTION_LTR) { | 220 if (buffer->props.direction == HB_DIRECTION_LTR) { |
221 pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_e
xtents.x_bearing; | 221 pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_e
xtents.x_bearing; |
222 break; | 222 break; |
223 } else if (buffer->props.direction == HB_DIRECTION_RTL) { | 223 } else if (buffer->props.direction == HB_DIRECTION_RTL) { |
224 pos.x_offset += base_extents.x_bearing + base_extents.width - mark_exten
ts.width / 2 - mark_extents.x_bearing; | 224 pos.x_offset += base_extents.x_bearing + base_extents.width - mark_exten
ts.width / 2 - mark_extents.x_bearing; |
225 break; | 225 break; |
226 } | 226 } |
227 /* Fall through */ | 227 HB_FALLTHROUGH; |
228 | 228 |
229 default: | 229 default: |
230 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: | 230 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: |
231 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: | 231 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: |
232 case HB_UNICODE_COMBINING_CLASS_BELOW: | 232 case HB_UNICODE_COMBINING_CLASS_BELOW: |
233 case HB_UNICODE_COMBINING_CLASS_ABOVE: | 233 case HB_UNICODE_COMBINING_CLASS_ABOVE: |
234 /* Center align. */ | 234 /* Center align. */ |
235 pos.x_offset += base_extents.x_bearing + (base_extents.width - mark_extent
s.width) / 2 - mark_extents.x_bearing; | 235 pos.x_offset += base_extents.x_bearing + (base_extents.width - mark_extent
s.width) / 2 - mark_extents.x_bearing; |
236 break; | 236 break; |
237 | 237 |
(...skipping 14 matching lines...) Expand all Loading... |
252 | 252 |
253 /* Y positioning */ | 253 /* Y positioning */ |
254 switch (combining_class) | 254 switch (combining_class) |
255 { | 255 { |
256 case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: | 256 case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: |
257 case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT: | 257 case HB_UNICODE_COMBINING_CLASS_BELOW_LEFT: |
258 case HB_UNICODE_COMBINING_CLASS_BELOW: | 258 case HB_UNICODE_COMBINING_CLASS_BELOW: |
259 case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: | 259 case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: |
260 /* Add gap, fall-through. */ | 260 /* Add gap, fall-through. */ |
261 base_extents.height -= y_gap; | 261 base_extents.height -= y_gap; |
| 262 HB_FALLTHROUGH; |
262 | 263 |
263 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: | 264 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: |
264 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: | 265 case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: |
265 pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents
.y_bearing; | 266 pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents
.y_bearing; |
266 /* Never shift up "below" marks. */ | 267 /* Never shift up "below" marks. */ |
267 if ((y_gap > 0) == (pos.y_offset > 0)) | 268 if ((y_gap > 0) == (pos.y_offset > 0)) |
268 { | 269 { |
269 base_extents.height -= pos.y_offset; | 270 base_extents.height -= pos.y_offset; |
270 pos.y_offset = 0; | 271 pos.y_offset = 0; |
271 } | 272 } |
272 base_extents.height += mark_extents.height; | 273 base_extents.height += mark_extents.height; |
273 break; | 274 break; |
274 | 275 |
275 case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: | 276 case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: |
276 case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT: | 277 case HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT: |
277 case HB_UNICODE_COMBINING_CLASS_ABOVE: | 278 case HB_UNICODE_COMBINING_CLASS_ABOVE: |
278 case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT: | 279 case HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT: |
279 /* Add gap, fall-through. */ | 280 /* Add gap, fall-through. */ |
280 base_extents.y_bearing += y_gap; | 281 base_extents.y_bearing += y_gap; |
281 base_extents.height -= y_gap; | 282 base_extents.height -= y_gap; |
| 283 HB_FALLTHROUGH; |
282 | 284 |
283 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: | 285 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: |
284 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: | 286 case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: |
285 pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_ext
ents.height); | 287 pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_ext
ents.height); |
286 /* Don't shift down "above" marks too much. */ | 288 /* Don't shift down "above" marks too much. */ |
287 if ((y_gap > 0) != (pos.y_offset > 0)) | 289 if ((y_gap > 0) != (pos.y_offset > 0)) |
288 { | 290 { |
289 unsigned int correction = -pos.y_offset / 2; | 291 unsigned int correction = -pos.y_offset / 2; |
290 base_extents.y_bearing += correction; | 292 base_extents.y_bearing += correction; |
291 base_extents.height -= correction; | 293 base_extents.height -= correction; |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 hb_position_t kern1 = y_kern >> 1; | 477 hb_position_t kern1 = y_kern >> 1; |
476 hb_position_t kern2 = y_kern - kern1; | 478 hb_position_t kern2 = y_kern - kern1; |
477 pos[idx].y_advance += kern1; | 479 pos[idx].y_advance += kern1; |
478 pos[skippy_iter.idx].y_advance += kern2; | 480 pos[skippy_iter.idx].y_advance += kern2; |
479 pos[skippy_iter.idx].y_offset += kern2; | 481 pos[skippy_iter.idx].y_offset += kern2; |
480 } | 482 } |
481 | 483 |
482 idx = skippy_iter.idx; | 484 idx = skippy_iter.idx; |
483 } | 485 } |
484 } | 486 } |
| 487 |
| 488 |
| 489 /* Adjusts width of various spaces. */ |
| 490 void |
| 491 _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan, |
| 492 hb_font_t *font, |
| 493 hb_buffer_t *buffer) |
| 494 { |
| 495 if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) |
| 496 return; |
| 497 |
| 498 hb_glyph_info_t *info = buffer->info; |
| 499 hb_glyph_position_t *pos = buffer->pos; |
| 500 unsigned int count = buffer->len; |
| 501 for (unsigned int i = 0; i < count; i++) |
| 502 if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&
info[i])) |
| 503 { |
| 504 hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_
fallback_type (&info[i]); |
| 505 hb_codepoint_t glyph; |
| 506 typedef hb_unicode_funcs_t t; |
| 507 switch (space_type) |
| 508 { |
| 509 case t::NOT_SPACE: /* Shouldn't happen. */ |
| 510 case t::SPACE: |
| 511 break; |
| 512 |
| 513 case t::SPACE_EM: |
| 514 case t::SPACE_EM_2: |
| 515 case t::SPACE_EM_3: |
| 516 case t::SPACE_EM_4: |
| 517 case t::SPACE_EM_5: |
| 518 case t::SPACE_EM_6: |
| 519 case t::SPACE_EM_16: |
| 520 pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) spac
e_type; |
| 521 break; |
| 522 |
| 523 case t::SPACE_4_EM_18: |
| 524 pos[i].x_advance = font->x_scale * 4 / 18; |
| 525 break; |
| 526 |
| 527 case t::SPACE_FIGURE: |
| 528 for (char u = '0'; u <= '9'; u++) |
| 529 if (font->get_glyph (u, 0, &glyph)) |
| 530 { |
| 531 pos[i].x_advance = font->get_glyph_h_advance (glyph); |
| 532 break; |
| 533 } |
| 534 break; |
| 535 |
| 536 case t::SPACE_PUNCTUATION: |
| 537 if (font->get_glyph ('.', 0, &glyph)) |
| 538 pos[i].x_advance = font->get_glyph_h_advance (glyph); |
| 539 else if (font->get_glyph (',', 0, &glyph)) |
| 540 pos[i].x_advance = font->get_glyph_h_advance (glyph); |
| 541 break; |
| 542 |
| 543 case t::SPACE_NARROW: |
| 544 /* Half-space? |
| 545 * Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 o
r 1/5 of EM. |
| 546 * However, in my testing, many fonts have their regular space being a
bout that |
| 547 * size. To me, a percentage of the space width makes more sense. Ha
lf is as |
| 548 * good as any. */ |
| 549 pos[i].x_advance /= 2; |
| 550 break; |
| 551 } |
| 552 } |
| 553 } |
OLD | NEW |