| 1 | /* | 
|---|
| 2 | * Copyright © 2009  Red Hat, Inc. | 
|---|
| 3 | * Copyright © 2011  Google, Inc. | 
|---|
| 4 | * | 
|---|
| 5 | *  This is part of HarfBuzz, a text shaping library. | 
|---|
| 6 | * | 
|---|
| 7 | * Permission is hereby granted, without written agreement and without | 
|---|
| 8 | * license or royalty fees, to use, copy, modify, and distribute this | 
|---|
| 9 | * software and its documentation for any purpose, provided that the | 
|---|
| 10 | * above copyright notice and the following two paragraphs appear in | 
|---|
| 11 | * all copies of this software. | 
|---|
| 12 | * | 
|---|
| 13 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 
|---|
| 14 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | 
|---|
| 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 | 
|---|
| 17 | * DAMAGE. | 
|---|
| 18 | * | 
|---|
| 19 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | 
|---|
| 20 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
|---|
| 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 | 
|---|
| 23 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 
|---|
| 24 | * | 
|---|
| 25 | * Red Hat Author(s): Behdad Esfahbod | 
|---|
| 26 | * Google Author(s): Behdad Esfahbod | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | #ifndef HB_FONT_HH | 
|---|
| 30 | #define HB_FONT_HH | 
|---|
| 31 |  | 
|---|
| 32 | #include "hb.hh" | 
|---|
| 33 |  | 
|---|
| 34 | #include "hb-face.hh" | 
|---|
| 35 | #include "hb-shaper.hh" | 
|---|
| 36 |  | 
|---|
| 37 |  | 
|---|
| 38 | /* | 
|---|
| 39 | * hb_font_funcs_t | 
|---|
| 40 | */ | 
|---|
| 41 |  | 
|---|
| 42 | #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ | 
|---|
| 43 | HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ | 
|---|
| 44 | HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ | 
|---|
| 45 | HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \ | 
|---|
| 46 | HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \ | 
|---|
| 47 | HB_FONT_FUNC_IMPLEMENT (variation_glyph) \ | 
|---|
| 48 | HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ | 
|---|
| 49 | HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ | 
|---|
| 50 | HB_FONT_FUNC_IMPLEMENT (glyph_h_advances) \ | 
|---|
| 51 | HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \ | 
|---|
| 52 | HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ | 
|---|
| 53 | HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ | 
|---|
| 54 | HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ | 
|---|
| 55 | HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \ | 
|---|
| 56 | HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ | 
|---|
| 57 | HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ | 
|---|
| 58 | HB_FONT_FUNC_IMPLEMENT (glyph_name) \ | 
|---|
| 59 | HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ | 
|---|
| 60 | /* ^--- Add new callbacks here */ | 
|---|
| 61 |  | 
|---|
| 62 | struct hb_font_funcs_t | 
|---|
| 63 | { | 
|---|
| 64 | hb_object_header_t ; | 
|---|
| 65 |  | 
|---|
| 66 | struct { | 
|---|
| 67 | #define HB_FONT_FUNC_IMPLEMENT(name) void *name; | 
|---|
| 68 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 
|---|
| 69 | #undef HB_FONT_FUNC_IMPLEMENT | 
|---|
| 70 | } user_data; | 
|---|
| 71 |  | 
|---|
| 72 | struct { | 
|---|
| 73 | #define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name; | 
|---|
| 74 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 
|---|
| 75 | #undef HB_FONT_FUNC_IMPLEMENT | 
|---|
| 76 | } destroy; | 
|---|
| 77 |  | 
|---|
| 78 | /* Don't access these directly.  Call font->get_*() instead. */ | 
|---|
| 79 | union get_t { | 
|---|
| 80 | struct get_funcs_t { | 
|---|
| 81 | #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; | 
|---|
| 82 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 
|---|
| 83 | #undef HB_FONT_FUNC_IMPLEMENT | 
|---|
| 84 | } f; | 
|---|
| 85 | void (*array[0 | 
|---|
| 86 | #define HB_FONT_FUNC_IMPLEMENT(name) +1 | 
|---|
| 87 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 
|---|
| 88 | #undef HB_FONT_FUNC_IMPLEMENT | 
|---|
| 89 | ]) (); | 
|---|
| 90 | } get; | 
|---|
| 91 | }; | 
|---|
| 92 | DECLARE_NULL_INSTANCE (hb_font_funcs_t); | 
|---|
| 93 |  | 
|---|
| 94 |  | 
|---|
| 95 | /* | 
|---|
| 96 | * hb_font_t | 
|---|
| 97 | */ | 
|---|
| 98 |  | 
|---|
| 99 | #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font); | 
|---|
| 100 | #include "hb-shaper-list.hh" | 
|---|
| 101 | #undef HB_SHAPER_IMPLEMENT | 
|---|
| 102 |  | 
|---|
| 103 | struct hb_font_t | 
|---|
| 104 | { | 
|---|
| 105 | hb_object_header_t ; | 
|---|
| 106 |  | 
|---|
| 107 | hb_font_t *parent; | 
|---|
| 108 | hb_face_t *face; | 
|---|
| 109 |  | 
|---|
| 110 | int32_t x_scale; | 
|---|
| 111 | int32_t y_scale; | 
|---|
| 112 | int64_t x_mult; | 
|---|
| 113 | int64_t y_mult; | 
|---|
| 114 |  | 
|---|
| 115 | unsigned int x_ppem; | 
|---|
| 116 | unsigned int y_ppem; | 
|---|
| 117 |  | 
|---|
| 118 | float ptem; | 
|---|
| 119 |  | 
|---|
| 120 | /* Font variation coordinates. */ | 
|---|
| 121 | unsigned int num_coords; | 
|---|
| 122 | int *coords; | 
|---|
| 123 | float *design_coords; | 
|---|
| 124 |  | 
|---|
| 125 | hb_font_funcs_t   *klass; | 
|---|
| 126 | void              *user_data; | 
|---|
| 127 | hb_destroy_func_t  destroy; | 
|---|
| 128 |  | 
|---|
| 129 | hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */ | 
|---|
| 130 |  | 
|---|
| 131 |  | 
|---|
| 132 | /* Convert from font-space to user-space */ | 
|---|
| 133 | int64_t dir_mult (hb_direction_t direction) | 
|---|
| 134 | { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; } | 
|---|
| 135 | hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); } | 
|---|
| 136 | hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); } | 
|---|
| 137 | hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); } | 
|---|
| 138 | hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); } | 
|---|
| 139 | float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); } | 
|---|
| 140 | float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); } | 
|---|
| 141 | hb_position_t em_scale_dir (int16_t v, hb_direction_t direction) | 
|---|
| 142 | { return em_mult (v, dir_mult (direction)); } | 
|---|
| 143 |  | 
|---|
| 144 | /* Convert from parent-font user-space to our user-space */ | 
|---|
| 145 | hb_position_t parent_scale_x_distance (hb_position_t v) | 
|---|
| 146 | { | 
|---|
| 147 | if (unlikely (parent && parent->x_scale != x_scale)) | 
|---|
| 148 | return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale); | 
|---|
| 149 | return v; | 
|---|
| 150 | } | 
|---|
| 151 | hb_position_t parent_scale_y_distance (hb_position_t v) | 
|---|
| 152 | { | 
|---|
| 153 | if (unlikely (parent && parent->y_scale != y_scale)) | 
|---|
| 154 | return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale); | 
|---|
| 155 | return v; | 
|---|
| 156 | } | 
|---|
| 157 | hb_position_t parent_scale_x_position (hb_position_t v) | 
|---|
| 158 | { return parent_scale_x_distance (v); } | 
|---|
| 159 | hb_position_t parent_scale_y_position (hb_position_t v) | 
|---|
| 160 | { return parent_scale_y_distance (v); } | 
|---|
| 161 |  | 
|---|
| 162 | void parent_scale_distance (hb_position_t *x, hb_position_t *y) | 
|---|
| 163 | { | 
|---|
| 164 | *x = parent_scale_x_distance (*x); | 
|---|
| 165 | *y = parent_scale_y_distance (*y); | 
|---|
| 166 | } | 
|---|
| 167 | void parent_scale_position (hb_position_t *x, hb_position_t *y) | 
|---|
| 168 | { | 
|---|
| 169 | *x = parent_scale_x_position (*x); | 
|---|
| 170 | *y = parent_scale_y_position (*y); | 
|---|
| 171 | } | 
|---|
| 172 |  | 
|---|
| 173 |  | 
|---|
| 174 | /* Public getters */ | 
|---|
| 175 |  | 
|---|
| 176 | HB_INTERNAL bool has_func (unsigned int i); | 
|---|
| 177 | HB_INTERNAL bool has_func_set (unsigned int i); | 
|---|
| 178 |  | 
|---|
| 179 | /* has_* ... */ | 
|---|
| 180 | #define HB_FONT_FUNC_IMPLEMENT(name) \ | 
|---|
| 181 | bool \ | 
|---|
| 182 | has_##name##_func () \ | 
|---|
| 183 | { \ | 
|---|
| 184 | hb_font_funcs_t *funcs = this->klass; \ | 
|---|
| 185 | unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ | 
|---|
| 186 | return has_func (i); \ | 
|---|
| 187 | } \ | 
|---|
| 188 | bool \ | 
|---|
| 189 | has_##name##_func_set () \ | 
|---|
| 190 | { \ | 
|---|
| 191 | hb_font_funcs_t *funcs = this->klass; \ | 
|---|
| 192 | unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ | 
|---|
| 193 | return has_func_set (i); \ | 
|---|
| 194 | } | 
|---|
| 195 | HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 
|---|
| 196 | #undef HB_FONT_FUNC_IMPLEMENT | 
|---|
| 197 |  | 
|---|
| 198 | hb_bool_t get_font_h_extents (hb_font_extents_t *extents) | 
|---|
| 199 | { | 
|---|
| 200 | memset (extents, 0, sizeof (*extents)); | 
|---|
| 201 | return klass->get.f.font_h_extents (this, user_data, | 
|---|
| 202 | extents, | 
|---|
| 203 | klass->user_data.font_h_extents); | 
|---|
| 204 | } | 
|---|
| 205 | hb_bool_t get_font_v_extents (hb_font_extents_t *extents) | 
|---|
| 206 | { | 
|---|
| 207 | memset (extents, 0, sizeof (*extents)); | 
|---|
| 208 | return klass->get.f.font_v_extents (this, user_data, | 
|---|
| 209 | extents, | 
|---|
| 210 | klass->user_data.font_v_extents); | 
|---|
| 211 | } | 
|---|
| 212 |  | 
|---|
| 213 | bool has_glyph (hb_codepoint_t unicode) | 
|---|
| 214 | { | 
|---|
| 215 | hb_codepoint_t glyph; | 
|---|
| 216 | return get_nominal_glyph (unicode, &glyph); | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | hb_bool_t get_nominal_glyph (hb_codepoint_t unicode, | 
|---|
| 220 | hb_codepoint_t *glyph) | 
|---|
| 221 | { | 
|---|
| 222 | *glyph = 0; | 
|---|
| 223 | return klass->get.f.nominal_glyph (this, user_data, | 
|---|
| 224 | unicode, glyph, | 
|---|
| 225 | klass->user_data.nominal_glyph); | 
|---|
| 226 | } | 
|---|
| 227 | unsigned int get_nominal_glyphs (unsigned int count, | 
|---|
| 228 | const hb_codepoint_t *first_unicode, | 
|---|
| 229 | unsigned int unicode_stride, | 
|---|
| 230 | hb_codepoint_t *first_glyph, | 
|---|
| 231 | unsigned int glyph_stride) | 
|---|
| 232 | { | 
|---|
| 233 | return klass->get.f.nominal_glyphs (this, user_data, | 
|---|
| 234 | count, | 
|---|
| 235 | first_unicode, unicode_stride, | 
|---|
| 236 | first_glyph, glyph_stride, | 
|---|
| 237 | klass->user_data.nominal_glyphs); | 
|---|
| 238 | } | 
|---|
| 239 |  | 
|---|
| 240 | hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, | 
|---|
| 241 | hb_codepoint_t *glyph) | 
|---|
| 242 | { | 
|---|
| 243 | *glyph = 0; | 
|---|
| 244 | return klass->get.f.variation_glyph (this, user_data, | 
|---|
| 245 | unicode, variation_selector, glyph, | 
|---|
| 246 | klass->user_data.variation_glyph); | 
|---|
| 247 | } | 
|---|
| 248 |  | 
|---|
| 249 | hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) | 
|---|
| 250 | { | 
|---|
| 251 | return klass->get.f.glyph_h_advance (this, user_data, | 
|---|
| 252 | glyph, | 
|---|
| 253 | klass->user_data.glyph_h_advance); | 
|---|
| 254 | } | 
|---|
| 255 |  | 
|---|
| 256 | hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) | 
|---|
| 257 | { | 
|---|
| 258 | return klass->get.f.glyph_v_advance (this, user_data, | 
|---|
| 259 | glyph, | 
|---|
| 260 | klass->user_data.glyph_v_advance); | 
|---|
| 261 | } | 
|---|
| 262 |  | 
|---|
| 263 | void get_glyph_h_advances (unsigned int count, | 
|---|
| 264 | const hb_codepoint_t *first_glyph, | 
|---|
| 265 | unsigned int glyph_stride, | 
|---|
| 266 | hb_position_t *first_advance, | 
|---|
| 267 | unsigned int advance_stride) | 
|---|
| 268 | { | 
|---|
| 269 | return klass->get.f.glyph_h_advances (this, user_data, | 
|---|
| 270 | count, | 
|---|
| 271 | first_glyph, glyph_stride, | 
|---|
| 272 | first_advance, advance_stride, | 
|---|
| 273 | klass->user_data.glyph_h_advances); | 
|---|
| 274 | } | 
|---|
| 275 |  | 
|---|
| 276 | void get_glyph_v_advances (unsigned int count, | 
|---|
| 277 | const hb_codepoint_t *first_glyph, | 
|---|
| 278 | unsigned int glyph_stride, | 
|---|
| 279 | hb_position_t *first_advance, | 
|---|
| 280 | unsigned int advance_stride) | 
|---|
| 281 | { | 
|---|
| 282 | return klass->get.f.glyph_v_advances (this, user_data, | 
|---|
| 283 | count, | 
|---|
| 284 | first_glyph, glyph_stride, | 
|---|
| 285 | first_advance, advance_stride, | 
|---|
| 286 | klass->user_data.glyph_v_advances); | 
|---|
| 287 | } | 
|---|
| 288 |  | 
|---|
| 289 | hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, | 
|---|
| 290 | hb_position_t *x, hb_position_t *y) | 
|---|
| 291 | { | 
|---|
| 292 | *x = *y = 0; | 
|---|
| 293 | return klass->get.f.glyph_h_origin (this, user_data, | 
|---|
| 294 | glyph, x, y, | 
|---|
| 295 | klass->user_data.glyph_h_origin); | 
|---|
| 296 | } | 
|---|
| 297 |  | 
|---|
| 298 | hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, | 
|---|
| 299 | hb_position_t *x, hb_position_t *y) | 
|---|
| 300 | { | 
|---|
| 301 | *x = *y = 0; | 
|---|
| 302 | return klass->get.f.glyph_v_origin (this, user_data, | 
|---|
| 303 | glyph, x, y, | 
|---|
| 304 | klass->user_data.glyph_v_origin); | 
|---|
| 305 | } | 
|---|
| 306 |  | 
|---|
| 307 | hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, | 
|---|
| 308 | hb_codepoint_t right_glyph) | 
|---|
| 309 | { | 
|---|
| 310 | #ifdef HB_DISABLE_DEPRECATED | 
|---|
| 311 | return 0; | 
|---|
| 312 | #else | 
|---|
| 313 | return klass->get.f.glyph_h_kerning (this, user_data, | 
|---|
| 314 | left_glyph, right_glyph, | 
|---|
| 315 | klass->user_data.glyph_h_kerning); | 
|---|
| 316 | #endif | 
|---|
| 317 | } | 
|---|
| 318 |  | 
|---|
| 319 | hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, | 
|---|
| 320 | hb_codepoint_t bottom_glyph) | 
|---|
| 321 | { | 
|---|
| 322 | #ifdef HB_DISABLE_DEPRECATED | 
|---|
| 323 | return 0; | 
|---|
| 324 | #else | 
|---|
| 325 | return klass->get.f.glyph_v_kerning (this, user_data, | 
|---|
| 326 | top_glyph, bottom_glyph, | 
|---|
| 327 | klass->user_data.glyph_v_kerning); | 
|---|
| 328 | #endif | 
|---|
| 329 | } | 
|---|
| 330 |  | 
|---|
| 331 | hb_bool_t get_glyph_extents (hb_codepoint_t glyph, | 
|---|
| 332 | hb_glyph_extents_t *extents) | 
|---|
| 333 | { | 
|---|
| 334 | memset (extents, 0, sizeof (*extents)); | 
|---|
| 335 | return klass->get.f.glyph_extents (this, user_data, | 
|---|
| 336 | glyph, | 
|---|
| 337 | extents, | 
|---|
| 338 | klass->user_data.glyph_extents); | 
|---|
| 339 | } | 
|---|
| 340 |  | 
|---|
| 341 | hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, | 
|---|
| 342 | hb_position_t *x, hb_position_t *y) | 
|---|
| 343 | { | 
|---|
| 344 | *x = *y = 0; | 
|---|
| 345 | return klass->get.f.glyph_contour_point (this, user_data, | 
|---|
| 346 | glyph, point_index, | 
|---|
| 347 | x, y, | 
|---|
| 348 | klass->user_data.glyph_contour_point); | 
|---|
| 349 | } | 
|---|
| 350 |  | 
|---|
| 351 | hb_bool_t get_glyph_name (hb_codepoint_t glyph, | 
|---|
| 352 | char *name, unsigned int size) | 
|---|
| 353 | { | 
|---|
| 354 | if (size) *name = '\0'; | 
|---|
| 355 | return klass->get.f.glyph_name (this, user_data, | 
|---|
| 356 | glyph, | 
|---|
| 357 | name, size, | 
|---|
| 358 | klass->user_data.glyph_name); | 
|---|
| 359 | } | 
|---|
| 360 |  | 
|---|
| 361 | hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ | 
|---|
| 362 | hb_codepoint_t *glyph) | 
|---|
| 363 | { | 
|---|
| 364 | *glyph = 0; | 
|---|
| 365 | if (len == -1) len = strlen (name); | 
|---|
| 366 | return klass->get.f.glyph_from_name (this, user_data, | 
|---|
| 367 | name, len, | 
|---|
| 368 | glyph, | 
|---|
| 369 | klass->user_data.glyph_from_name); | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 |  | 
|---|
| 373 | /* A bit higher-level, and with fallback */ | 
|---|
| 374 |  | 
|---|
| 375 | void get_h_extents_with_fallback (hb_font_extents_t *extents) | 
|---|
| 376 | { | 
|---|
| 377 | if (!get_font_h_extents (extents)) | 
|---|
| 378 | { | 
|---|
| 379 | extents->ascender = y_scale * .8; | 
|---|
| 380 | extents->descender = extents->ascender - y_scale; | 
|---|
| 381 | extents->line_gap = 0; | 
|---|
| 382 | } | 
|---|
| 383 | } | 
|---|
| 384 | void get_v_extents_with_fallback (hb_font_extents_t *extents) | 
|---|
| 385 | { | 
|---|
| 386 | if (!get_font_v_extents (extents)) | 
|---|
| 387 | { | 
|---|
| 388 | extents->ascender = x_scale / 2; | 
|---|
| 389 | extents->descender = extents->ascender - x_scale; | 
|---|
| 390 | extents->line_gap = 0; | 
|---|
| 391 | } | 
|---|
| 392 | } | 
|---|
| 393 |  | 
|---|
| 394 | void get_extents_for_direction (hb_direction_t direction, | 
|---|
| 395 | hb_font_extents_t *extents) | 
|---|
| 396 | { | 
|---|
| 397 | if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) | 
|---|
| 398 | get_h_extents_with_fallback (extents); | 
|---|
| 399 | else | 
|---|
| 400 | get_v_extents_with_fallback (extents); | 
|---|
| 401 | } | 
|---|
| 402 |  | 
|---|
| 403 | void get_glyph_advance_for_direction (hb_codepoint_t glyph, | 
|---|
| 404 | hb_direction_t direction, | 
|---|
| 405 | hb_position_t *x, hb_position_t *y) | 
|---|
| 406 | { | 
|---|
| 407 | *x = *y = 0; | 
|---|
| 408 | if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) | 
|---|
| 409 | *x = get_glyph_h_advance (glyph); | 
|---|
| 410 | else | 
|---|
| 411 | *y = get_glyph_v_advance (glyph); | 
|---|
| 412 | } | 
|---|
| 413 | void get_glyph_advances_for_direction (hb_direction_t direction, | 
|---|
| 414 | unsigned int count, | 
|---|
| 415 | const hb_codepoint_t *first_glyph, | 
|---|
| 416 | unsigned glyph_stride, | 
|---|
| 417 | hb_position_t *first_advance, | 
|---|
| 418 | unsigned advance_stride) | 
|---|
| 419 | { | 
|---|
| 420 | if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) | 
|---|
| 421 | get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); | 
|---|
| 422 | else | 
|---|
| 423 | get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride); | 
|---|
| 424 | } | 
|---|
| 425 |  | 
|---|
| 426 | void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, | 
|---|
| 427 | hb_position_t *x, hb_position_t *y) | 
|---|
| 428 | { | 
|---|
| 429 | *x = get_glyph_h_advance (glyph) / 2; | 
|---|
| 430 |  | 
|---|
| 431 | /* TODO cache this somehow?! */ | 
|---|
| 432 | hb_font_extents_t extents; | 
|---|
| 433 | get_h_extents_with_fallback (&extents); | 
|---|
| 434 | *y = extents.ascender; | 
|---|
| 435 | } | 
|---|
| 436 |  | 
|---|
| 437 | void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, | 
|---|
| 438 | hb_position_t *x, hb_position_t *y) | 
|---|
| 439 | { | 
|---|
| 440 | if (!get_glyph_h_origin (glyph, x, y) && | 
|---|
| 441 | get_glyph_v_origin (glyph, x, y)) | 
|---|
| 442 | { | 
|---|
| 443 | hb_position_t dx, dy; | 
|---|
| 444 | guess_v_origin_minus_h_origin (glyph, &dx, &dy); | 
|---|
| 445 | *x -= dx; *y -= dy; | 
|---|
| 446 | } | 
|---|
| 447 | } | 
|---|
| 448 | void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, | 
|---|
| 449 | hb_position_t *x, hb_position_t *y) | 
|---|
| 450 | { | 
|---|
| 451 | if (!get_glyph_v_origin (glyph, x, y) && | 
|---|
| 452 | get_glyph_h_origin (glyph, x, y)) | 
|---|
| 453 | { | 
|---|
| 454 | hb_position_t dx, dy; | 
|---|
| 455 | guess_v_origin_minus_h_origin (glyph, &dx, &dy); | 
|---|
| 456 | *x += dx; *y += dy; | 
|---|
| 457 | } | 
|---|
| 458 | } | 
|---|
| 459 |  | 
|---|
| 460 | void get_glyph_origin_for_direction (hb_codepoint_t glyph, | 
|---|
| 461 | hb_direction_t direction, | 
|---|
| 462 | hb_position_t *x, hb_position_t *y) | 
|---|
| 463 | { | 
|---|
| 464 | if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) | 
|---|
| 465 | get_glyph_h_origin_with_fallback (glyph, x, y); | 
|---|
| 466 | else | 
|---|
| 467 | get_glyph_v_origin_with_fallback (glyph, x, y); | 
|---|
| 468 | } | 
|---|
| 469 |  | 
|---|
| 470 | void add_glyph_h_origin (hb_codepoint_t glyph, | 
|---|
| 471 | hb_position_t *x, hb_position_t *y) | 
|---|
| 472 | { | 
|---|
| 473 | hb_position_t origin_x, origin_y; | 
|---|
| 474 |  | 
|---|
| 475 | get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); | 
|---|
| 476 |  | 
|---|
| 477 | *x += origin_x; | 
|---|
| 478 | *y += origin_y; | 
|---|
| 479 | } | 
|---|
| 480 | void add_glyph_v_origin (hb_codepoint_t glyph, | 
|---|
| 481 | hb_position_t *x, hb_position_t *y) | 
|---|
| 482 | { | 
|---|
| 483 | hb_position_t origin_x, origin_y; | 
|---|
| 484 |  | 
|---|
| 485 | get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); | 
|---|
| 486 |  | 
|---|
| 487 | *x += origin_x; | 
|---|
| 488 | *y += origin_y; | 
|---|
| 489 | } | 
|---|
| 490 | void add_glyph_origin_for_direction (hb_codepoint_t glyph, | 
|---|
| 491 | hb_direction_t direction, | 
|---|
| 492 | hb_position_t *x, hb_position_t *y) | 
|---|
| 493 | { | 
|---|
| 494 | hb_position_t origin_x, origin_y; | 
|---|
| 495 |  | 
|---|
| 496 | get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); | 
|---|
| 497 |  | 
|---|
| 498 | *x += origin_x; | 
|---|
| 499 | *y += origin_y; | 
|---|
| 500 | } | 
|---|
| 501 |  | 
|---|
| 502 | void subtract_glyph_h_origin (hb_codepoint_t glyph, | 
|---|
| 503 | hb_position_t *x, hb_position_t *y) | 
|---|
| 504 | { | 
|---|
| 505 | hb_position_t origin_x, origin_y; | 
|---|
| 506 |  | 
|---|
| 507 | get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); | 
|---|
| 508 |  | 
|---|
| 509 | *x -= origin_x; | 
|---|
| 510 | *y -= origin_y; | 
|---|
| 511 | } | 
|---|
| 512 | void subtract_glyph_v_origin (hb_codepoint_t glyph, | 
|---|
| 513 | hb_position_t *x, hb_position_t *y) | 
|---|
| 514 | { | 
|---|
| 515 | hb_position_t origin_x, origin_y; | 
|---|
| 516 |  | 
|---|
| 517 | get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); | 
|---|
| 518 |  | 
|---|
| 519 | *x -= origin_x; | 
|---|
| 520 | *y -= origin_y; | 
|---|
| 521 | } | 
|---|
| 522 | void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, | 
|---|
| 523 | hb_direction_t direction, | 
|---|
| 524 | hb_position_t *x, hb_position_t *y) | 
|---|
| 525 | { | 
|---|
| 526 | hb_position_t origin_x, origin_y; | 
|---|
| 527 |  | 
|---|
| 528 | get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); | 
|---|
| 529 |  | 
|---|
| 530 | *x -= origin_x; | 
|---|
| 531 | *y -= origin_y; | 
|---|
| 532 | } | 
|---|
| 533 |  | 
|---|
| 534 | void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, | 
|---|
| 535 | hb_direction_t direction, | 
|---|
| 536 | hb_position_t *x, hb_position_t *y) | 
|---|
| 537 | { | 
|---|
| 538 | if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { | 
|---|
| 539 | *y = 0; | 
|---|
| 540 | *x = get_glyph_h_kerning (first_glyph, second_glyph); | 
|---|
| 541 | } else { | 
|---|
| 542 | *x = 0; | 
|---|
| 543 | *y = get_glyph_v_kerning (first_glyph, second_glyph); | 
|---|
| 544 | } | 
|---|
| 545 | } | 
|---|
| 546 |  | 
|---|
| 547 | hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph, | 
|---|
| 548 | hb_direction_t direction, | 
|---|
| 549 | hb_glyph_extents_t *extents) | 
|---|
| 550 | { | 
|---|
| 551 | hb_bool_t ret = get_glyph_extents (glyph, extents); | 
|---|
| 552 |  | 
|---|
| 553 | if (ret) | 
|---|
| 554 | subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing); | 
|---|
| 555 |  | 
|---|
| 556 | return ret; | 
|---|
| 557 | } | 
|---|
| 558 |  | 
|---|
| 559 | hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index, | 
|---|
| 560 | hb_direction_t direction, | 
|---|
| 561 | hb_position_t *x, hb_position_t *y) | 
|---|
| 562 | { | 
|---|
| 563 | hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y); | 
|---|
| 564 |  | 
|---|
| 565 | if (ret) | 
|---|
| 566 | subtract_glyph_origin_for_direction (glyph, direction, x, y); | 
|---|
| 567 |  | 
|---|
| 568 | return ret; | 
|---|
| 569 | } | 
|---|
| 570 |  | 
|---|
| 571 | /* Generates gidDDD if glyph has no name. */ | 
|---|
| 572 | void | 
|---|
| 573 | glyph_to_string (hb_codepoint_t glyph, | 
|---|
| 574 | char *s, unsigned int size) | 
|---|
| 575 | { | 
|---|
| 576 | if (get_glyph_name (glyph, s, size)) return; | 
|---|
| 577 |  | 
|---|
| 578 | if (size && snprintf (s, size, "gid%u", glyph) < 0) | 
|---|
| 579 | *s = '\0'; | 
|---|
| 580 | } | 
|---|
| 581 |  | 
|---|
| 582 | /* Parses gidDDD and uniUUUU strings automatically. */ | 
|---|
| 583 | hb_bool_t | 
|---|
| 584 | glyph_from_string (const char *s, int len, /* -1 means nul-terminated */ | 
|---|
| 585 | hb_codepoint_t *glyph) | 
|---|
| 586 | { | 
|---|
| 587 | if (get_glyph_from_name (s, len, glyph)) return true; | 
|---|
| 588 |  | 
|---|
| 589 | if (len == -1) len = strlen (s); | 
|---|
| 590 |  | 
|---|
| 591 | /* Straight glyph index. */ | 
|---|
| 592 | if (hb_codepoint_parse (s, len, 10, glyph)) | 
|---|
| 593 | return true; | 
|---|
| 594 |  | 
|---|
| 595 | if (len > 3) | 
|---|
| 596 | { | 
|---|
| 597 | /* gidDDD syntax for glyph indices. */ | 
|---|
| 598 | if (0 == strncmp (s, "gid", 3) && | 
|---|
| 599 | hb_codepoint_parse (s + 3, len - 3, 10, glyph)) | 
|---|
| 600 | return true; | 
|---|
| 601 |  | 
|---|
| 602 | /* uniUUUU and other Unicode character indices. */ | 
|---|
| 603 | hb_codepoint_t unichar; | 
|---|
| 604 | if (0 == strncmp (s, "uni", 3) && | 
|---|
| 605 | hb_codepoint_parse (s + 3, len - 3, 16, &unichar) && | 
|---|
| 606 | get_nominal_glyph (unichar, glyph)) | 
|---|
| 607 | return true; | 
|---|
| 608 | } | 
|---|
| 609 |  | 
|---|
| 610 | return false; | 
|---|
| 611 | } | 
|---|
| 612 |  | 
|---|
| 613 | void mults_changed () | 
|---|
| 614 | { | 
|---|
| 615 | signed upem = face->get_upem (); | 
|---|
| 616 | x_mult = ((int64_t) x_scale << 16) / upem; | 
|---|
| 617 | y_mult = ((int64_t) y_scale << 16) / upem; | 
|---|
| 618 | } | 
|---|
| 619 |  | 
|---|
| 620 | hb_position_t em_mult (int16_t v, int64_t mult) | 
|---|
| 621 | { | 
|---|
| 622 | return (hb_position_t) ((v * mult) >> 16); | 
|---|
| 623 | } | 
|---|
| 624 | hb_position_t em_scalef (float v, int scale) | 
|---|
| 625 | { return (hb_position_t) roundf (v * scale / face->get_upem ()); } | 
|---|
| 626 | float em_fscale (int16_t v, int scale) | 
|---|
| 627 | { return (float) v * scale / face->get_upem (); } | 
|---|
| 628 | }; | 
|---|
| 629 | DECLARE_NULL_INSTANCE (hb_font_t); | 
|---|
| 630 |  | 
|---|
| 631 |  | 
|---|
| 632 | #endif /* HB_FONT_HH */ | 
|---|
| 633 |  | 
|---|