91
92 /*
93 * hb_font_t
94 */
95
96 struct hb_font_t {
97 hb_object_header_t header;
98 ASSERT_POD ();
99
100 hb_bool_t immutable;
101
102 hb_font_t *parent;
103 hb_face_t *face;
104
105 int x_scale;
106 int y_scale;
107
108 unsigned int x_ppem;
109 unsigned int y_ppem;
110
111 hb_font_funcs_t *klass;
112 void *user_data;
113 hb_destroy_func_t destroy;
114
115 struct hb_shaper_data_t shaper_data;
116
117
118 /* Convert from font-space to user-space */
119 inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
120 inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
121
122 /* Convert from parent-font user-space to our user-space */
123 inline hb_position_t parent_scale_x_distance (hb_position_t v) {
124 if (unlikely (parent && parent->x_scale != x_scale))
125 return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
126 return v;
127 }
128 inline hb_position_t parent_scale_y_distance (hb_position_t v) {
129 if (unlikely (parent && parent->y_scale != y_scale))
130 return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
131 return v;
132 }
133 inline hb_position_t parent_scale_x_position (hb_position_t v) {
134 return parent_scale_x_distance (v);
135 }
136 inline hb_position_t parent_scale_y_position (hb_position_t v) {
137 return parent_scale_y_distance (v);
138 }
139
140 inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
275 return klass->get.f.glyph_name (this, user_data,
276 glyph,
277 name, size,
278 klass->user_data.glyph_name);
279 }
280
281 inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
282 hb_codepoint_t *glyph)
283 {
284 *glyph = 0;
285 if (len == -1) len = strlen (name);
286 return klass->get.f.glyph_from_name (this, user_data,
287 name, len,
288 glyph,
289 klass->user_data.glyph_from_name);
290 }
291
292
293 /* A bit higher-level, and with fallback */
294
295 inline void get_extents_for_direction (hb_direction_t direction,
296 hb_font_extents_t *extents)
297 {
298 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
299 if (!get_font_h_extents (extents))
300 {
301 extents->ascender = y_scale * .8;
302 extents->descender = y_scale - extents->ascender;
303 extents->line_gap = 0;
304 }
305 } else {
306 if (!get_font_v_extents (extents))
307 {
308 extents->ascender = x_scale / 2;
309 extents->descender = x_scale - extents->ascender;
310 extents->line_gap = 0;
311 }
312 }
313 }
314
315 inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
316 hb_direction_t direction,
317 hb_position_t *x, hb_position_t *y)
318 {
319 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
320 *x = get_glyph_h_advance (glyph);
321 *y = 0;
322 } else {
323 *x = 0;
324 *y = get_glyph_v_advance (glyph);
325 }
326 }
327
328 /* Internal only */
329 inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
330 hb_position_t *x, hb_position_t *y)
331 {
332 *x = get_glyph_h_advance (glyph) / 2;
333
334 /* TODO use font_extents.ascender */
335 *y = y_scale;
336 }
337
338 inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
339 hb_direction_t direction,
340 hb_position_t *x, hb_position_t *y)
341 {
342 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
343 {
344 if (!get_glyph_h_origin (glyph, x, y) &&
345 get_glyph_v_origin (glyph, x, y))
346 {
347 hb_position_t dx, dy;
348 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
349 *x -= dx; *y -= dy;
350 }
351 }
352 else
353 {
354 if (!get_glyph_v_origin (glyph, x, y) &&
355 get_glyph_h_origin (glyph, x, y))
356 {
357 hb_position_t dx, dy;
358 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
359 *x += dx; *y += dy;
360 }
361 }
362 }
363
364 inline void add_glyph_h_origin (hb_codepoint_t glyph,
365 hb_position_t *x, hb_position_t *y)
366 {
367 hb_position_t origin_x, origin_y;
368
369 get_glyph_h_origin (glyph, &origin_x, &origin_y);
370
371 *x += origin_x;
372 *y += origin_y;
373 }
374 inline void add_glyph_v_origin (hb_codepoint_t glyph,
375 hb_position_t *x, hb_position_t *y)
376 {
377 hb_position_t origin_x, origin_y;
378
379 get_glyph_v_origin (glyph, &origin_x, &origin_y);
380
381 *x += origin_x;
382 *y += origin_y;
383 }
384 inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
385 hb_direction_t direction,
386 hb_position_t *x, hb_position_t *y)
387 {
388 hb_position_t origin_x, origin_y;
389
390 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
391
392 *x += origin_x;
393 *y += origin_y;
394 }
395
396 inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
397 hb_position_t *x, hb_position_t *y)
398 {
399 hb_position_t origin_x, origin_y;
400
401 get_glyph_h_origin (glyph, &origin_x, &origin_y);
402
403 *x -= origin_x;
404 *y -= origin_y;
405 }
406 inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
407 hb_position_t *x, hb_position_t *y)
408 {
409 hb_position_t origin_x, origin_y;
410
411 get_glyph_v_origin (glyph, &origin_x, &origin_y);
412
413 *x -= origin_x;
414 *y -= origin_y;
415 }
416 inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
417 hb_direction_t direction,
418 hb_position_t *x, hb_position_t *y)
419 {
420 hb_position_t origin_x, origin_y;
421
422 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
423
424 *x -= origin_x;
425 *y -= origin_y;
426 }
427
428 inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
429 hb_direction_t direction,
430 hb_position_t *x, hb_position_t *y)
431 {
487 return true;
488
489 if (len > 3)
490 {
491 /* gidDDD syntax for glyph indices. */
492 if (0 == strncmp (s, "gid", 3) &&
493 hb_codepoint_parse (s + 3, len - 3, 10, glyph))
494 return true;
495
496 /* uniUUUU and other Unicode character indices. */
497 hb_codepoint_t unichar;
498 if (0 == strncmp (s, "uni", 3) &&
499 hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
500 get_nominal_glyph (unichar, glyph))
501 return true;
502 }
503
504 return false;
505 }
506
507 private:
508 inline hb_position_t em_scale (int16_t v, int scale)
509 {
510 int upem = face->get_upem ();
511 int64_t scaled = v * (int64_t) scale;
512 scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
513 return (hb_position_t) (scaled / upem);
514 }
515 };
516
517 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
518 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
519 #include "hb-shaper-list.hh"
520 #undef HB_SHAPER_IMPLEMENT
521 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
522
523
524 #endif /* HB_FONT_PRIVATE_HH */
|
91
92 /*
93 * hb_font_t
94 */
95
96 struct hb_font_t {
97 hb_object_header_t header;
98 ASSERT_POD ();
99
100 hb_bool_t immutable;
101
102 hb_font_t *parent;
103 hb_face_t *face;
104
105 int x_scale;
106 int y_scale;
107
108 unsigned int x_ppem;
109 unsigned int y_ppem;
110
111 /* Font variation coordinates. */
112 unsigned int num_coords;
113 int *coords;
114
115 hb_font_funcs_t *klass;
116 void *user_data;
117 hb_destroy_func_t destroy;
118
119 struct hb_shaper_data_t shaper_data;
120
121
122 /* Convert from font-space to user-space */
123 inline int dir_scale (hb_direction_t direction)
124 { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
125 inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
126 inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
127 inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
128 inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
129 inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
130 { return em_scale (v, dir_scale (direction)); }
131
132 /* Convert from parent-font user-space to our user-space */
133 inline hb_position_t parent_scale_x_distance (hb_position_t v) {
134 if (unlikely (parent && parent->x_scale != x_scale))
135 return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
136 return v;
137 }
138 inline hb_position_t parent_scale_y_distance (hb_position_t v) {
139 if (unlikely (parent && parent->y_scale != y_scale))
140 return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
141 return v;
142 }
143 inline hb_position_t parent_scale_x_position (hb_position_t v) {
144 return parent_scale_x_distance (v);
145 }
146 inline hb_position_t parent_scale_y_position (hb_position_t v) {
147 return parent_scale_y_distance (v);
148 }
149
150 inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
285 return klass->get.f.glyph_name (this, user_data,
286 glyph,
287 name, size,
288 klass->user_data.glyph_name);
289 }
290
291 inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
292 hb_codepoint_t *glyph)
293 {
294 *glyph = 0;
295 if (len == -1) len = strlen (name);
296 return klass->get.f.glyph_from_name (this, user_data,
297 name, len,
298 glyph,
299 klass->user_data.glyph_from_name);
300 }
301
302
303 /* A bit higher-level, and with fallback */
304
305 inline void get_h_extents_with_fallback (hb_font_extents_t *extents)
306 {
307 if (!get_font_h_extents (extents))
308 {
309 extents->ascender = y_scale * .8;
310 extents->descender = extents->ascender - y_scale;
311 extents->line_gap = 0;
312 }
313 }
314 inline void get_v_extents_with_fallback (hb_font_extents_t *extents)
315 {
316 if (!get_font_v_extents (extents))
317 {
318 extents->ascender = x_scale / 2;
319 extents->descender = extents->ascender - x_scale;
320 extents->line_gap = 0;
321 }
322 }
323
324 inline void get_extents_for_direction (hb_direction_t direction,
325 hb_font_extents_t *extents)
326 {
327 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
328 get_h_extents_with_fallback (extents);
329 else
330 get_v_extents_with_fallback (extents);
331 }
332
333 inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
334 hb_direction_t direction,
335 hb_position_t *x, hb_position_t *y)
336 {
337 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
338 *x = get_glyph_h_advance (glyph);
339 *y = 0;
340 } else {
341 *x = 0;
342 *y = get_glyph_v_advance (glyph);
343 }
344 }
345
346 inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
347 hb_position_t *x, hb_position_t *y)
348 {
349 *x = get_glyph_h_advance (glyph) / 2;
350
351 /* TODO cache this somehow?! */
352 hb_font_extents_t extents;
353 get_h_extents_with_fallback (&extents);
354 *y = extents.ascender;
355 }
356
357 inline void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
358 hb_position_t *x, hb_position_t *y)
359 {
360 if (!get_glyph_h_origin (glyph, x, y) &&
361 get_glyph_v_origin (glyph, x, y))
362 {
363 hb_position_t dx, dy;
364 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
365 *x -= dx; *y -= dy;
366 }
367 }
368 inline void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
369 hb_position_t *x, hb_position_t *y)
370 {
371 if (!get_glyph_v_origin (glyph, x, y) &&
372 get_glyph_h_origin (glyph, x, y))
373 {
374 hb_position_t dx, dy;
375 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
376 *x += dx; *y += dy;
377 }
378 }
379
380 inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
381 hb_direction_t direction,
382 hb_position_t *x, hb_position_t *y)
383 {
384 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
385 get_glyph_h_origin_with_fallback (glyph, x, y);
386 else
387 get_glyph_v_origin_with_fallback (glyph, x, y);
388 }
389
390 inline void add_glyph_h_origin (hb_codepoint_t glyph,
391 hb_position_t *x, hb_position_t *y)
392 {
393 hb_position_t origin_x, origin_y;
394
395 get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
396
397 *x += origin_x;
398 *y += origin_y;
399 }
400 inline void add_glyph_v_origin (hb_codepoint_t glyph,
401 hb_position_t *x, hb_position_t *y)
402 {
403 hb_position_t origin_x, origin_y;
404
405 get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
406
407 *x += origin_x;
408 *y += origin_y;
409 }
410 inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
411 hb_direction_t direction,
412 hb_position_t *x, hb_position_t *y)
413 {
414 hb_position_t origin_x, origin_y;
415
416 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
417
418 *x += origin_x;
419 *y += origin_y;
420 }
421
422 inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
423 hb_position_t *x, hb_position_t *y)
424 {
425 hb_position_t origin_x, origin_y;
426
427 get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
428
429 *x -= origin_x;
430 *y -= origin_y;
431 }
432 inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
433 hb_position_t *x, hb_position_t *y)
434 {
435 hb_position_t origin_x, origin_y;
436
437 get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
438
439 *x -= origin_x;
440 *y -= origin_y;
441 }
442 inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
443 hb_direction_t direction,
444 hb_position_t *x, hb_position_t *y)
445 {
446 hb_position_t origin_x, origin_y;
447
448 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
449
450 *x -= origin_x;
451 *y -= origin_y;
452 }
453
454 inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
455 hb_direction_t direction,
456 hb_position_t *x, hb_position_t *y)
457 {
513 return true;
514
515 if (len > 3)
516 {
517 /* gidDDD syntax for glyph indices. */
518 if (0 == strncmp (s, "gid", 3) &&
519 hb_codepoint_parse (s + 3, len - 3, 10, glyph))
520 return true;
521
522 /* uniUUUU and other Unicode character indices. */
523 hb_codepoint_t unichar;
524 if (0 == strncmp (s, "uni", 3) &&
525 hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
526 get_nominal_glyph (unichar, glyph))
527 return true;
528 }
529
530 return false;
531 }
532
533 inline hb_position_t em_scale (int16_t v, int scale)
534 {
535 int upem = face->get_upem ();
536 int64_t scaled = v * (int64_t) scale;
537 scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
538 return (hb_position_t) (scaled / upem);
539 }
540 inline hb_position_t em_scalef (float v, int scale)
541 {
542 return (hb_position_t) (v * scale / face->get_upem ());
543 }
544 };
545
546 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
547 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
548 #include "hb-shaper-list.hh"
549 #undef HB_SHAPER_IMPLEMENT
550 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
551
552
553 #endif /* HB_FONT_PRIVATE_HH */
|