Coverage Report

Created: 2023-10-07 15:07

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