OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2009 Red Hat, Inc. |
| 3 * |
| 4 * This is part of HarfBuzz, a text shaping library. |
| 5 * |
| 6 * Permission is hereby granted, without written agreement and without |
| 7 * license or royalty fees, to use, copy, modify, and distribute this |
| 8 * software and its documentation for any purpose, provided that the |
| 9 * above copyright notice and the following two paragraphs appear in |
| 10 * all copies of this software. |
| 11 * |
| 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
| 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
| 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
| 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| 16 * DAMAGE. |
| 17 * |
| 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
| 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
| 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 23 * |
| 24 * Red Hat Author(s): Behdad Esfahbod |
| 25 */ |
| 26 |
| 27 #include "hb-private.h" |
| 28 |
| 29 #include "hb-font-private.h" |
| 30 #include "hb-blob-private.h" |
| 31 #include "hb-open-file-private.hh" |
| 32 |
| 33 #include "hb-ot-layout-private.hh" |
| 34 |
| 35 #include <string.h> |
| 36 |
| 37 HB_BEGIN_DECLS |
| 38 |
| 39 |
| 40 /* |
| 41 * hb_font_funcs_t |
| 42 */ |
| 43 |
| 44 static hb_codepoint_t |
| 45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, |
| 46 hb_face_t *face HB_UNUSED, |
| 47 const void *user_data HB_UNUSED, |
| 48 hb_codepoint_t unicode HB_UNUSED, |
| 49 hb_codepoint_t variation_selector HB_UNUSED) |
| 50 { return 0; } |
| 51 |
| 52 static void |
| 53 hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED, |
| 54 hb_face_t *face HB_UNUSED, |
| 55 const void *user_data HB_UNUSED, |
| 56 hb_codepoint_t glyph HB_UNUSED, |
| 57 hb_position_t *x_advance HB_UNUSED, |
| 58 hb_position_t *y_advance HB_UNUSED) |
| 59 { } |
| 60 |
| 61 static void |
| 62 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, |
| 63 hb_face_t *face HB_UNUSED, |
| 64 const void *user_data HB_UNUSED, |
| 65 hb_codepoint_t glyph HB_UNUSED, |
| 66 hb_glyph_extents_t *extents HB_UNUSED) |
| 67 { } |
| 68 |
| 69 static hb_bool_t |
| 70 hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED, |
| 71 hb_face_t *face HB_UNUSED, |
| 72 const void *user_data HB_UNUSED, |
| 73 unsigned int point_index HB_UNUSED, |
| 74 hb_codepoint_t glyph HB_UNUSED, |
| 75 hb_position_t *x HB_UNUSED, |
| 76 hb_position_t *y HB_UNUSED) |
| 77 { return false; } |
| 78 |
| 79 static hb_position_t |
| 80 hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED, |
| 81 hb_face_t *face HB_UNUSED, |
| 82 const void *user_data HB_UNUSED, |
| 83 hb_codepoint_t first_glyph HB_UNUSED, |
| 84 hb_codepoint_t second_glyph HB_UNUSED) |
| 85 { return 0; } |
| 86 |
| 87 hb_font_funcs_t _hb_font_funcs_nil = { |
| 88 HB_REFERENCE_COUNT_INVALID, /* ref_count */ |
| 89 TRUE, /* immutable */ |
| 90 { |
| 91 hb_font_get_glyph_nil, |
| 92 hb_font_get_glyph_advance_nil, |
| 93 hb_font_get_glyph_extents_nil, |
| 94 hb_font_get_contour_point_nil, |
| 95 hb_font_get_kerning_nil |
| 96 } |
| 97 }; |
| 98 |
| 99 hb_font_funcs_t * |
| 100 hb_font_funcs_create (void) |
| 101 { |
| 102 hb_font_funcs_t *ffuncs; |
| 103 |
| 104 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) |
| 105 return &_hb_font_funcs_nil; |
| 106 |
| 107 ffuncs->v = _hb_font_funcs_nil.v; |
| 108 |
| 109 return ffuncs; |
| 110 } |
| 111 |
| 112 hb_font_funcs_t * |
| 113 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) |
| 114 { |
| 115 HB_OBJECT_DO_REFERENCE (ffuncs); |
| 116 } |
| 117 |
| 118 unsigned int |
| 119 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs) |
| 120 { |
| 121 HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs); |
| 122 } |
| 123 |
| 124 void |
| 125 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) |
| 126 { |
| 127 HB_OBJECT_DO_DESTROY (ffuncs); |
| 128 |
| 129 free (ffuncs); |
| 130 } |
| 131 |
| 132 hb_font_funcs_t * |
| 133 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs) |
| 134 { |
| 135 hb_font_funcs_t *ffuncs; |
| 136 |
| 137 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) |
| 138 return &_hb_font_funcs_nil; |
| 139 |
| 140 ffuncs->v = other_ffuncs->v; |
| 141 |
| 142 return ffuncs; |
| 143 } |
| 144 |
| 145 void |
| 146 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) |
| 147 { |
| 148 if (HB_OBJECT_IS_INERT (ffuncs)) |
| 149 return; |
| 150 |
| 151 ffuncs->immutable = TRUE; |
| 152 } |
| 153 |
| 154 hb_bool_t |
| 155 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) |
| 156 { |
| 157 return ffuncs->immutable; |
| 158 } |
| 159 |
| 160 |
| 161 void |
| 162 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, |
| 163 hb_font_get_glyph_func_t glyph_func) |
| 164 { |
| 165 if (ffuncs->immutable) |
| 166 return; |
| 167 |
| 168 ffuncs->v.get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil; |
| 169 } |
| 170 |
| 171 void |
| 172 hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs, |
| 173 hb_font_get_glyph_advance_func_t glyph_adv
ance_func) |
| 174 { |
| 175 if (ffuncs->immutable) |
| 176 return; |
| 177 |
| 178 ffuncs->v.get_glyph_advance = glyph_advance_func ? glyph_advance_func : hb_fon
t_get_glyph_advance_nil; |
| 179 } |
| 180 |
| 181 void |
| 182 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, |
| 183 hb_font_get_glyph_extents_func_t glyph_ext
ents_func) |
| 184 { |
| 185 if (ffuncs->immutable) |
| 186 return; |
| 187 |
| 188 ffuncs->v.get_glyph_extents = glyph_extents_func ? glyph_extents_func : hb_fon
t_get_glyph_extents_nil; |
| 189 } |
| 190 |
| 191 void |
| 192 hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs, |
| 193 hb_font_get_contour_point_func_t contour_p
oint_func) |
| 194 { |
| 195 if (ffuncs->immutable) |
| 196 return; |
| 197 |
| 198 ffuncs->v.get_contour_point = contour_point_func ? contour_point_func : hb_fon
t_get_contour_point_nil; |
| 199 } |
| 200 |
| 201 void |
| 202 hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs, |
| 203 hb_font_get_kerning_func_t kerning_func) |
| 204 { |
| 205 if (ffuncs->immutable) |
| 206 return; |
| 207 |
| 208 ffuncs->v.get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil; |
| 209 } |
| 210 |
| 211 |
| 212 hb_font_get_glyph_func_t |
| 213 hb_font_funcs_get_glyph_func (hb_font_funcs_t *ffuncs) |
| 214 { |
| 215 return ffuncs->v.get_glyph; |
| 216 } |
| 217 |
| 218 hb_font_get_glyph_advance_func_t |
| 219 hb_font_funcs_get_glyph_advance_func (hb_font_funcs_t *ffuncs) |
| 220 { |
| 221 return ffuncs->v.get_glyph_advance; |
| 222 } |
| 223 |
| 224 hb_font_get_glyph_extents_func_t |
| 225 hb_font_funcs_get_glyph_extents_func (hb_font_funcs_t *ffuncs) |
| 226 { |
| 227 return ffuncs->v.get_glyph_extents; |
| 228 } |
| 229 |
| 230 hb_font_get_contour_point_func_t |
| 231 hb_font_funcs_get_contour_point_func (hb_font_funcs_t *ffuncs) |
| 232 { |
| 233 return ffuncs->v.get_contour_point; |
| 234 } |
| 235 |
| 236 hb_font_get_kerning_func_t |
| 237 hb_font_funcs_get_kerning_func (hb_font_funcs_t *ffuncs) |
| 238 { |
| 239 return ffuncs->v.get_kerning; |
| 240 } |
| 241 |
| 242 |
| 243 |
| 244 hb_codepoint_t |
| 245 hb_font_get_glyph (hb_font_t *font, hb_face_t *face, |
| 246 hb_codepoint_t unicode, hb_codepoint_t variation_selector) |
| 247 { |
| 248 return font->klass->v.get_glyph (font, face, font->user_data, |
| 249 unicode, variation_selector); |
| 250 } |
| 251 |
| 252 void |
| 253 hb_font_get_glyph_advance (hb_font_t *font, hb_face_t *face, |
| 254 hb_codepoint_t glyph, |
| 255 hb_position_t *x_advance, hb_position_t *y_advance) |
| 256 { |
| 257 *x_advance = *y_advance = 0; |
| 258 return font->klass->v.get_glyph_advance (font, face, font->user_data, |
| 259 glyph, x_advance, y_advance); |
| 260 } |
| 261 |
| 262 void |
| 263 hb_font_get_glyph_extents (hb_font_t *font, hb_face_t *face, |
| 264 hb_codepoint_t glyph, hb_glyph_extents_t *extents) |
| 265 { |
| 266 memset (extents, 0, sizeof (*extents)); |
| 267 return font->klass->v.get_glyph_extents (font, face, font->user_data, |
| 268 glyph, extents); |
| 269 } |
| 270 |
| 271 hb_bool_t |
| 272 hb_font_get_contour_point (hb_font_t *font, hb_face_t *face, |
| 273 unsigned int point_index, |
| 274 hb_codepoint_t glyph, hb_position_t *x, hb_position_t
*y) |
| 275 { |
| 276 *x = 0; *y = 0; |
| 277 return font->klass->v.get_contour_point (font, face, font->user_data, |
| 278 point_index, |
| 279 glyph, x, y); |
| 280 } |
| 281 |
| 282 hb_position_t |
| 283 hb_font_get_kerning (hb_font_t *font, hb_face_t *face, |
| 284 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph) |
| 285 { |
| 286 return font->klass->v.get_kerning (font, face, font->user_data, |
| 287 first_glyph, second_glyph); |
| 288 } |
| 289 |
| 290 |
| 291 /* |
| 292 * hb_face_t |
| 293 */ |
| 294 |
| 295 static hb_face_t _hb_face_nil = { |
| 296 HB_REFERENCE_COUNT_INVALID, /* ref_count */ |
| 297 |
| 298 NULL, /* get_table */ |
| 299 NULL, /* destroy */ |
| 300 NULL, /* user_data */ |
| 301 |
| 302 NULL, /* head_blob */ |
| 303 NULL, /* head_table */ |
| 304 |
| 305 NULL /* ot_layout */ |
| 306 }; |
| 307 |
| 308 |
| 309 hb_face_t * |
| 310 hb_face_create_for_tables (hb_get_table_func_t get_table, |
| 311 hb_destroy_func_t destroy, |
| 312 void *user_data) |
| 313 { |
| 314 hb_face_t *face; |
| 315 |
| 316 if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) { |
| 317 if (destroy) |
| 318 destroy (user_data); |
| 319 return &_hb_face_nil; |
| 320 } |
| 321 |
| 322 face->get_table = get_table; |
| 323 face->destroy = destroy; |
| 324 face->user_data = user_data; |
| 325 |
| 326 face->ot_layout = _hb_ot_layout_new (face); |
| 327 |
| 328 face->head_blob = Sanitizer<head>::sanitize (hb_face_get_table (face, HB_OT_TA
G_head)); |
| 329 face->head_table = Sanitizer<head>::lock_instance (face->head_blob); |
| 330 |
| 331 return face; |
| 332 } |
| 333 |
| 334 |
| 335 typedef struct _hb_face_for_data_closure_t { |
| 336 hb_blob_t *blob; |
| 337 unsigned int index; |
| 338 } hb_face_for_data_closure_t; |
| 339 |
| 340 static hb_face_for_data_closure_t * |
| 341 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) |
| 342 { |
| 343 hb_face_for_data_closure_t *closure; |
| 344 |
| 345 closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_clos
ure_t)); |
| 346 if (unlikely (!closure)) |
| 347 return NULL; |
| 348 |
| 349 closure->blob = blob; |
| 350 closure->index = index; |
| 351 |
| 352 return closure; |
| 353 } |
| 354 |
| 355 static void |
| 356 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) |
| 357 { |
| 358 hb_blob_destroy (closure->blob); |
| 359 free (closure); |
| 360 } |
| 361 |
| 362 static hb_blob_t * |
| 363 _hb_face_for_data_get_table (hb_tag_t tag, void *user_data) |
| 364 { |
| 365 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; |
| 366 |
| 367 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); |
| 368 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); |
| 369 |
| 370 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); |
| 371 |
| 372 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); |
| 373 |
| 374 hb_blob_unlock (data->blob); |
| 375 |
| 376 return blob; |
| 377 } |
| 378 |
| 379 hb_face_t * |
| 380 hb_face_create_for_data (hb_blob_t *blob, |
| 381 unsigned int index) |
| 382 { |
| 383 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); |
| 384 |
| 385 if (unlikely (!closure)) |
| 386 return &_hb_face_nil; |
| 387 |
| 388 return hb_face_create_for_tables (_hb_face_for_data_get_table, |
| 389 (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy, |
| 390 closure); |
| 391 } |
| 392 |
| 393 |
| 394 hb_face_t * |
| 395 hb_face_reference (hb_face_t *face) |
| 396 { |
| 397 HB_OBJECT_DO_REFERENCE (face); |
| 398 } |
| 399 |
| 400 unsigned int |
| 401 hb_face_get_reference_count (hb_face_t *face) |
| 402 { |
| 403 HB_OBJECT_DO_GET_REFERENCE_COUNT (face); |
| 404 } |
| 405 |
| 406 void |
| 407 hb_face_destroy (hb_face_t *face) |
| 408 { |
| 409 HB_OBJECT_DO_DESTROY (face); |
| 410 |
| 411 _hb_ot_layout_free (face->ot_layout); |
| 412 |
| 413 hb_blob_unlock (face->head_blob); |
| 414 hb_blob_destroy (face->head_blob); |
| 415 |
| 416 if (face->destroy) |
| 417 face->destroy (face->user_data); |
| 418 |
| 419 free (face); |
| 420 } |
| 421 |
| 422 hb_blob_t * |
| 423 hb_face_get_table (hb_face_t *face, |
| 424 hb_tag_t tag) |
| 425 { |
| 426 hb_blob_t *blob; |
| 427 |
| 428 if (unlikely (!face || !face->get_table)) |
| 429 return &_hb_blob_nil; |
| 430 |
| 431 blob = face->get_table (tag, face->user_data); |
| 432 |
| 433 return blob; |
| 434 } |
| 435 |
| 436 unsigned int |
| 437 hb_face_get_upem (hb_face_t *face) |
| 438 { |
| 439 return (face->head_table ? face->head_table : &Null(head))->get_upem (); |
| 440 } |
| 441 |
| 442 |
| 443 /* |
| 444 * hb_font_t |
| 445 */ |
| 446 |
| 447 static hb_font_t _hb_font_nil = { |
| 448 HB_REFERENCE_COUNT_INVALID, /* ref_count */ |
| 449 |
| 450 0, /* x_scale */ |
| 451 0, /* y_scale */ |
| 452 |
| 453 0, /* x_ppem */ |
| 454 0, /* y_ppem */ |
| 455 |
| 456 NULL, /* klass */ |
| 457 NULL, /* destroy */ |
| 458 NULL /* user_data */ |
| 459 }; |
| 460 |
| 461 hb_font_t * |
| 462 hb_font_create (void) |
| 463 { |
| 464 hb_font_t *font; |
| 465 |
| 466 if (!HB_OBJECT_DO_CREATE (hb_font_t, font)) |
| 467 return &_hb_font_nil; |
| 468 |
| 469 font->klass = &_hb_font_funcs_nil; |
| 470 |
| 471 return font; |
| 472 } |
| 473 |
| 474 hb_font_t * |
| 475 hb_font_reference (hb_font_t *font) |
| 476 { |
| 477 HB_OBJECT_DO_REFERENCE (font); |
| 478 } |
| 479 |
| 480 unsigned int |
| 481 hb_font_get_reference_count (hb_font_t *font) |
| 482 { |
| 483 HB_OBJECT_DO_GET_REFERENCE_COUNT (font); |
| 484 } |
| 485 |
| 486 void |
| 487 hb_font_destroy (hb_font_t *font) |
| 488 { |
| 489 HB_OBJECT_DO_DESTROY (font); |
| 490 |
| 491 hb_font_funcs_destroy (font->klass); |
| 492 if (font->destroy) |
| 493 font->destroy (font->user_data); |
| 494 |
| 495 free (font); |
| 496 } |
| 497 |
| 498 void |
| 499 hb_font_set_funcs (hb_font_t *font, |
| 500 hb_font_funcs_t *klass, |
| 501 hb_destroy_func_t destroy, |
| 502 void *user_data) |
| 503 { |
| 504 if (HB_OBJECT_IS_INERT (font)) |
| 505 return; |
| 506 |
| 507 if (font->destroy) |
| 508 font->destroy (font->user_data); |
| 509 |
| 510 if (!klass) |
| 511 klass = &_hb_font_funcs_nil; |
| 512 |
| 513 hb_font_funcs_reference (klass); |
| 514 hb_font_funcs_destroy (font->klass); |
| 515 font->klass = klass; |
| 516 font->destroy = destroy; |
| 517 font->user_data = user_data; |
| 518 } |
| 519 |
| 520 void |
| 521 hb_font_unset_funcs (hb_font_t *font, |
| 522 hb_font_funcs_t **klass, |
| 523 hb_destroy_func_t *destroy, |
| 524 void **user_data) |
| 525 { |
| 526 /* None of the input arguments can be NULL. */ |
| 527 |
| 528 *klass = font->klass; |
| 529 *destroy = font->destroy; |
| 530 *user_data = font->user_data; |
| 531 |
| 532 if (HB_OBJECT_IS_INERT (font)) |
| 533 return; |
| 534 |
| 535 font->klass = NULL; |
| 536 font->destroy = NULL; |
| 537 font->user_data = NULL; |
| 538 } |
| 539 |
| 540 void |
| 541 hb_font_set_scale (hb_font_t *font, |
| 542 unsigned int x_scale, |
| 543 unsigned int y_scale) |
| 544 { |
| 545 if (HB_OBJECT_IS_INERT (font)) |
| 546 return; |
| 547 |
| 548 font->x_scale = x_scale; |
| 549 font->y_scale = y_scale; |
| 550 } |
| 551 |
| 552 void |
| 553 hb_font_get_scale (hb_font_t *font, |
| 554 unsigned int *x_scale, |
| 555 unsigned int *y_scale) |
| 556 { |
| 557 if (x_scale) *x_scale = font->x_scale; |
| 558 if (y_scale) *y_scale = font->y_scale; |
| 559 } |
| 560 |
| 561 void |
| 562 hb_font_set_ppem (hb_font_t *font, |
| 563 unsigned int x_ppem, |
| 564 unsigned int y_ppem) |
| 565 { |
| 566 if (HB_OBJECT_IS_INERT (font)) |
| 567 return; |
| 568 |
| 569 font->x_ppem = x_ppem; |
| 570 font->y_ppem = y_ppem; |
| 571 } |
| 572 |
| 573 void |
| 574 hb_font_get_ppem (hb_font_t *font, |
| 575 unsigned int *x_ppem, |
| 576 unsigned int *y_ppem) |
| 577 { |
| 578 if (x_ppem) *x_ppem = font->x_ppem; |
| 579 if (y_ppem) *y_ppem = font->y_ppem; |
| 580 } |
| 581 |
| 582 |
| 583 HB_END_DECLS |
OLD | NEW |