hb-font.cc 33.5 KB
Newer Older
1
/*
B
Behdad Esfahbod 已提交
2
 * Copyright © 2009  Red Hat, Inc.
3
 * Copyright © 2012  Google, Inc.
4
 *
B
Behdad Esfahbod 已提交
5
 *  This is part of HarfBuzz, a text shaping library.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
26
 * Google Author(s): Behdad Esfahbod
27 28
 */

29
#include "hb-private.hh"
30

31 32
#include "hb-ot-layout-private.hh"

33
#include "hb-font-private.hh"
34
#include "hb-open-file-private.hh"
35
#include "hb-ot-head-table.hh"
B
Behdad Esfahbod 已提交
36
#include "hb-ot-maxp-table.hh"
37

38 39
#include "hb-cache-private.hh"

B
Behdad Esfahbod 已提交
40 41
#include <string.h>

B
Behdad Esfahbod 已提交
42

43
/*
B
Behdad Esfahbod 已提交
44
 * hb_font_funcs_t
45 46
 */

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
static hb_bool_t
hb_font_get_font_h_extents_nil (hb_font_t *font,
				void *font_data HB_UNUSED,
				hb_font_extents_t *metrics,
				void *user_data HB_UNUSED)
{
  memset (metrics, 0, sizeof (*metrics));
  return false;
}
static hb_bool_t
hb_font_get_font_h_extents_parent (hb_font_t *font,
				   void *font_data HB_UNUSED,
				   hb_font_extents_t *metrics,
				   void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_font_h_extents (metrics);
  if (ret) {
    metrics->ascender = font->parent_scale_y_distance (metrics->ascender);
    metrics->descender = font->parent_scale_y_distance (metrics->descender);
    metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap);
  }
  return ret;
}

static hb_bool_t
hb_font_get_font_v_extents_nil (hb_font_t *font,
				void *font_data HB_UNUSED,
				hb_font_extents_t *metrics,
				void *user_data HB_UNUSED)
{
  memset (metrics, 0, sizeof (*metrics));
  return false;
}
static hb_bool_t
hb_font_get_font_v_extents_parent (hb_font_t *font,
				   void *font_data HB_UNUSED,
				   hb_font_extents_t *metrics,
				   void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_font_v_extents (metrics);
  if (ret) {
    metrics->ascender = font->parent_scale_x_distance (metrics->ascender);
    metrics->descender = font->parent_scale_x_distance (metrics->descender);
    metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap);
  }
  return ret;
}

95
static hb_bool_t
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED,
			       void *font_data HB_UNUSED,
			       hb_codepoint_t unicode,
			       hb_codepoint_t *glyph,
			       void *user_data HB_UNUSED)
{
  *glyph = 0;
  return false;
}
static hb_bool_t
hb_font_get_nominal_glyph_parent (hb_font_t *font,
				  void *font_data HB_UNUSED,
				  hb_codepoint_t unicode,
				  hb_codepoint_t *glyph,
				  void *user_data HB_UNUSED)
{
  return font->parent->get_nominal_glyph (unicode, glyph);
}

static hb_bool_t
hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
				 void *font_data HB_UNUSED,
				 hb_codepoint_t unicode,
				 hb_codepoint_t variation_selector,
				 hb_codepoint_t *glyph,
				 void *user_data HB_UNUSED)
122 123
{
  *glyph = 0;
124
  return false;
125
}
126
static hb_bool_t
127 128 129 130 131 132
hb_font_get_variation_glyph_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    hb_codepoint_t unicode,
				    hb_codepoint_t variation_selector,
				    hb_codepoint_t *glyph,
				    void *user_data HB_UNUSED)
133
{
134
  return font->parent->get_variation_glyph (unicode, variation_selector, glyph);
135
}
136

137

138
static hb_position_t
139
hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
140 141 142
				 void *font_data HB_UNUSED,
				 hb_codepoint_t glyph,
				 void *user_data HB_UNUSED)
143
{
144
  return font->x_scale;
145
}
146 147 148 149 150 151 152 153
static hb_position_t
hb_font_get_glyph_h_advance_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    hb_codepoint_t glyph,
				    void *user_data HB_UNUSED)
{
  return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
}
B
Behdad Esfahbod 已提交
154

155
static hb_position_t
156
hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
157 158 159
				 void *font_data HB_UNUSED,
				 hb_codepoint_t glyph,
				 void *user_data HB_UNUSED)
160
{
161
  return font->y_scale;
162
}
163 164 165 166 167 168 169 170
static hb_position_t
hb_font_get_glyph_v_advance_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    hb_codepoint_t glyph,
				    void *user_data HB_UNUSED)
{
  return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
}
171

B
Behdad Esfahbod 已提交
172
static hb_bool_t
173
hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED,
B
Behdad Esfahbod 已提交
174 175
				void *font_data HB_UNUSED,
				hb_codepoint_t glyph,
B
Behdad Esfahbod 已提交
176 177
				hb_position_t *x,
				hb_position_t *y,
B
Behdad Esfahbod 已提交
178 179
				void *user_data HB_UNUSED)
{
B
Behdad Esfahbod 已提交
180
  *x = *y = 0;
181
  return true;
B
Behdad Esfahbod 已提交
182
}
183 184 185 186 187 188 189 190 191 192 193 194 195
static hb_bool_t
hb_font_get_glyph_h_origin_parent (hb_font_t *font,
				   void *font_data HB_UNUSED,
				   hb_codepoint_t glyph,
				   hb_position_t *x,
				   hb_position_t *y,
				   void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y);
  if (ret)
    font->parent_scale_position (x, y);
  return ret;
}
B
Behdad Esfahbod 已提交
196

197
static hb_bool_t
198
hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
199 200
				void *font_data HB_UNUSED,
				hb_codepoint_t glyph,
B
Behdad Esfahbod 已提交
201 202
				hb_position_t *x,
				hb_position_t *y,
203 204
				void *user_data HB_UNUSED)
{
B
Behdad Esfahbod 已提交
205
  *x = *y = 0;
206
  return false;
207
}
208 209 210 211 212 213 214 215 216 217 218 219 220
static hb_bool_t
hb_font_get_glyph_v_origin_parent (hb_font_t *font,
				   void *font_data HB_UNUSED,
				   hb_codepoint_t glyph,
				   hb_position_t *x,
				   hb_position_t *y,
				   void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y);
  if (ret)
    font->parent_scale_position (x, y);
  return ret;
}
221

222
static hb_position_t
223
hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
B
Behdad Esfahbod 已提交
224 225 226 227
				 void *font_data HB_UNUSED,
				 hb_codepoint_t left_glyph,
				 hb_codepoint_t right_glyph,
				 void *user_data HB_UNUSED)
228
{
229
  return 0;
230
}
231 232 233 234 235 236 237 238 239
static hb_position_t
hb_font_get_glyph_h_kerning_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    hb_codepoint_t left_glyph,
				    hb_codepoint_t right_glyph,
				    void *user_data HB_UNUSED)
{
  return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
}
240

241
static hb_position_t
242
hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
B
Behdad Esfahbod 已提交
243 244 245 246
				 void *font_data HB_UNUSED,
				 hb_codepoint_t top_glyph,
				 hb_codepoint_t bottom_glyph,
				 void *user_data HB_UNUSED)
247
{
248
  return 0;
249
}
250 251 252 253 254 255 256 257 258
static hb_position_t
hb_font_get_glyph_v_kerning_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    hb_codepoint_t top_glyph,
				    hb_codepoint_t bottom_glyph,
				    void *user_data HB_UNUSED)
{
  return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
}
B
Behdad Esfahbod 已提交
259

260
static hb_bool_t
261
hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
262
			       void *font_data HB_UNUSED,
263 264
			       hb_codepoint_t glyph,
			       hb_glyph_extents_t *extents,
265
			       void *user_data HB_UNUSED)
266
{
267
  memset (extents, 0, sizeof (*extents));
268
  return false;
269
}
270 271 272 273 274 275 276 277 278 279 280 281 282 283
static hb_bool_t
hb_font_get_glyph_extents_parent (hb_font_t *font,
				  void *font_data HB_UNUSED,
				  hb_codepoint_t glyph,
				  hb_glyph_extents_t *extents,
				  void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents);
  if (ret) {
    font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
    font->parent_scale_distance (&extents->width, &extents->height);
  }
  return ret;
}
284

285
static hb_bool_t
286
hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED,
B
Behdad Esfahbod 已提交
287 288 289 290 291 292
				     void *font_data HB_UNUSED,
				     hb_codepoint_t glyph,
				     unsigned int point_index,
				     hb_position_t *x,
				     hb_position_t *y,
				     void *user_data HB_UNUSED)
293
{
294
  *x = *y = 0;
295
  return false;
296
}
297 298 299 300 301 302 303 304 305 306 307 308 309 310
static hb_bool_t
hb_font_get_glyph_contour_point_parent (hb_font_t *font,
					void *font_data HB_UNUSED,
					hb_codepoint_t glyph,
					unsigned int point_index,
					hb_position_t *x,
					hb_position_t *y,
					void *user_data HB_UNUSED)
{
  hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y);
  if (ret)
    font->parent_scale_position (x, y);
  return ret;
}
B
Behdad Esfahbod 已提交
311

312
static hb_bool_t
313
hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED,
314 315 316 317 318
			    void *font_data HB_UNUSED,
			    hb_codepoint_t glyph,
			    char *name, unsigned int size,
			    void *user_data HB_UNUSED)
{
319
  if (size) *name = '\0';
320
  return false;
321
}
322 323 324 325 326 327 328 329 330
static hb_bool_t
hb_font_get_glyph_name_parent (hb_font_t *font,
			       void *font_data HB_UNUSED,
			       hb_codepoint_t glyph,
			       char *name, unsigned int size,
			       void *user_data HB_UNUSED)
{
  return font->parent->get_glyph_name (glyph, name, size);
}
331 332

static hb_bool_t
333
hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED,
334 335 336 337 338 339
				 void *font_data HB_UNUSED,
				 const char *name, int len, /* -1 means nul-terminated */
				 hb_codepoint_t *glyph,
				 void *user_data HB_UNUSED)
{
  *glyph = 0;
340
  return false;
341
}
342 343 344 345 346 347 348 349 350
static hb_bool_t
hb_font_get_glyph_from_name_parent (hb_font_t *font,
				    void *font_data HB_UNUSED,
				    const char *name, int len, /* -1 means nul-terminated */
				    hb_codepoint_t *glyph,
				    void *user_data HB_UNUSED)
{
  return font->parent->get_glyph_from_name (name, len, glyph);
}
351

352
static const hb_font_funcs_t _hb_font_funcs_nil = {
353 354
  HB_OBJECT_HEADER_STATIC,

355
  true, /* immutable */
356

357 358 359 360 361 362 363 364 365 366
  {
#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
  },
  {
#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
  },
367
  {
368
    {
369
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
370
      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
371
#undef HB_FONT_FUNC_IMPLEMENT
372
    }
373
  }
374
};
375 376 377 378 379
static const hb_font_funcs_t _hb_font_funcs_parent = {
  HB_OBJECT_HEADER_STATIC,

  true, /* immutable */

380 381 382 383 384 385 386 387 388 389
  {
#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
  },
  {
#define HB_FONT_FUNC_IMPLEMENT(name) NULL,
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
  },
390
  {
391
    {
392
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent,
393
      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
394
#undef HB_FONT_FUNC_IMPLEMENT
395
    }
396 397
  }
};
398

B
Behdad Esfahbod 已提交
399

400
/**
401
 * hb_font_funcs_create: (Xconstructor)
402 403 404 405 406
 *
 * 
 *
 * Return value: (transfer full): 
 *
407
 * Since: 0.9.2
408
 **/
B
Behdad Esfahbod 已提交
409 410
hb_font_funcs_t *
hb_font_funcs_create (void)
411
{
B
Behdad Esfahbod 已提交
412
  hb_font_funcs_t *ffuncs;
413

414
  if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
415
    return hb_font_funcs_get_empty ();
416

417
  ffuncs->get = _hb_font_funcs_parent.get;
418

B
Behdad Esfahbod 已提交
419
  return ffuncs;
420 421
}

422 423 424 425 426 427 428
/**
 * hb_font_funcs_get_empty:
 *
 * 
 *
 * Return value: (transfer full): 
 *
429
 * Since: 0.9.2
430
 **/
431 432 433
hb_font_funcs_t *
hb_font_funcs_get_empty (void)
{
434
  return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent);
435 436
}

437 438 439 440 441 442 443 444
/**
 * hb_font_funcs_reference: (skip)
 * @ffuncs: font functions.
 *
 * 
 *
 * Return value: 
 *
445
 * Since: 0.9.2
446
 **/
B
Behdad Esfahbod 已提交
447 448
hb_font_funcs_t *
hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
449
{
450
  return hb_object_reference (ffuncs);
451 452
}

453 454 455 456 457 458
/**
 * hb_font_funcs_destroy: (skip)
 * @ffuncs: font functions.
 *
 * 
 *
459
 * Since: 0.9.2
460
 **/
461
void
B
Behdad Esfahbod 已提交
462
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
463
{
464
  if (!hb_object_destroy (ffuncs)) return;
465

B
Behdad Esfahbod 已提交
466 467
#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \
  ffuncs->destroy.name (ffuncs->user_data.name);
468 469
  HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
470

B
Behdad Esfahbod 已提交
471
  free (ffuncs);
472 473
}

474 475 476 477 478 479 480 481 482 483 484 485
/**
 * hb_font_funcs_set_user_data: (skip)
 * @ffuncs: font functions.
 * @key: 
 * @data: 
 * @destroy: 
 * @replace: 
 *
 * 
 *
 * Return value: 
 *
486
 * Since: 0.9.2
487
 **/
488 489 490 491
hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
			     hb_user_data_key_t *key,
			     void *              data,
492 493
			     hb_destroy_func_t   destroy,
			     hb_bool_t           replace)
494
{
495
  return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
496 497
}

498 499 500 501 502 503 504 505 506
/**
 * hb_font_funcs_get_user_data: (skip)
 * @ffuncs: font functions.
 * @key: 
 *
 * 
 *
 * Return value: (transfer none): 
 *
507
 * Since: 0.9.2
508
 **/
509 510 511 512 513 514 515 516
void *
hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
			     hb_user_data_key_t *key)
{
  return hb_object_get_user_data (ffuncs, key);
}


517 518 519 520 521 522
/**
 * hb_font_funcs_make_immutable:
 * @ffuncs: font functions.
 *
 * 
 *
523
 * Since: 0.9.2
524
 **/
525 526 527
void
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
{
528
  if (unlikely (hb_object_is_inert (ffuncs)))
529 530
    return;

531
  ffuncs->immutable = true;
B
Behdad Esfahbod 已提交
532 533
}

534 535 536 537 538 539 540 541
/**
 * hb_font_funcs_is_immutable:
 * @ffuncs: font functions.
 *
 * 
 *
 * Return value: 
 *
542
 * Since: 0.9.2
543
 **/
B
Behdad Esfahbod 已提交
544 545 546
hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
{
B
Behdad Esfahbod 已提交
547
  return ffuncs->immutable;
548 549
}

550

551
#define HB_FONT_FUNC_IMPLEMENT(name) \
552 553 554 555 556 557 558
                                                                         \
void                                                                     \
hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
                                 hb_font_get_##name##_func_t  func,      \
                                 void                        *user_data, \
                                 hb_destroy_func_t            destroy)   \
{                                                                        \
B
Behdad Esfahbod 已提交
559 560 561
  if (ffuncs->immutable) {                                               \
    if (destroy)                                                         \
      destroy (user_data);                                               \
562
    return;                                                              \
B
Behdad Esfahbod 已提交
563
  }                                                                      \
564 565 566 567 568
                                                                         \
  if (ffuncs->destroy.name)                                              \
    ffuncs->destroy.name (ffuncs->user_data.name);                       \
                                                                         \
  if (func) {                                                            \
569
    ffuncs->get.f.name = func;                                           \
570 571 572
    ffuncs->user_data.name = user_data;                                  \
    ffuncs->destroy.name = destroy;                                      \
  } else {                                                               \
573
    ffuncs->get.f.name = hb_font_get_##name##_parent;                    \
574 575 576
    ffuncs->user_data.name = NULL;                                       \
    ffuncs->destroy.name = NULL;                                         \
  }                                                                      \
B
Behdad Esfahbod 已提交
577 578
}

579 580 581
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT

582 583 584 585 586 587 588
bool
hb_font_t::has_func (unsigned int i)
{
  if (parent && parent != hb_font_get_empty () && parent->has_func (i))
    return true;
  return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i];
}
589

B
Behdad Esfahbod 已提交
590 591
/* Public getters */

592 593 594 595 596 597 598 599 600
/**
 * hb_font_get_h_extents:
 * @font: a font.
 * @extents: (out):
 *
 *
 *
 * Return value:
 *
B
Behdad Esfahbod 已提交
601
 * Since: 1.1.3
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
 **/
hb_bool_t
hb_font_get_h_extents (hb_font_t *font,
		       hb_font_extents_t *extents)
{
  return font->get_font_h_extents (extents);
}

/**
 * hb_font_get_v_extents:
 * @font: a font.
 * @extents: (out):
 *
 *
 *
 * Return value:
 *
B
Behdad Esfahbod 已提交
619
 * Since: 1.1.3
620 621 622 623 624 625 626 627
 **/
hb_bool_t
hb_font_get_v_extents (hb_font_t *font,
		       hb_font_extents_t *extents)
{
  return font->get_font_v_extents (extents);
}

628 629 630 631 632 633 634 635 636 637 638
/**
 * hb_font_get_glyph:
 * @font: a font.
 * @unicode: 
 * @variation_selector: 
 * @glyph: (out): 
 *
 * 
 *
 * Return value: 
 *
639
 * Since: 0.9.2
640
 **/
641 642 643 644 645
hb_bool_t
hb_font_get_glyph (hb_font_t *font,
		   hb_codepoint_t unicode, hb_codepoint_t variation_selector,
		   hb_codepoint_t *glyph)
{
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
  if (unlikely (variation_selector))
    return font->get_variation_glyph (unicode, variation_selector, glyph);
  return font->get_nominal_glyph (unicode, glyph);
}

/**
 * hb_font_get_nominal_glyph:
 * @font: a font.
 * @unicode: 
 * @glyph: (out): 
 *
 * 
 *
 * Return value: 
 *
 * Since: 1.2.3
 **/
hb_bool_t
hb_font_get_nominal_glyph (hb_font_t *font,
			   hb_codepoint_t unicode,
			   hb_codepoint_t *glyph)
{
  return font->get_nominal_glyph (unicode, glyph);
}

/**
 * hb_font_get_variation_glyph:
 * @font: a font.
 * @unicode: 
 * @variation_selector: 
 * @glyph: (out): 
 *
 * 
 *
 * Return value: 
 *
 * Since: 1.2.3
 **/
hb_bool_t
hb_font_get_variation_glyph (hb_font_t *font,
			     hb_codepoint_t unicode, hb_codepoint_t variation_selector,
			     hb_codepoint_t *glyph)
{
  return font->get_variation_glyph (unicode, variation_selector, glyph);
690 691
}

692 693 694 695 696 697 698 699 700
/**
 * hb_font_get_glyph_h_advance:
 * @font: a font.
 * @glyph: 
 *
 * 
 *
 * Return value: 
 *
701
 * Since: 0.9.2
702
 **/
703
hb_position_t
704
hb_font_get_glyph_h_advance (hb_font_t *font,
705
			     hb_codepoint_t glyph)
706
{
B
Behdad Esfahbod 已提交
707
  return font->get_glyph_h_advance (glyph);
708 709
}

710 711 712 713 714 715 716 717 718
/**
 * hb_font_get_glyph_v_advance:
 * @font: a font.
 * @glyph: 
 *
 * 
 *
 * Return value: 
 *
719
 * Since: 0.9.2
720
 **/
721
hb_position_t
722
hb_font_get_glyph_v_advance (hb_font_t *font,
723
			     hb_codepoint_t glyph)
724
{
B
Behdad Esfahbod 已提交
725
  return font->get_glyph_v_advance (glyph);
726 727
}

728 729 730 731 732 733 734 735 736 737 738
/**
 * hb_font_get_glyph_h_origin:
 * @font: a font.
 * @glyph: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
 * Return value: 
 *
739
 * Since: 0.9.2
740
 **/
B
Behdad Esfahbod 已提交
741 742 743
hb_bool_t
hb_font_get_glyph_h_origin (hb_font_t *font,
			    hb_codepoint_t glyph,
B
Behdad Esfahbod 已提交
744
			    hb_position_t *x, hb_position_t *y)
B
Behdad Esfahbod 已提交
745
{
B
Behdad Esfahbod 已提交
746
  return font->get_glyph_h_origin (glyph, x, y);
B
Behdad Esfahbod 已提交
747 748
}

749 750 751 752 753 754 755 756 757 758 759
/**
 * hb_font_get_glyph_v_origin:
 * @font: a font.
 * @glyph: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
 * Return value: 
 *
760
 * Since: 0.9.2
761
 **/
762 763 764
hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
			    hb_codepoint_t glyph,
B
Behdad Esfahbod 已提交
765
			    hb_position_t *x, hb_position_t *y)
766
{
B
Behdad Esfahbod 已提交
767
  return font->get_glyph_v_origin (glyph, x, y);
768 769
}

770 771 772 773 774 775 776 777 778 779
/**
 * hb_font_get_glyph_h_kerning:
 * @font: a font.
 * @left_glyph: 
 * @right_glyph: 
 *
 * 
 *
 * Return value: 
 *
780
 * Since: 0.9.2
781
 **/
782
hb_position_t
B
Behdad Esfahbod 已提交
783
hb_font_get_glyph_h_kerning (hb_font_t *font,
784
			     hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
785
{
B
Behdad Esfahbod 已提交
786
  return font->get_glyph_h_kerning (left_glyph, right_glyph);
787
}
B
Behdad Esfahbod 已提交
788

789 790 791 792 793 794 795 796 797 798
/**
 * hb_font_get_glyph_v_kerning:
 * @font: a font.
 * @top_glyph: 
 * @bottom_glyph: 
 *
 * 
 *
 * Return value: 
 *
799
 * Since: 0.9.2
800
 **/
801
hb_position_t
B
Behdad Esfahbod 已提交
802
hb_font_get_glyph_v_kerning (hb_font_t *font,
803
			     hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
804
{
805
  return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
806
}
B
Behdad Esfahbod 已提交
807

808 809 810 811 812 813 814 815 816 817
/**
 * hb_font_get_glyph_extents:
 * @font: a font.
 * @glyph: 
 * @extents: (out): 
 *
 * 
 *
 * Return value: 
 *
818
 * Since: 0.9.2
819
 **/
820 821 822 823 824
hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
			   hb_codepoint_t glyph,
			   hb_glyph_extents_t *extents)
{
B
Behdad Esfahbod 已提交
825
  return font->get_glyph_extents (glyph, extents);
826
}
827

828 829 830 831 832 833 834 835 836 837 838 839
/**
 * hb_font_get_glyph_contour_point:
 * @font: a font.
 * @glyph: 
 * @point_index: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
 * Return value: 
 *
840
 * Since: 0.9.2
841
 **/
842
hb_bool_t
B
Behdad Esfahbod 已提交
843 844 845
hb_font_get_glyph_contour_point (hb_font_t *font,
				 hb_codepoint_t glyph, unsigned int point_index,
				 hb_position_t *x, hb_position_t *y)
B
Behdad Esfahbod 已提交
846
{
B
Behdad Esfahbod 已提交
847
  return font->get_glyph_contour_point (glyph, point_index, x, y);
B
Behdad Esfahbod 已提交
848 849
}

850 851 852 853 854 855 856 857 858 859 860
/**
 * hb_font_get_glyph_name:
 * @font: a font.
 * @glyph: 
 * @name: (array length=size): 
 * @size: 
 *
 * 
 *
 * Return value: 
 *
S
Sascha Brawer 已提交
861
 * Since: 0.9.2
862
 **/
863 864 865 866 867
hb_bool_t
hb_font_get_glyph_name (hb_font_t *font,
			hb_codepoint_t glyph,
			char *name, unsigned int size)
{
868
  return font->get_glyph_name (glyph, name, size);
869 870
}

871 872 873 874 875 876 877 878 879 880 881
/**
 * hb_font_get_glyph_from_name:
 * @font: a font.
 * @name: (array length=len): 
 * @len: 
 * @glyph: (out): 
 *
 * 
 *
 * Return value: 
 *
S
Sascha Brawer 已提交
882
 * Since: 0.9.2
883
 **/
884 885 886 887 888
hb_bool_t
hb_font_get_glyph_from_name (hb_font_t *font,
			     const char *name, int len, /* -1 means nul-terminated */
			     hb_codepoint_t *glyph)
{
B
Behdad Esfahbod 已提交
889
  return font->get_glyph_from_name (name, len, glyph);
890 891
}

892 893 894

/* A bit higher-level, and with fallback */

895 896 897 898 899 900 901 902
/**
 * hb_font_get_extents_for_direction:
 * @font: a font.
 * @direction:
 * @extents:
 *
 *
 *
B
Behdad Esfahbod 已提交
903
 * Since: 1.1.3
904 905 906 907 908 909 910 911
 **/
void
hb_font_get_extents_for_direction (hb_font_t *font,
				   hb_direction_t direction,
				   hb_font_extents_t *extents)
{
  return font->get_extents_for_direction (direction, extents);
}
912 913 914 915 916 917 918 919 920 921
/**
 * hb_font_get_glyph_advance_for_direction:
 * @font: a font.
 * @glyph: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
922
 * Since: 0.9.2
923
 **/
924
void
925 926 927
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
					 hb_codepoint_t glyph,
					 hb_direction_t direction,
B
Behdad Esfahbod 已提交
928
					 hb_position_t *x, hb_position_t *y)
929
{
B
Behdad Esfahbod 已提交
930
  return font->get_glyph_advance_for_direction (glyph, direction, x, y);
931 932
}

933 934 935 936 937 938 939 940 941 942
/**
 * hb_font_get_glyph_origin_for_direction:
 * @font: a font.
 * @glyph: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
943
 * Since: 0.9.2
944
 **/
945
void
B
Behdad Esfahbod 已提交
946 947 948
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
					hb_codepoint_t glyph,
					hb_direction_t direction,
B
Behdad Esfahbod 已提交
949
					hb_position_t *x, hb_position_t *y)
B
Behdad Esfahbod 已提交
950
{
B
Behdad Esfahbod 已提交
951
  return font->get_glyph_origin_for_direction (glyph, direction, x, y);
B
Behdad Esfahbod 已提交
952 953
}

954 955 956 957 958 959 960 961 962 963
/**
 * hb_font_add_glyph_origin_for_direction:
 * @font: a font.
 * @glyph: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
964
 * Since: 0.9.2
965
 **/
B
Behdad Esfahbod 已提交
966 967 968 969 970 971
void
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
					hb_codepoint_t glyph,
					hb_direction_t direction,
					hb_position_t *x, hb_position_t *y)
{
B
Behdad Esfahbod 已提交
972
  return font->add_glyph_origin_for_direction (glyph, direction, x, y);
B
Behdad Esfahbod 已提交
973 974
}

975 976 977 978 979 980 981 982 983 984
/**
 * hb_font_subtract_glyph_origin_for_direction:
 * @font: a font.
 * @glyph: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
985
 * Since: 0.9.2
986
 **/
B
Behdad Esfahbod 已提交
987 988 989 990 991 992
void
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
					     hb_codepoint_t glyph,
					     hb_direction_t direction,
					     hb_position_t *x, hb_position_t *y)
{
B
Behdad Esfahbod 已提交
993
  return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
B
Behdad Esfahbod 已提交
994 995
}

996 997 998 999 1000 1001 1002 1003 1004 1005 1006
/**
 * hb_font_get_glyph_kerning_for_direction:
 * @font: a font.
 * @first_glyph: 
 * @second_glyph: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
1007
 * Since: 0.9.2
1008
 **/
B
Behdad Esfahbod 已提交
1009 1010 1011 1012
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
					 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
					 hb_direction_t direction,
B
Behdad Esfahbod 已提交
1013
					 hb_position_t *x, hb_position_t *y)
1014
{
B
Behdad Esfahbod 已提交
1015
  return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
1016 1017
}

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
/**
 * hb_font_get_glyph_extents_for_origin:
 * @font: a font.
 * @glyph: 
 * @direction: 
 * @extents: (out): 
 *
 * 
 *
 * Return value: 
 *
1029
 * Since: 0.9.2
1030
 **/
1031 1032 1033 1034 1035
hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
				      hb_codepoint_t glyph,
				      hb_direction_t direction,
				      hb_glyph_extents_t *extents)
B
Behdad Esfahbod 已提交
1036
{
B
Behdad Esfahbod 已提交
1037
  return font->get_glyph_extents_for_origin (glyph, direction, extents);
B
Behdad Esfahbod 已提交
1038 1039
}

1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
/**
 * hb_font_get_glyph_contour_point_for_origin:
 * @font: a font.
 * @glyph: 
 * @point_index: 
 * @direction: 
 * @x: (out): 
 * @y: (out): 
 *
 * 
 *
 * Return value: 
 *
1053
 * Since: 0.9.2
1054
 **/
1055
hb_bool_t
1056 1057 1058 1059
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
					    hb_codepoint_t glyph, unsigned int point_index,
					    hb_direction_t direction,
					    hb_position_t *x, hb_position_t *y)
B
Behdad Esfahbod 已提交
1060
{
B
Behdad Esfahbod 已提交
1061
  return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y);
B
Behdad Esfahbod 已提交
1062 1063
}

1064
/* Generates gidDDD if glyph has no name. */
1065 1066 1067 1068 1069 1070 1071 1072 1073
/**
 * hb_font_glyph_to_string:
 * @font: a font.
 * @glyph: 
 * @s: (array length=size): 
 * @size: 
 *
 * 
 *
S
Sascha Brawer 已提交
1074
 * Since: 0.9.2
1075
 **/
1076 1077 1078 1079 1080 1081 1082 1083 1084
void
hb_font_glyph_to_string (hb_font_t *font,
			 hb_codepoint_t glyph,
			 char *s, unsigned int size)
{
  font->glyph_to_string (glyph, s, size);
}

/* Parses gidDDD and uniUUUU strings automatically. */
1085 1086 1087
/**
 * hb_font_glyph_from_string:
 * @font: a font.
1088
 * @s: (array length=len) (element-type uint8_t): 
1089 1090 1091 1092 1093 1094 1095
 * @len: 
 * @glyph: (out): 
 *
 * 
 *
 * Return value: 
 *
S
Sascha Brawer 已提交
1096
 * Since: 0.9.2
1097
 **/
1098 1099 1100 1101 1102 1103 1104 1105
hb_bool_t
hb_font_glyph_from_string (hb_font_t *font,
			   const char *s, int len, /* -1 means nul-terminated */
			   hb_codepoint_t *glyph)
{
  return font->glyph_from_string (s, len, glyph);
}

1106

1107 1108 1109 1110
/*
 * hb_font_t
 */

1111
/**
1112
 * hb_font_create: (Xconstructor)
1113 1114 1115 1116 1117 1118
 * @face: a face.
 *
 * 
 *
 * Return value: (transfer full): 
 *
1119
 * Since: 0.9.2
1120
 **/
1121
hb_font_t *
1122
hb_font_create (hb_face_t *face)
1123 1124 1125
{
  hb_font_t *font;

1126
  if (unlikely (!face))
1127
    face = hb_face_get_empty ();
1128
  if (!(font = hb_object_create<hb_font_t> ()))
1129
    return hb_font_get_empty ();
1130

1131
  hb_face_make_immutable (face);
1132
  font->parent = hb_font_get_empty ();
1133
  font->face = hb_face_reference (face);
1134
  font->klass = hb_font_funcs_get_empty ();
B
Behdad Esfahbod 已提交
1135

B
Behdad Esfahbod 已提交
1136 1137
  font->x_scale = font->y_scale = hb_face_get_upem (face);

1138 1139 1140
  return font;
}

1141 1142 1143 1144 1145 1146 1147 1148
/**
 * hb_font_create_sub_font:
 * @parent: parent font.
 *
 * 
 *
 * Return value: (transfer full): 
 *
1149
 * Since: 0.9.2
1150
 **/
1151 1152 1153 1154
hb_font_t *
hb_font_create_sub_font (hb_font_t *parent)
{
  if (unlikely (!parent))
B
Behdad Esfahbod 已提交
1155
    parent = hb_font_get_empty ();
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171

  hb_font_t *font = hb_font_create (parent->face);

  if (unlikely (hb_object_is_inert (font)))
    return font;

  font->parent = hb_font_reference (parent);

  font->x_scale = parent->x_scale;
  font->y_scale = parent->y_scale;
  font->x_ppem = parent->x_ppem;
  font->y_ppem = parent->y_ppem;

  return font;
}

1172 1173 1174 1175 1176 1177 1178
/**
 * hb_font_get_empty:
 *
 * 
 *
 * Return value: (transfer full)
 *
1179
 * Since: 0.9.2
1180
 **/
1181 1182 1183
hb_font_t *
hb_font_get_empty (void)
{
1184 1185 1186
  static const hb_font_t _hb_font_nil = {
    HB_OBJECT_HEADER_STATIC,

1187
    true, /* immutable */
1188 1189 1190 1191

    NULL, /* parent */
    const_cast<hb_face_t *> (&_hb_face_nil),

1192 1193
    1000, /* x_scale */
    1000, /* y_scale */
1194 1195 1196 1197 1198 1199

    0, /* x_ppem */
    0, /* y_ppem */

    const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
    NULL, /* user_data */
1200 1201 1202 1203 1204 1205 1206
    NULL, /* destroy */

    {
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
    }
1207 1208 1209
  };

  return const_cast<hb_font_t *> (&_hb_font_nil);
1210 1211
}

1212 1213 1214 1215 1216 1217 1218 1219
/**
 * hb_font_reference: (skip)
 * @font: a font.
 *
 * 
 *
 * Return value: (transfer full): 
 *
1220
 * Since: 0.9.2
1221
 **/
1222 1223 1224
hb_font_t *
hb_font_reference (hb_font_t *font)
{
1225
  return hb_object_reference (font);
1226 1227
}

1228 1229 1230 1231 1232 1233
/**
 * hb_font_destroy: (skip)
 * @font: a font.
 *
 * 
 *
1234
 * Since: 0.9.2
1235
 **/
1236 1237 1238
void
hb_font_destroy (hb_font_t *font)
{
1239
  if (!hb_object_destroy (font)) return;
1240

1241 1242 1243 1244 1245 1246 1247
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT

  if (font->destroy)
    font->destroy (font->user_data);

1248
  hb_font_destroy (font->parent);
1249
  hb_face_destroy (font->face);
B
Behdad Esfahbod 已提交
1250
  hb_font_funcs_destroy (font->klass);
1251 1252 1253 1254

  free (font);
}

1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
/**
 * hb_font_set_user_data: (skip)
 * @font: a font.
 * @key: 
 * @data: 
 * @destroy: 
 * @replace: 
 *
 * 
 *
 * Return value: 
 *
1267
 * Since: 0.9.2
1268
 **/
1269 1270 1271 1272
hb_bool_t
hb_font_set_user_data (hb_font_t          *font,
		       hb_user_data_key_t *key,
		       void *              data,
1273 1274
		       hb_destroy_func_t   destroy,
		       hb_bool_t           replace)
1275
{
1276
  return hb_object_set_user_data (font, key, data, destroy, replace);
1277 1278
}

1279 1280 1281 1282 1283 1284 1285 1286 1287
/**
 * hb_font_get_user_data: (skip)
 * @font: a font.
 * @key: 
 *
 * 
 *
 * Return value: (transfer none): 
 *
1288
 * Since: 0.9.2
1289
 **/
1290 1291 1292 1293 1294 1295 1296
void *
hb_font_get_user_data (hb_font_t          *font,
		       hb_user_data_key_t *key)
{
  return hb_object_get_user_data (font, key);
}

1297 1298 1299 1300 1301 1302
/**
 * hb_font_make_immutable:
 * @font: a font.
 *
 * 
 *
1303
 * Since: 0.9.2
1304
 **/
1305 1306 1307
void
hb_font_make_immutable (hb_font_t *font)
{
1308
  if (unlikely (hb_object_is_inert (font)))
1309 1310
    return;

1311 1312 1313
  if (font->parent)
    hb_font_make_immutable (font->parent);

1314 1315 1316
  font->immutable = true;
}

1317 1318 1319 1320 1321 1322 1323 1324
/**
 * hb_font_is_immutable:
 * @font: a font.
 *
 * 
 *
 * Return value: 
 *
1325
 * Since: 0.9.2
1326
 **/
1327 1328 1329 1330 1331 1332
hb_bool_t
hb_font_is_immutable (hb_font_t *font)
{
  return font->immutable;
}

B
Behdad Esfahbod 已提交
1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
/**
 * hb_font_set_parent:
 * @font: a font.
 * @parent: new parent.
 *
 * Sets parent font of @font.
 *
 * Since: 1.0.5
 **/
void
hb_font_set_parent (hb_font_t *font,
		    hb_font_t *parent)
{
  if (font->immutable)
    return;

  if (!parent)
    parent = hb_font_get_empty ();

  hb_font_t *old = font->parent;

  font->parent = hb_font_reference (parent);

  hb_font_destroy (old);
}

1359 1360 1361 1362 1363 1364 1365 1366
/**
 * hb_font_get_parent:
 * @font: a font.
 *
 * 
 *
 * Return value: (transfer none): 
 *
1367
 * Since: 0.9.2
1368
 **/
1369 1370 1371 1372 1373
hb_font_t *
hb_font_get_parent (hb_font_t *font)
{
  return font->parent;
}
1374

1375 1376 1377 1378 1379 1380 1381 1382
/**
 * hb_font_get_face:
 * @font: a font.
 *
 * 
 *
 * Return value: (transfer none): 
 *
S
Sascha Brawer 已提交
1383
 * Since: 0.9.2
1384
 **/
1385 1386 1387 1388 1389 1390 1391
hb_face_t *
hb_font_get_face (hb_font_t *font)
{
  return font->face;
}


1392 1393 1394
/**
 * hb_font_set_funcs:
 * @font: a font.
1395
 * @klass: (closure font_data) (destroy destroy) (scope notified):
1396
 * @font_data: 
1397 1398 1399 1400
 * @destroy: 
 *
 * 
 *
S
Sascha Brawer 已提交
1401
 * Since: 0.9.2
1402
 **/
B
Behdad Esfahbod 已提交
1403
void
B
Behdad Esfahbod 已提交
1404 1405
hb_font_set_funcs (hb_font_t         *font,
		   hb_font_funcs_t   *klass,
1406
		   void              *font_data,
1407
		   hb_destroy_func_t  destroy)
1408
{
B
Behdad Esfahbod 已提交
1409 1410
  if (font->immutable) {
    if (destroy)
1411
      destroy (font_data);
B
Behdad Esfahbod 已提交
1412
    return;
B
Behdad Esfahbod 已提交
1413
  }
1414

B
Behdad Esfahbod 已提交
1415 1416 1417
  if (font->destroy)
    font->destroy (font->user_data);

B
Behdad Esfahbod 已提交
1418
  if (!klass)
1419
    klass = hb_font_funcs_get_empty ();
B
Behdad Esfahbod 已提交
1420

B
Behdad Esfahbod 已提交
1421 1422 1423
  hb_font_funcs_reference (klass);
  hb_font_funcs_destroy (font->klass);
  font->klass = klass;
1424
  font->user_data = font_data;
1425
  font->destroy = destroy;
1426 1427
}

1428 1429 1430
/**
 * hb_font_set_funcs_data:
 * @font: a font.
1431
 * @font_data: (destroy destroy) (scope notified):
1432 1433 1434 1435
 * @destroy: 
 *
 * 
 *
S
Sascha Brawer 已提交
1436
 * Since: 0.9.2
1437
 **/
1438 1439
void
hb_font_set_funcs_data (hb_font_t         *font,
1440
		        void              *font_data,
1441 1442
		        hb_destroy_func_t  destroy)
{
B
Behdad Esfahbod 已提交
1443 1444 1445
  /* Destroy user_data? */
  if (font->immutable) {
    if (destroy)
1446
      destroy (font_data);
1447
    return;
B
Behdad Esfahbod 已提交
1448
  }
1449 1450 1451 1452

  if (font->destroy)
    font->destroy (font->user_data);

1453
  font->user_data = font_data;
1454 1455 1456
  font->destroy = destroy;
}

B
Behdad Esfahbod 已提交
1457

1458 1459 1460 1461 1462 1463 1464 1465
/**
 * hb_font_set_scale:
 * @font: a font.
 * @x_scale: 
 * @y_scale: 
 *
 * 
 *
1466
 * Since: 0.9.2
1467
 **/
1468 1469
void
hb_font_set_scale (hb_font_t *font,
1470 1471
		   int x_scale,
		   int y_scale)
1472
{
1473
  if (font->immutable)
1474 1475 1476 1477 1478 1479
    return;

  font->x_scale = x_scale;
  font->y_scale = y_scale;
}

1480 1481 1482 1483 1484 1485 1486 1487
/**
 * hb_font_get_scale:
 * @font: a font.
 * @x_scale: (out): 
 * @y_scale: (out): 
 *
 * 
 *
1488
 * Since: 0.9.2
1489
 **/
B
Behdad Esfahbod 已提交
1490 1491
void
hb_font_get_scale (hb_font_t *font,
1492 1493
		   int *x_scale,
		   int *y_scale)
B
Behdad Esfahbod 已提交
1494 1495 1496 1497 1498
{
  if (x_scale) *x_scale = font->x_scale;
  if (y_scale) *y_scale = font->y_scale;
}

1499 1500 1501 1502 1503 1504 1505 1506
/**
 * hb_font_set_ppem:
 * @font: a font.
 * @x_ppem: 
 * @y_ppem: 
 *
 * 
 *
1507
 * Since: 0.9.2
1508
 **/
1509 1510 1511 1512 1513
void
hb_font_set_ppem (hb_font_t *font,
		  unsigned int x_ppem,
		  unsigned int y_ppem)
{
1514
  if (font->immutable)
1515 1516 1517 1518 1519 1520
    return;

  font->x_ppem = x_ppem;
  font->y_ppem = y_ppem;
}

1521 1522 1523 1524 1525 1526 1527 1528
/**
 * hb_font_get_ppem:
 * @font: a font.
 * @x_ppem: (out): 
 * @y_ppem: (out): 
 *
 * 
 *
1529
 * Since: 0.9.2
1530
 **/
B
Behdad Esfahbod 已提交
1531 1532 1533 1534 1535 1536 1537 1538
void
hb_font_get_ppem (hb_font_t *font,
		  unsigned int *x_ppem,
		  unsigned int *y_ppem)
{
  if (x_ppem) *x_ppem = font->x_ppem;
  if (y_ppem) *y_ppem = font->y_ppem;
}
1539 1540


1541 1542
#ifndef HB_DISABLE_DEPRECATED

1543 1544 1545 1546 1547 1548 1549 1550
/*
 * Deprecated get_glyph_func():
 */

struct hb_trampoline_closure_t
{
  void *user_data;
  hb_destroy_func_t destroy;
1551
  unsigned int ref_count;
1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575
};

template <typename FuncType>
struct hb_trampoline_t
{
  hb_trampoline_closure_t closure; /* Must be first. */
  FuncType func;
};

template <typename FuncType>
static hb_trampoline_t<FuncType> *
trampoline_create (FuncType           func,
		   void              *user_data,
		   hb_destroy_func_t  destroy)
{
  typedef hb_trampoline_t<FuncType> trampoline_t;

  trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t));

  if (unlikely (!trampoline))
    return NULL;

  trampoline->closure.user_data = user_data;
  trampoline->closure.destroy = destroy;
1576
  trampoline->closure.ref_count = 1;
1577 1578 1579 1580 1581
  trampoline->func = func;

  return trampoline;
}

1582 1583 1584 1585 1586 1587
static void
trampoline_reference (hb_trampoline_closure_t *closure)
{
  closure->ref_count++;
}

1588 1589 1590 1591
static void
trampoline_destroy (void *user_data)
{
  hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
1592 1593 1594 1595

  if (--closure->ref_count)
    return;

1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646
  if (closure->destroy)
    closure->destroy (closure->user_data);
  free (closure);
}

typedef hb_trampoline_t<hb_font_get_glyph_func_t> hb_font_get_glyph_trampoline_t;

static hb_bool_t
hb_font_get_nominal_glyph_trampoline (hb_font_t *font,
				      void *font_data,
				      hb_codepoint_t unicode,
				      hb_codepoint_t *glyph,
				      void *user_data)
{
  hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
  return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data);
}

static hb_bool_t
hb_font_get_variation_glyph_trampoline (hb_font_t *font,
					void *font_data,
					hb_codepoint_t unicode,
					hb_codepoint_t variation_selector,
					hb_codepoint_t *glyph,
					void *user_data)
{
  hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data;
  return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data);
}

/**
 * hb_font_funcs_set_glyph_func:
 * @ffuncs: font functions.
 * @func: (closure user_data) (destroy destroy) (scope notified):
 * @user_data:
 * @destroy:
 *
 * Deprecated.  Use hb_font_funcs_set_nominal_glyph_func() and
 * hb_font_funcs_set_variation_glyph_func() instead.
 *
 * Since: 0.9.2
 * Deprecated: 1.2.3
 **/
void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
			      hb_font_get_glyph_func_t func,
			      void *user_data, hb_destroy_func_t destroy)
{
  hb_font_get_glyph_trampoline_t *trampoline;

  trampoline = trampoline_create (func, user_data, destroy);
1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661
  if (unlikely (!trampoline))
  {
    if (destroy)
      destroy (user_data);
    return;
  }

  hb_font_funcs_set_nominal_glyph_func (ffuncs,
					hb_font_get_nominal_glyph_trampoline,
					trampoline,
					trampoline_destroy);

  trampoline_reference (&trampoline->closure);
  hb_font_funcs_set_variation_glyph_func (ffuncs,
					  hb_font_get_variation_glyph_trampoline,
1662 1663 1664
					  trampoline,
					  trampoline_destroy);
}
1665 1666

#endif /* HB_DISABLE_DEPRECATED */