Coverage Report

Created: 2023-09-25 06:24

/src/harfbuzz/src/hb-font.hh
Line
Count
Source (jump to first uncovered line)
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
0
  HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \
44
0
  HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \
45
0
  HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \
46
0
  HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \
47
0
  HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \
48
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \
49
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \
50
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \
51
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \
52
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \
53
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \
54
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \
55
0
  HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \
56
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \
57
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \
58
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \
59
0
  HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \
60
0
  HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \
61
0
  HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \
62
  /* ^--- Add new callbacks here */
63
64
struct hb_font_funcs_t
65
{
66
  hb_object_header_t header;
67
68
  struct {
69
#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name;
70
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
71
#undef HB_FONT_FUNC_IMPLEMENT
72
  } *user_data;
73
74
  struct {
75
#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name;
76
    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
77
#undef HB_FONT_FUNC_IMPLEMENT
78
  } *destroy;
79
80
  /* Don't access these directly.  Call font->get_*() instead. */
81
  union get_t {
82
    struct get_funcs_t {
83
#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name;
84
      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
85
#undef HB_FONT_FUNC_IMPLEMENT
86
    } f;
87
    void (*array[0
88
#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1
89
      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
90
#undef HB_FONT_FUNC_IMPLEMENT
91
    ]) ();
92
  } get;
93
};
94
DECLARE_NULL_INSTANCE (hb_font_funcs_t);
95
96
97
/*
98
 * hb_font_t
99
 */
100
101
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font);
102
#include "hb-shaper-list.hh"
103
#undef HB_SHAPER_IMPLEMENT
104
105
struct hb_font_t
106
{
107
  hb_object_header_t header;
108
  unsigned int serial;
109
  unsigned int serial_coords;
110
111
  hb_font_t *parent;
112
  hb_face_t *face;
113
114
  int32_t x_scale;
115
  int32_t y_scale;
116
117
  float x_embolden;
118
  float y_embolden;
119
  bool embolden_in_place;
120
  int32_t x_strength; /* x_embolden, in scaled units. */
121
  int32_t y_strength; /* y_embolden, in scaled units. */
122
123
  float slant;
124
  float slant_xy;
125
126
  float x_multf;
127
  float y_multf;
128
  int64_t x_mult;
129
  int64_t y_mult;
130
131
  unsigned int x_ppem;
132
  unsigned int y_ppem;
133
134
  float ptem;
135
136
  /* Font variation coordinates. */
137
  unsigned int instance_index;
138
  unsigned int num_coords;
139
  int *coords;
140
  float *design_coords;
141
142
  hb_font_funcs_t   *klass;
143
  void              *user_data;
144
  hb_destroy_func_t  destroy;
145
146
  hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */
147
148
149
  /* Convert from font-space to user-space */
150
  int64_t dir_mult (hb_direction_t direction)
151
0
  { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
152
0
  hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
153
0
  hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
154
0
  hb_position_t em_scalef_x (float v) { return em_multf (v, x_multf); }
155
0
  hb_position_t em_scalef_y (float v) { return em_multf (v, y_multf); }
156
0
  float em_fscale_x (int16_t v) { return em_fmult (v, x_multf); }
157
0
  float em_fscale_y (int16_t v) { return em_fmult (v, y_multf); }
158
0
  float em_fscalef_x (float v) { return em_fmultf (v, x_multf); }
159
0
  float em_fscalef_y (float v) { return em_fmultf (v, y_multf); }
160
  hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
161
0
  { return em_mult (v, dir_mult (direction)); }
162
163
  /* Convert from parent-font user-space to our user-space */
164
  hb_position_t parent_scale_x_distance (hb_position_t v)
165
0
  {
166
0
    if (unlikely (parent && parent->x_scale != x_scale))
167
0
      return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
168
0
    return v;
169
0
  }
170
  hb_position_t parent_scale_y_distance (hb_position_t v)
171
0
  {
172
0
    if (unlikely (parent && parent->y_scale != y_scale))
173
0
      return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
174
0
    return v;
175
0
  }
176
  hb_position_t parent_scale_x_position (hb_position_t v)
177
0
  { return parent_scale_x_distance (v); }
178
  hb_position_t parent_scale_y_position (hb_position_t v)
179
0
  { return parent_scale_y_distance (v); }
180
181
  void parent_scale_distance (hb_position_t *x, hb_position_t *y)
182
0
  {
183
0
    *x = parent_scale_x_distance (*x);
184
0
    *y = parent_scale_y_distance (*y);
185
0
  }
186
  void parent_scale_position (hb_position_t *x, hb_position_t *y)
187
0
  {
188
0
    *x = parent_scale_x_position (*x);
189
0
    *y = parent_scale_y_position (*y);
190
0
  }
191
192
  void scale_glyph_extents (hb_glyph_extents_t *extents)
193
0
  {
194
0
    float x1 = em_fscale_x (extents->x_bearing);
195
0
    float y1 = em_fscale_y (extents->y_bearing);
196
0
    float x2 = em_fscale_x (extents->x_bearing + extents->width);
197
0
    float y2 = em_fscale_y (extents->y_bearing + extents->height);
198
199
    /* Apply slant. */
200
0
    if (slant_xy)
201
0
    {
202
0
      x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
203
0
      x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
204
0
    }
205
206
0
    extents->x_bearing = floorf (x1);
207
0
    extents->y_bearing = floorf (y1);
208
0
    extents->width = ceilf (x2) - extents->x_bearing;
209
0
    extents->height = ceilf (y2) - extents->y_bearing;
210
211
0
    if (x_strength || y_strength)
212
0
    {
213
      /* Y */
214
0
      int y_shift = y_strength;
215
0
      if (y_scale < 0) y_shift = -y_shift;
216
0
      extents->y_bearing += y_shift;
217
0
      extents->height -= y_shift;
218
219
      /* X */
220
0
      int x_shift = x_strength;
221
0
      if (x_scale < 0) x_shift = -x_shift;
222
0
      if (embolden_in_place)
223
0
  extents->x_bearing -= x_shift / 2;
224
0
      extents->width += x_shift;
225
0
    }
226
0
  }
227
228
229
  /* Public getters */
230
231
  HB_INTERNAL bool has_func (unsigned int i);
232
  HB_INTERNAL bool has_func_set (unsigned int i);
233
234
  /* has_* ... */
235
#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
236
  bool \
237
  has_##name##_func () \
238
614k
  { \
239
614k
    hb_font_funcs_t *funcs = this->klass; \
240
614k
    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
241
614k
    return has_func (i); \
242
614k
  } \
Unexecuted instantiation: hb_font_t::has_font_h_extents_func()
Unexecuted instantiation: hb_font_t::has_font_v_extents_func()
Unexecuted instantiation: hb_font_t::has_nominal_glyph_func()
Unexecuted instantiation: hb_font_t::has_nominal_glyphs_func()
Unexecuted instantiation: hb_font_t::has_variation_glyph_func()
Unexecuted instantiation: hb_font_t::has_glyph_h_advance_func()
Unexecuted instantiation: hb_font_t::has_glyph_v_advance_func()
Unexecuted instantiation: hb_font_t::has_glyph_h_advances_func()
Unexecuted instantiation: hb_font_t::has_glyph_v_advances_func()
hb_font_t::has_glyph_h_origin_func()
Line
Count
Source
238
614k
  { \
239
614k
    hb_font_funcs_t *funcs = this->klass; \
240
614k
    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
241
614k
    return has_func (i); \
242
614k
  } \
Unexecuted instantiation: hb_font_t::has_glyph_v_origin_func()
Unexecuted instantiation: hb_font_t::has_glyph_h_kerning_func()
Unexecuted instantiation: hb_font_t::has_glyph_extents_func()
Unexecuted instantiation: hb_font_t::has_glyph_contour_point_func()
Unexecuted instantiation: hb_font_t::has_glyph_name_func()
Unexecuted instantiation: hb_font_t::has_glyph_from_name_func()
Unexecuted instantiation: hb_font_t::has_draw_glyph_func()
Unexecuted instantiation: hb_font_t::has_paint_glyph_func()
243
  bool \
244
  has_##name##_func_set () \
245
409k
  { \
246
409k
    hb_font_funcs_t *funcs = this->klass; \
247
409k
    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
248
409k
    return has_func_set (i); \
249
409k
  }
Unexecuted instantiation: hb_font_t::has_font_h_extents_func_set()
Unexecuted instantiation: hb_font_t::has_font_v_extents_func_set()
hb_font_t::has_nominal_glyph_func_set()
Line
Count
Source
245
204k
  { \
246
204k
    hb_font_funcs_t *funcs = this->klass; \
247
204k
    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
248
204k
    return has_func_set (i); \
249
204k
  }
Unexecuted instantiation: hb_font_t::has_nominal_glyphs_func_set()
Unexecuted instantiation: hb_font_t::has_variation_glyph_func_set()
hb_font_t::has_glyph_h_advance_func_set()
Line
Count
Source
245
204k
  { \
246
204k
    hb_font_funcs_t *funcs = this->klass; \
247
204k
    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
248
204k
    return has_func_set (i); \
249
204k
  }
Unexecuted instantiation: hb_font_t::has_glyph_v_advance_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_h_advances_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_v_advances_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_h_origin_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_v_origin_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_h_kerning_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_extents_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_contour_point_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_name_func_set()
Unexecuted instantiation: hb_font_t::has_glyph_from_name_func_set()
Unexecuted instantiation: hb_font_t::has_draw_glyph_func_set()
Unexecuted instantiation: hb_font_t::has_paint_glyph_func_set()
250
  HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
251
#undef HB_FONT_FUNC_IMPLEMENT
252
253
  hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
254
0
  {
255
0
    hb_memset (extents, 0, sizeof (*extents));
256
0
    return klass->get.f.font_h_extents (this, user_data,
257
0
          extents,
258
0
          !klass->user_data ? nullptr : klass->user_data->font_h_extents);
259
0
  }
260
  hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
261
0
  {
262
0
    hb_memset (extents, 0, sizeof (*extents));
263
0
    return klass->get.f.font_v_extents (this, user_data,
264
0
          extents,
265
0
          !klass->user_data ? nullptr : klass->user_data->font_v_extents);
266
0
  }
267
268
  bool has_glyph (hb_codepoint_t unicode)
269
0
  {
270
0
    hb_codepoint_t glyph;
271
0
    return get_nominal_glyph (unicode, &glyph);
272
0
  }
273
274
  hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
275
             hb_codepoint_t *glyph,
276
             hb_codepoint_t not_found = 0)
277
2.93M
  {
278
2.93M
    *glyph = not_found;
279
2.93M
    return klass->get.f.nominal_glyph (this, user_data,
280
2.93M
               unicode, glyph,
281
2.93M
               !klass->user_data ? nullptr : klass->user_data->nominal_glyph);
282
2.93M
  }
283
  unsigned int get_nominal_glyphs (unsigned int count,
284
           const hb_codepoint_t *first_unicode,
285
           unsigned int unicode_stride,
286
           hb_codepoint_t *first_glyph,
287
           unsigned int glyph_stride)
288
204k
  {
289
204k
    return klass->get.f.nominal_glyphs (this, user_data,
290
204k
          count,
291
204k
          first_unicode, unicode_stride,
292
204k
          first_glyph, glyph_stride,
293
204k
          !klass->user_data ? nullptr : klass->user_data->nominal_glyphs);
294
204k
  }
295
296
  hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
297
         hb_codepoint_t *glyph,
298
         hb_codepoint_t not_found = 0)
299
0
  {
300
0
    *glyph = not_found;
301
0
    return klass->get.f.variation_glyph (this, user_data,
302
0
           unicode, variation_selector, glyph,
303
0
           !klass->user_data ? nullptr : klass->user_data->variation_glyph);
304
0
  }
305
306
  hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
307
2.93M
  {
308
2.93M
    return klass->get.f.glyph_h_advance (this, user_data,
309
2.93M
           glyph,
310
2.93M
           !klass->user_data ? nullptr : klass->user_data->glyph_h_advance);
311
2.93M
  }
312
313
  hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
314
0
  {
315
0
    return klass->get.f.glyph_v_advance (this, user_data,
316
0
           glyph,
317
0
           !klass->user_data ? nullptr : klass->user_data->glyph_v_advance);
318
0
  }
319
320
  void get_glyph_h_advances (unsigned int count,
321
           const hb_codepoint_t *first_glyph,
322
           unsigned int glyph_stride,
323
           hb_position_t *first_advance,
324
           unsigned int advance_stride)
325
204k
  {
326
204k
    return klass->get.f.glyph_h_advances (this, user_data,
327
204k
            count,
328
204k
            first_glyph, glyph_stride,
329
204k
            first_advance, advance_stride,
330
204k
            !klass->user_data ? nullptr : klass->user_data->glyph_h_advances);
331
204k
  }
332
333
  void get_glyph_v_advances (unsigned int count,
334
           const hb_codepoint_t *first_glyph,
335
           unsigned int glyph_stride,
336
           hb_position_t *first_advance,
337
           unsigned int advance_stride)
338
0
  {
339
0
    return klass->get.f.glyph_v_advances (this, user_data,
340
0
            count,
341
0
            first_glyph, glyph_stride,
342
0
            first_advance, advance_stride,
343
0
            !klass->user_data ? nullptr : klass->user_data->glyph_v_advances);
344
0
  }
345
346
  hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
347
        hb_position_t *x, hb_position_t *y)
348
8.79M
  {
349
8.79M
    *x = *y = 0;
350
8.79M
    return klass->get.f.glyph_h_origin (this, user_data,
351
8.79M
          glyph, x, y,
352
8.79M
          !klass->user_data ? nullptr : klass->user_data->glyph_h_origin);
353
8.79M
  }
354
355
  hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
356
        hb_position_t *x, hb_position_t *y)
357
0
  {
358
0
    *x = *y = 0;
359
0
    return klass->get.f.glyph_v_origin (this, user_data,
360
0
          glyph, x, y,
361
0
          !klass->user_data ? nullptr : klass->user_data->glyph_v_origin);
362
0
  }
363
364
  hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
365
             hb_codepoint_t right_glyph)
366
0
  {
367
#ifdef HB_DISABLE_DEPRECATED
368
    return 0;
369
#else
370
0
    return klass->get.f.glyph_h_kerning (this, user_data,
371
0
           left_glyph, right_glyph,
372
0
           !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
373
0
#endif
374
0
  }
375
376
  hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
377
             hb_codepoint_t bottom_glyph)
378
0
  {
379
#ifdef HB_DISABLE_DEPRECATED
380
    return 0;
381
#else
382
0
    return klass->get.f.glyph_v_kerning (this, user_data,
383
0
           top_glyph, bottom_glyph,
384
0
           !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
385
0
#endif
386
0
  }
387
388
  hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
389
             hb_glyph_extents_t *extents)
390
0
  {
391
0
    hb_memset (extents, 0, sizeof (*extents));
392
0
    return klass->get.f.glyph_extents (this, user_data,
393
0
               glyph,
394
0
               extents,
395
0
               !klass->user_data ? nullptr : klass->user_data->glyph_extents);
396
0
  }
397
398
  hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
399
             hb_position_t *x, hb_position_t *y)
400
0
  {
401
0
    *x = *y = 0;
402
0
    return klass->get.f.glyph_contour_point (this, user_data,
403
0
               glyph, point_index,
404
0
               x, y,
405
0
               !klass->user_data ? nullptr : klass->user_data->glyph_contour_point);
406
0
  }
407
408
  hb_bool_t get_glyph_name (hb_codepoint_t glyph,
409
          char *name, unsigned int size)
410
0
  {
411
0
    if (size) *name = '\0';
412
0
    return klass->get.f.glyph_name (this, user_data,
413
0
            glyph,
414
0
            name, size,
415
0
            !klass->user_data ? nullptr : klass->user_data->glyph_name);
416
0
  }
417
418
  hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
419
         hb_codepoint_t *glyph)
420
0
  {
421
0
    *glyph = 0;
422
0
    if (len == -1) len = strlen (name);
423
0
    return klass->get.f.glyph_from_name (this, user_data,
424
0
           name, len,
425
0
           glyph,
426
0
           !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
427
0
  }
428
429
  void draw_glyph (hb_codepoint_t glyph,
430
       hb_draw_funcs_t *draw_funcs, void *draw_data)
431
0
  {
432
0
    klass->get.f.draw_glyph (this, user_data,
433
0
           glyph,
434
0
           draw_funcs, draw_data,
435
0
           !klass->user_data ? nullptr : klass->user_data->draw_glyph);
436
0
  }
437
438
  void paint_glyph (hb_codepoint_t glyph,
439
                    hb_paint_funcs_t *paint_funcs, void *paint_data,
440
                    unsigned int palette,
441
                    hb_color_t foreground)
442
0
  {
443
0
    klass->get.f.paint_glyph (this, user_data,
444
0
                              glyph,
445
0
                              paint_funcs, paint_data,
446
0
                              palette, foreground,
447
0
                              !klass->user_data ? nullptr : klass->user_data->paint_glyph);
448
0
  }
449
450
  /* A bit higher-level, and with fallback */
451
452
  void get_h_extents_with_fallback (hb_font_extents_t *extents)
453
0
  {
454
0
    if (!get_font_h_extents (extents))
455
0
    {
456
0
      extents->ascender = y_scale * .8;
457
0
      extents->descender = extents->ascender - y_scale;
458
0
      extents->line_gap = 0;
459
0
    }
460
0
  }
461
  void get_v_extents_with_fallback (hb_font_extents_t *extents)
462
0
  {
463
0
    if (!get_font_v_extents (extents))
464
0
    {
465
0
      extents->ascender = x_scale / 2;
466
0
      extents->descender = extents->ascender - x_scale;
467
0
      extents->line_gap = 0;
468
0
    }
469
0
  }
470
471
  void get_extents_for_direction (hb_direction_t direction,
472
          hb_font_extents_t *extents)
473
0
  {
474
0
    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
475
0
      get_h_extents_with_fallback (extents);
476
0
    else
477
0
      get_v_extents_with_fallback (extents);
478
0
  }
479
480
  void get_glyph_advance_for_direction (hb_codepoint_t glyph,
481
          hb_direction_t direction,
482
          hb_position_t *x, hb_position_t *y)
483
0
  {
484
0
    *x = *y = 0;
485
0
    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
486
0
      *x = get_glyph_h_advance (glyph);
487
0
    else
488
0
      *y = get_glyph_v_advance (glyph);
489
0
  }
490
  void get_glyph_advances_for_direction (hb_direction_t direction,
491
           unsigned int count,
492
           const hb_codepoint_t *first_glyph,
493
           unsigned glyph_stride,
494
           hb_position_t *first_advance,
495
           unsigned advance_stride)
496
0
  {
497
0
    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
498
0
      get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
499
0
    else
500
0
      get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
501
0
  }
502
503
  void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
504
              hb_position_t *x, hb_position_t *y)
505
0
  {
506
0
    *x = get_glyph_h_advance (glyph) / 2;
507
508
0
    hb_font_extents_t extents;
509
0
    get_h_extents_with_fallback (&extents);
510
0
    *y = extents.ascender;
511
0
  }
512
513
  void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
514
           hb_position_t *x, hb_position_t *y)
515
8.79M
  {
516
8.79M
    if (!get_glyph_h_origin (glyph, x, y) &&
517
8.79M
   get_glyph_v_origin (glyph, x, y))
518
0
    {
519
0
      hb_position_t dx, dy;
520
0
      guess_v_origin_minus_h_origin (glyph, &dx, &dy);
521
0
      *x -= dx; *y -= dy;
522
0
    }
523
8.79M
  }
524
  void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
525
           hb_position_t *x, hb_position_t *y)
526
0
  {
527
0
    if (!get_glyph_v_origin (glyph, x, y) &&
528
0
   get_glyph_h_origin (glyph, x, y))
529
0
    {
530
0
      hb_position_t dx, dy;
531
0
      guess_v_origin_minus_h_origin (glyph, &dx, &dy);
532
0
      *x += dx; *y += dy;
533
0
    }
534
0
  }
535
536
  void get_glyph_origin_for_direction (hb_codepoint_t glyph,
537
               hb_direction_t direction,
538
               hb_position_t *x, hb_position_t *y)
539
0
  {
540
0
    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
541
0
      get_glyph_h_origin_with_fallback (glyph, x, y);
542
0
    else
543
0
      get_glyph_v_origin_with_fallback (glyph, x, y);
544
0
  }
545
546
  void add_glyph_h_origin (hb_codepoint_t glyph,
547
         hb_position_t *x, hb_position_t *y)
548
2.93M
  {
549
2.93M
    hb_position_t origin_x, origin_y;
550
551
2.93M
    get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
552
553
2.93M
    *x += origin_x;
554
2.93M
    *y += origin_y;
555
2.93M
  }
556
  void add_glyph_v_origin (hb_codepoint_t glyph,
557
         hb_position_t *x, hb_position_t *y)
558
0
  {
559
0
    hb_position_t origin_x, origin_y;
560
0
561
0
    get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
562
0
563
0
    *x += origin_x;
564
0
    *y += origin_y;
565
0
  }
566
  void add_glyph_origin_for_direction (hb_codepoint_t glyph,
567
               hb_direction_t direction,
568
               hb_position_t *x, hb_position_t *y)
569
0
  {
570
0
    hb_position_t origin_x, origin_y;
571
572
0
    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
573
574
0
    *x += origin_x;
575
0
    *y += origin_y;
576
0
  }
577
578
  void subtract_glyph_h_origin (hb_codepoint_t glyph,
579
        hb_position_t *x, hb_position_t *y)
580
5.86M
  {
581
5.86M
    hb_position_t origin_x, origin_y;
582
583
5.86M
    get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
584
585
5.86M
    *x -= origin_x;
586
5.86M
    *y -= origin_y;
587
5.86M
  }
588
  void subtract_glyph_v_origin (hb_codepoint_t glyph,
589
        hb_position_t *x, hb_position_t *y)
590
0
  {
591
0
    hb_position_t origin_x, origin_y;
592
593
0
    get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
594
595
0
    *x -= origin_x;
596
0
    *y -= origin_y;
597
0
  }
598
  void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
599
              hb_direction_t direction,
600
              hb_position_t *x, hb_position_t *y)
601
0
  {
602
0
    hb_position_t origin_x, origin_y;
603
604
0
    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
605
606
0
    *x -= origin_x;
607
0
    *y -= origin_y;
608
0
  }
609
610
  void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
611
          hb_direction_t direction,
612
          hb_position_t *x, hb_position_t *y)
613
0
  {
614
0
    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
615
0
      *y = 0;
616
0
      *x = get_glyph_h_kerning (first_glyph, second_glyph);
617
0
    } else {
618
0
      *x = 0;
619
0
      *y = get_glyph_v_kerning (first_glyph, second_glyph);
620
0
    }
621
0
  }
622
623
  hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
624
            hb_direction_t direction,
625
            hb_glyph_extents_t *extents)
626
0
  {
627
0
    hb_bool_t ret = get_glyph_extents (glyph, extents);
628
629
0
    if (ret)
630
0
      subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
631
632
0
    return ret;
633
0
  }
634
635
  hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
636
            hb_direction_t direction,
637
            hb_position_t *x, hb_position_t *y)
638
0
  {
639
0
    hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
640
641
0
    if (ret)
642
0
      subtract_glyph_origin_for_direction (glyph, direction, x, y);
643
644
0
    return ret;
645
0
  }
646
647
  /* Generates gidDDD if glyph has no name. */
648
  void
649
  glyph_to_string (hb_codepoint_t glyph,
650
       char *s, unsigned int size)
651
0
  {
652
0
    if (get_glyph_name (glyph, s, size)) return;
653
654
0
    if (size && snprintf (s, size, "gid%u", glyph) < 0)
655
0
      *s = '\0';
656
0
  }
657
658
  /* Parses gidDDD and uniUUUU strings automatically. */
659
  hb_bool_t
660
  glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
661
         hb_codepoint_t *glyph)
662
0
  {
663
0
    if (get_glyph_from_name (s, len, glyph)) return true;
664
665
0
    if (len == -1) len = strlen (s);
666
667
    /* Straight glyph index. */
668
0
    if (hb_codepoint_parse (s, len, 10, glyph))
669
0
      return true;
670
671
0
    if (len > 3)
672
0
    {
673
      /* gidDDD syntax for glyph indices. */
674
0
      if (0 == strncmp (s, "gid", 3) &&
675
0
    hb_codepoint_parse (s + 3, len - 3, 10, glyph))
676
0
  return true;
677
678
      /* uniUUUU and other Unicode character indices. */
679
0
      hb_codepoint_t unichar;
680
0
      if (0 == strncmp (s, "uni", 3) &&
681
0
    hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
682
0
    get_nominal_glyph (unichar, glyph))
683
0
  return true;
684
0
    }
685
686
0
    return false;
687
0
  }
688
689
  void mults_changed ()
690
21
  {
691
21
    float upem = face->get_upem ();
692
693
21
    x_multf = x_scale / upem;
694
21
    y_multf = y_scale / upem;
695
21
    bool x_neg = x_scale < 0;
696
21
    x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
697
21
    bool y_neg = y_scale < 0;
698
21
    y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem;
699
700
21
    x_strength = fabsf (roundf (x_scale * x_embolden));
701
21
    y_strength = fabsf (roundf (y_scale * y_embolden));
702
703
21
    slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
704
705
21
    data.fini ();
706
21
  }
707
708
  hb_position_t em_mult (int16_t v, int64_t mult)
709
0
  { return (hb_position_t) ((v * mult + 32768) >> 16); }
710
  hb_position_t em_multf (float v, float mult)
711
0
  { return (hb_position_t) roundf (em_fmultf (v, mult)); }
712
  float em_fmultf (float v, float mult)
713
0
  { return v * mult; }
714
  float em_fmult (int16_t v, float mult)
715
0
  { return (float) v * mult; }
716
};
717
DECLARE_NULL_INSTANCE (hb_font_t);
718
719
720
#endif /* HB_FONT_HH */