OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
3 * Copyright © 2011 Google, Inc. | 3 * Copyright © 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 |
(...skipping 15 matching lines...) Expand all Loading... |
26 * Google Author(s): Behdad Esfahbod | 26 * Google Author(s): Behdad Esfahbod |
27 */ | 27 */ |
28 | 28 |
29 #ifndef HB_FONT_PRIVATE_HH | 29 #ifndef HB_FONT_PRIVATE_HH |
30 #define HB_FONT_PRIVATE_HH | 30 #define HB_FONT_PRIVATE_HH |
31 | 31 |
32 #include "hb-private.hh" | 32 #include "hb-private.hh" |
33 | 33 |
34 #include "hb-font.h" | 34 #include "hb-font.h" |
35 #include "hb-object-private.hh" | 35 #include "hb-object-private.hh" |
| 36 #include "hb-shaper-private.hh" |
| 37 #include "hb-shape-plan-private.hh" |
36 | 38 |
37 | 39 |
38 | 40 |
39 /* | 41 /* |
40 * hb_font_funcs_t | 42 * hb_font_funcs_t |
41 */ | 43 */ |
42 | 44 |
43 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ | 45 #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ |
44 HB_FONT_FUNC_IMPLEMENT (glyph) \ | 46 HB_FONT_FUNC_IMPLEMENT (glyph) \ |
45 HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ | 47 HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ |
46 HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ | 48 HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ |
47 HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ | 49 HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ |
48 HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ | 50 HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \ |
49 HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ | 51 HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \ |
50 HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \ | 52 HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \ |
51 HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ | 53 HB_FONT_FUNC_IMPLEMENT (glyph_extents) \ |
52 HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ | 54 HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \ |
53 HB_FONT_FUNC_IMPLEMENT (glyph_name) \ | 55 HB_FONT_FUNC_IMPLEMENT (glyph_name) \ |
54 HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ | 56 HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ |
55 /* ^--- Add new callbacks here */ | 57 /* ^--- Add new callbacks here */ |
56 | 58 |
57 struct _hb_font_funcs_t { | 59 struct hb_font_funcs_t { |
58 hb_object_header_t header; | 60 hb_object_header_t header; |
59 ASSERT_POD (); | 61 ASSERT_POD (); |
60 | 62 |
61 hb_bool_t immutable; | 63 hb_bool_t immutable; |
62 | 64 |
63 /* Don't access these directly. Call hb_font_get_*() instead. */ | 65 /* Don't access these directly. Call hb_font_get_*() instead. */ |
64 | 66 |
65 struct { | 67 struct { |
66 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; | 68 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; |
67 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 69 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
(...skipping 11 matching lines...) Expand all Loading... |
79 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS | 81 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
80 #undef HB_FONT_FUNC_IMPLEMENT | 82 #undef HB_FONT_FUNC_IMPLEMENT |
81 } destroy; | 83 } destroy; |
82 }; | 84 }; |
83 | 85 |
84 | 86 |
85 /* | 87 /* |
86 * hb_face_t | 88 * hb_face_t |
87 */ | 89 */ |
88 | 90 |
89 struct _hb_face_t { | 91 struct hb_face_t { |
90 hb_object_header_t header; | 92 hb_object_header_t header; |
91 ASSERT_POD (); | 93 ASSERT_POD (); |
92 | 94 |
93 hb_bool_t immutable; | 95 hb_bool_t immutable; |
94 | 96 |
95 hb_reference_table_func_t reference_table; | 97 hb_reference_table_func_t reference_table_func; |
96 void *user_data; | 98 void *user_data; |
97 hb_destroy_func_t destroy; | 99 hb_destroy_func_t destroy; |
98 | 100 |
99 struct hb_ot_layout_t *ot_layout; | 101 unsigned int index; |
| 102 mutable unsigned int upem; |
100 | 103 |
101 unsigned int index; | 104 struct hb_shaper_data_t shaper_data; |
102 unsigned int upem; | 105 |
| 106 struct plan_node_t { |
| 107 hb_shape_plan_t *shape_plan; |
| 108 plan_node_t *next; |
| 109 } *shape_plans; |
| 110 |
| 111 |
| 112 inline hb_blob_t *reference_table (hb_tag_t tag) const |
| 113 { |
| 114 hb_blob_t *blob; |
| 115 |
| 116 if (unlikely (!this || !reference_table_func)) |
| 117 return hb_blob_get_empty (); |
| 118 |
| 119 blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, use
r_data); |
| 120 if (unlikely (!blob)) |
| 121 return hb_blob_get_empty (); |
| 122 |
| 123 return blob; |
| 124 } |
| 125 |
| 126 inline unsigned int get_upem (void) const |
| 127 { |
| 128 if (unlikely (!upem)) |
| 129 load_upem (); |
| 130 return upem; |
| 131 } |
| 132 |
| 133 private: |
| 134 HB_INTERNAL void load_upem (void) const; |
103 }; | 135 }; |
104 | 136 |
| 137 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
| 138 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); |
| 139 #include "hb-shaper-list.hh" |
| 140 #undef HB_SHAPER_IMPLEMENT |
| 141 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
| 142 |
105 | 143 |
106 /* | 144 /* |
107 * hb_font_t | 145 * hb_font_t |
108 */ | 146 */ |
109 | 147 |
110 struct _hb_font_t { | 148 struct hb_font_t { |
111 hb_object_header_t header; | 149 hb_object_header_t header; |
112 ASSERT_POD (); | 150 ASSERT_POD (); |
113 | 151 |
114 hb_bool_t immutable; | 152 hb_bool_t immutable; |
115 | 153 |
116 hb_font_t *parent; | 154 hb_font_t *parent; |
117 hb_face_t *face; | 155 hb_face_t *face; |
118 | 156 |
119 int x_scale; | 157 int x_scale; |
120 int y_scale; | 158 int y_scale; |
121 | 159 |
122 unsigned int x_ppem; | 160 unsigned int x_ppem; |
123 unsigned int y_ppem; | 161 unsigned int y_ppem; |
124 | 162 |
125 hb_font_funcs_t *klass; | 163 hb_font_funcs_t *klass; |
126 void *user_data; | 164 void *user_data; |
127 hb_destroy_func_t destroy; | 165 hb_destroy_func_t destroy; |
128 | 166 |
| 167 struct hb_shaper_data_t shaper_data; |
| 168 |
129 | 169 |
130 /* Convert from font-space to user-space */ | 170 /* Convert from font-space to user-space */ |
131 inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scal
e); } | 171 inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scal
e); } |
132 inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scal
e); } | 172 inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scal
e); } |
133 | 173 |
134 /* Convert from parent-font user-space to our user-space */ | 174 /* Convert from parent-font user-space to our user-space */ |
135 inline hb_position_t parent_scale_x_distance (hb_position_t v) { | 175 inline hb_position_t parent_scale_x_distance (hb_position_t v) { |
136 if (unlikely (parent && parent->x_scale != x_scale)) | 176 if (unlikely (parent && parent->x_scale != x_scale)) |
137 return v * (int64_t) this->x_scale / this->parent->x_scale; | 177 return v * (int64_t) this->x_scale / this->parent->x_scale; |
138 return v; | 178 return v; |
(...skipping 13 matching lines...) Expand all Loading... |
152 inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) { | 192 inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) { |
153 *x = parent_scale_x_distance (*x); | 193 *x = parent_scale_x_distance (*x); |
154 *y = parent_scale_y_distance (*y); | 194 *y = parent_scale_y_distance (*y); |
155 } | 195 } |
156 inline void parent_scale_position (hb_position_t *x, hb_position_t *y) { | 196 inline void parent_scale_position (hb_position_t *x, hb_position_t *y) { |
157 *x = parent_scale_x_position (*x); | 197 *x = parent_scale_x_position (*x); |
158 *y = parent_scale_y_position (*y); | 198 *y = parent_scale_y_position (*y); |
159 } | 199 } |
160 | 200 |
161 | 201 |
| 202 /* Public getters */ |
| 203 |
| 204 inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_s
elector, |
| 205 hb_codepoint_t *glyph) |
| 206 { |
| 207 *glyph = 0; |
| 208 return klass->get.glyph (this, user_data, |
| 209 unicode, variation_selector, glyph, |
| 210 klass->user_data.glyph); |
| 211 } |
| 212 |
| 213 inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) |
| 214 { |
| 215 return klass->get.glyph_h_advance (this, user_data, |
| 216 glyph, |
| 217 klass->user_data.glyph_h_advance); |
| 218 } |
| 219 |
| 220 inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) |
| 221 { |
| 222 return klass->get.glyph_v_advance (this, user_data, |
| 223 glyph, |
| 224 klass->user_data.glyph_v_advance); |
| 225 } |
| 226 |
| 227 inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, |
| 228 hb_position_t *x, hb_position_t *y) |
| 229 { |
| 230 *x = *y = 0; |
| 231 return klass->get.glyph_h_origin (this, user_data, |
| 232 glyph, x, y, |
| 233 klass->user_data.glyph_h_origin); |
| 234 } |
| 235 |
| 236 inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, |
| 237 hb_position_t *x, hb_position_t *y) |
| 238 { |
| 239 *x = *y = 0; |
| 240 return klass->get.glyph_v_origin (this, user_data, |
| 241 glyph, x, y, |
| 242 klass->user_data.glyph_v_origin); |
| 243 } |
| 244 |
| 245 inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepo
int_t right_glyph) |
| 246 { |
| 247 return klass->get.glyph_h_kerning (this, user_data, |
| 248 left_glyph, right_glyph, |
| 249 klass->user_data.glyph_h_kerning); |
| 250 } |
| 251 |
| 252 inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepo
int_t right_glyph) |
| 253 { |
| 254 return klass->get.glyph_v_kerning (this, user_data, |
| 255 left_glyph, right_glyph, |
| 256 klass->user_data.glyph_v_kerning); |
| 257 } |
| 258 |
| 259 inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph, |
| 260 hb_glyph_extents_t *extents) |
| 261 { |
| 262 memset (extents, 0, sizeof (*extents)); |
| 263 return klass->get.glyph_extents (this, user_data, |
| 264 glyph, |
| 265 extents, |
| 266 klass->user_data.glyph_extents); |
| 267 } |
| 268 |
| 269 inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int p
oint_index, |
| 270 hb_position_t *x, hb_position_t *y) |
| 271 { |
| 272 *x = *y = 0; |
| 273 return klass->get.glyph_contour_point (this, user_data, |
| 274 glyph, point_index, |
| 275 x, y, |
| 276 klass->user_data.glyph_contour_point)
; |
| 277 } |
| 278 |
| 279 inline hb_bool_t get_glyph_name (hb_codepoint_t glyph, |
| 280 char *name, unsigned int size) |
| 281 { |
| 282 if (size) *name = '\0'; |
| 283 return klass->get.glyph_name (this, user_data, |
| 284 glyph, |
| 285 name, size, |
| 286 klass->user_data.glyph_name); |
| 287 } |
| 288 |
| 289 inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means n
ul-terminated */ |
| 290 hb_codepoint_t *glyph) |
| 291 { |
| 292 *glyph = 0; |
| 293 if (len == -1) len = strlen (name); |
| 294 return klass->get.glyph_from_name (this, user_data, |
| 295 name, len, |
| 296 glyph, |
| 297 klass->user_data.glyph_from_name); |
| 298 } |
| 299 |
| 300 |
| 301 /* A bit higher-level, and with fallback */ |
| 302 |
| 303 inline void get_glyph_advance_for_direction (hb_codepoint_t glyph, |
| 304 hb_direction_t direction, |
| 305 hb_position_t *x, hb_position_t *
y) |
| 306 { |
| 307 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 308 *x = get_glyph_h_advance (glyph); |
| 309 *y = 0; |
| 310 } else { |
| 311 *x = 0; |
| 312 *y = get_glyph_v_advance (glyph); |
| 313 } |
| 314 } |
| 315 |
| 316 /* Internal only */ |
| 317 inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, |
| 318 hb_position_t *x, hb_position_t *y) |
| 319 { |
| 320 *x = get_glyph_h_advance (glyph) / 2; |
| 321 |
| 322 /* TODO use font_metics.ascent */ |
| 323 *y = y_scale; |
| 324 } |
| 325 |
| 326 inline void get_glyph_origin_for_direction (hb_codepoint_t glyph, |
| 327 hb_direction_t direction, |
| 328 hb_position_t *x, hb_position_t *y
) |
| 329 { |
| 330 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 331 hb_bool_t ret = get_glyph_h_origin (glyph, x, y); |
| 332 if (!ret && (ret = get_glyph_v_origin (glyph, x, y))) { |
| 333 hb_position_t dx, dy; |
| 334 guess_v_origin_minus_h_origin (glyph, &dx, &dy); |
| 335 *x -= dx; *y -= dy; |
| 336 } |
| 337 } else { |
| 338 hb_bool_t ret = get_glyph_v_origin (glyph, x, y); |
| 339 if (!ret && (ret = get_glyph_h_origin (glyph, x, y))) { |
| 340 hb_position_t dx, dy; |
| 341 guess_v_origin_minus_h_origin (glyph, &dx, &dy); |
| 342 *x += dx; *y += dy; |
| 343 } |
| 344 } |
| 345 } |
| 346 |
| 347 inline void add_glyph_origin_for_direction (hb_codepoint_t glyph, |
| 348 hb_direction_t direction, |
| 349 hb_position_t *x, hb_position_t *y
) |
| 350 { |
| 351 hb_position_t origin_x, origin_y; |
| 352 |
| 353 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); |
| 354 |
| 355 *x += origin_x; |
| 356 *y += origin_y; |
| 357 } |
| 358 |
| 359 inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, |
| 360 hb_direction_t direction, |
| 361 hb_position_t *x, hb_position
_t *y) |
| 362 { |
| 363 hb_position_t origin_x, origin_y; |
| 364 |
| 365 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); |
| 366 |
| 367 *x -= origin_x; |
| 368 *y -= origin_y; |
| 369 } |
| 370 |
| 371 inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_co
depoint_t second_glyph, |
| 372 hb_direction_t direction, |
| 373 hb_position_t *x, hb_position_t *
y) |
| 374 { |
| 375 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 376 *x = get_glyph_h_kerning (first_glyph, second_glyph); |
| 377 *y = 0; |
| 378 } else { |
| 379 *x = 0; |
| 380 *y = get_glyph_v_kerning (first_glyph, second_glyph); |
| 381 } |
| 382 } |
| 383 |
| 384 inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph, |
| 385 hb_direction_t direction, |
| 386 hb_glyph_extents_t *extents) |
| 387 { |
| 388 hb_bool_t ret = get_glyph_extents (glyph, extents); |
| 389 |
| 390 if (ret) |
| 391 subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing
, &extents->y_bearing); |
| 392 |
| 393 return ret; |
| 394 } |
| 395 |
| 396 inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, uns
igned int point_index, |
| 397 hb_direction_t direction, |
| 398 hb_position_t *x, hb_posi
tion_t *y) |
| 399 { |
| 400 hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y); |
| 401 |
| 402 if (ret) |
| 403 subtract_glyph_origin_for_direction (glyph, direction, x, y); |
| 404 |
| 405 return ret; |
| 406 } |
| 407 |
| 408 /* Generates gidDDD if glyph has no name. */ |
| 409 inline void |
| 410 glyph_to_string (hb_codepoint_t glyph, |
| 411 char *s, unsigned int size) |
| 412 { |
| 413 if (get_glyph_name (glyph, s, size)) return; |
| 414 |
| 415 snprintf (s, size, "gid%u", glyph); |
| 416 } |
| 417 |
| 418 /* Parses gidDDD and uniUUUU strings automatically. */ |
| 419 inline hb_bool_t |
| 420 glyph_from_string (const char *s, int len, /* -1 means nul-terminated */ |
| 421 hb_codepoint_t *glyph) |
| 422 { |
| 423 if (get_glyph_from_name (s, len, glyph)) return true; |
| 424 |
| 425 if (len == -1) len = strlen (s); |
| 426 |
| 427 /* Straight glyph index. */ |
| 428 if (hb_codepoint_parse (s, len, 10, glyph)) |
| 429 return true; |
| 430 |
| 431 if (len > 3) |
| 432 { |
| 433 /* gidDDD syntax for glyph indices. */ |
| 434 if (0 == strncmp (s, "gid", 3) && |
| 435 hb_codepoint_parse (s + 3, len - 3, 10, glyph)) |
| 436 return true; |
| 437 |
| 438 /* uniUUUU and other Unicode character indices. */ |
| 439 hb_codepoint_t unichar; |
| 440 if (0 == strncmp (s, "uni", 3) && |
| 441 hb_codepoint_parse (s + 3, len - 3, 16, &unichar) && |
| 442 get_glyph (unichar, 0, glyph)) |
| 443 return true; |
| 444 } |
| 445 |
| 446 return false; |
| 447 } |
| 448 |
162 private: | 449 private: |
163 inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) sc
ale / hb_face_get_upem (this->face); } | 450 inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) sc
ale / hb_face_get_upem (this->face); } |
164 }; | 451 }; |
165 | 452 |
| 453 #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
| 454 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font); |
| 455 #include "hb-shaper-list.hh" |
| 456 #undef HB_SHAPER_IMPLEMENT |
| 457 #undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
166 | 458 |
167 | 459 |
168 #endif /* HB_FONT_PRIVATE_HH */ | 460 #endif /* HB_FONT_PRIVATE_HH */ |
OLD | NEW |