blob: f503575c34adae816b1605b4564d1c35d482551d [file] [log] [blame]
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04001/*
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -04002 * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2011 Google, Inc.
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04004 *
Behdad Esfahbodc755cb32010-04-22 00:11:43 -04005 * This is part of HarfBuzz, a text shaping library.
Behdad Esfahbodc62b5032009-08-01 19:54:49 -04006 *
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
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -040026 * Google Author(s): Behdad Esfahbod
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040027 */
28
Behdad Esfahbodc77ae402018-08-25 22:36:36 -070029#ifndef HB_FONT_HH
30#define HB_FONT_HH
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040031
Behdad Esfahbodc77ae402018-08-25 22:36:36 -070032#include "hb.hh"
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040033
Behdad Esfahbodc77ae402018-08-25 22:36:36 -070034#include "hb-face.hh"
35#include "hb-shaper.hh"
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040036
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040037
38/*
Behdad Esfahbod5c441882009-08-10 20:05:16 -040039 * hb_font_funcs_t
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040040 */
41
Behdad Esfahbod744970a2011-05-16 18:15:37 -040042#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
Matthias Clasen0f287e72022-12-19 13:45:45 -050043 HB_FONT_FUNC_IMPLEMENT (get_,font_h_extents) \
44 HB_FONT_FUNC_IMPLEMENT (get_,font_v_extents) \
45 HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyph) \
46 HB_FONT_FUNC_IMPLEMENT (get_,nominal_glyphs) \
47 HB_FONT_FUNC_IMPLEMENT (get_,variation_glyph) \
48 HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advance) \
49 HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advance) \
50 HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_advances) \
51 HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_advances) \
52 HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_origin) \
53 HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_origin) \
54 HB_FONT_FUNC_IMPLEMENT (get_,glyph_h_kerning) \
55 HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (get_,glyph_v_kerning)) \
56 HB_FONT_FUNC_IMPLEMENT (get_,glyph_extents) \
57 HB_FONT_FUNC_IMPLEMENT (get_,glyph_contour_point) \
58 HB_FONT_FUNC_IMPLEMENT (get_,glyph_name) \
59 HB_FONT_FUNC_IMPLEMENT (get_,glyph_from_name) \
Matthias Clasen14b026f2022-12-19 13:53:49 -050060 HB_FONT_FUNC_IMPLEMENT (,draw_glyph) \
Matthias Clasen0f287e72022-12-19 13:45:45 -050061 HB_FONT_FUNC_IMPLEMENT (,paint_glyph) \
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040062 /* ^--- Add new callbacks here */
Behdad Esfahbod744970a2011-05-16 18:15:37 -040063
Behdad Esfahbod35066722018-08-06 06:17:48 -070064struct hb_font_funcs_t
65{
Behdad Esfahbod4b6317c2011-07-07 23:14:42 -040066 hb_object_header_t header;
67
Behdad Esfahbodb9d975b2011-05-10 20:41:13 -040068 struct {
Matthias Clasen0f287e72022-12-19 13:45:45 -050069#define HB_FONT_FUNC_IMPLEMENT(get_,name) void *name;
Behdad Esfahbod744970a2011-05-16 18:15:37 -040070 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
71#undef HB_FONT_FUNC_IMPLEMENT
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -060072 } *user_data;
Behdad Esfahbodb9d975b2011-05-10 20:41:13 -040073
74 struct {
Matthias Clasen0f287e72022-12-19 13:45:45 -050075#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_destroy_func_t name;
Behdad Esfahbod744970a2011-05-16 18:15:37 -040076 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
77#undef HB_FONT_FUNC_IMPLEMENT
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -060078 } *destroy;
Behdad Esfahbod28de1042015-11-04 22:00:25 -080079
80 /* Don't access these directly. Call font->get_*() instead. */
81 union get_t {
82 struct get_funcs_t {
Matthias Clasen0f287e72022-12-19 13:45:45 -050083#define HB_FONT_FUNC_IMPLEMENT(get_,name) hb_font_##get_##name##_func_t name;
Behdad Esfahbod28de1042015-11-04 22:00:25 -080084 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
85#undef HB_FONT_FUNC_IMPLEMENT
86 } f;
Behdad Esfahbod8c945112018-03-28 14:06:58 -070087 void (*array[0
Matthias Clasen0f287e72022-12-19 13:45:45 -050088#define HB_FONT_FUNC_IMPLEMENT(get_,name) +1
Behdad Esfahbod8c945112018-03-28 14:06:58 -070089 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
90#undef HB_FONT_FUNC_IMPLEMENT
Ebrahim Byagowie4120082018-12-17 21:31:01 +033091 ]) ();
Behdad Esfahbod28de1042015-11-04 22:00:25 -080092 } get;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040093};
Behdad Esfahbod35066722018-08-06 06:17:48 -070094DECLARE_NULL_INSTANCE (hb_font_funcs_t);
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040095
Behdad Esfahbodc62b5032009-08-01 19:54:49 -040096
97/*
98 * hb_font_t
99 */
100
Behdad Esfahbodce5da0f2018-11-16 02:29:13 -0500101#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font);
102#include "hb-shaper-list.hh"
103#undef HB_SHAPER_IMPLEMENT
104
Behdad Esfahbod35066722018-08-06 06:17:48 -0700105struct hb_font_t
106{
Behdad Esfahbodfca368c2011-04-21 18:24:02 -0400107 hb_object_header_t header;
Behdad Esfahboda2015cd2022-05-20 12:15:00 -0600108 unsigned int serial;
109 unsigned int serial_coords;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400110
Behdad Esfahboddefc45b2011-05-10 20:02:49 -0400111 hb_font_t *parent;
Behdad Esfahbod72657e42011-05-02 20:46:32 -0400112 hb_face_t *face;
113
Behdad Esfahbodb8477692019-07-05 13:52:09 -0700114 int32_t x_scale;
115 int32_t y_scale;
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700116
117 float x_embolden;
118 float y_embolden;
Behdad Esfahbodaef002e2023-02-07 11:29:49 -0700119 bool embolden_in_place;
120 int32_t x_strength; /* x_embolden, in scaled units. */
121 int32_t y_strength; /* y_embolden, in scaled units. */
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700122
Behdad Esfahbod810f5d72021-12-18 15:12:26 -0700123 float slant;
Behdad Esfahbodff697de2021-12-19 07:25:37 -0700124 float slant_xy;
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700125
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600126 float x_multf;
127 float y_multf;
Behdad Esfahbodb8477692019-07-05 13:52:09 -0700128 int64_t x_mult;
129 int64_t y_mult;
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400130
131 unsigned int x_ppem;
132 unsigned int y_ppem;
Behdad Esfahbod5c441882009-08-10 20:05:16 -0400133
Behdad Esfahbodb57f18d2017-10-11 11:47:47 +0200134 float ptem;
135
Behdad Esfahbod6d9d3c52016-03-01 19:12:08 +0900136 /* Font variation coordinates. */
Behdad Esfahbodd195e072023-01-15 10:44:04 -0700137 unsigned int instance_index;
Behdad Esfahbodca286702016-03-01 19:29:36 +0900138 unsigned int num_coords;
Behdad Esfahbod26648ce2016-09-10 02:11:05 -0700139 int *coords;
Ebrahim Byagowiab2d3ec2019-08-14 18:42:51 +0430140 float *design_coords;
Behdad Esfahbod6d9d3c52016-03-01 19:12:08 +0900141
Behdad Esfahbod8fb3d1a2009-11-03 18:34:20 -0500142 hb_font_funcs_t *klass;
Behdad Esfahbod8fb3d1a2009-11-03 18:34:20 -0500143 void *user_data;
Behdad Esfahbod56681892011-04-20 03:03:32 -0400144 hb_destroy_func_t destroy;
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400145
Behdad Esfahbodce5da0f2018-11-16 02:29:13 -0500146 hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */
Behdad Esfahbod027857d2012-07-26 17:34:25 -0400147
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400148
149 /* Convert from font-space to user-space */
Behdad Esfahbodf18ea1d2019-07-05 13:56:45 -0700150 int64_t dir_mult (hb_direction_t direction)
151 { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
152 hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
153 hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600154 hb_position_t em_scalef_x (float v) { return em_multf (v, x_multf); }
155 hb_position_t em_scalef_y (float v) { return em_multf (v, y_multf); }
156 float em_fscale_x (int16_t v) { return em_fmult (v, x_multf); }
157 float em_fscale_y (int16_t v) { return em_fmult (v, y_multf); }
158 float em_fscalef_x (float v) { return em_fmultf (v, x_multf); }
159 float em_fscalef_y (float v) { return em_fmultf (v, y_multf); }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330160 hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
Behdad Esfahbodf18ea1d2019-07-05 13:56:45 -0700161 { return em_mult (v, dir_mult (direction)); }
Behdad Esfahbodabcfe9b2011-05-11 00:02:02 -0400162
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400163 /* Convert from parent-font user-space to our user-space */
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330164 hb_position_t parent_scale_x_distance (hb_position_t v)
165 {
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400166 if (unlikely (parent && parent->x_scale != x_scale))
Behdad Esfahbod83408cf2013-11-06 14:46:04 -0500167 return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400168 return v;
169 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330170 hb_position_t parent_scale_y_distance (hb_position_t v)
171 {
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400172 if (unlikely (parent && parent->y_scale != y_scale))
Behdad Esfahbod83408cf2013-11-06 14:46:04 -0500173 return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400174 return v;
175 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330176 hb_position_t parent_scale_x_position (hb_position_t v)
177 { return parent_scale_x_distance (v); }
178 hb_position_t parent_scale_y_position (hb_position_t v)
179 { return parent_scale_y_distance (v); }
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400180
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330181 void parent_scale_distance (hb_position_t *x, hb_position_t *y)
182 {
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400183 *x = parent_scale_x_distance (*x);
184 *y = parent_scale_y_distance (*y);
185 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330186 void parent_scale_position (hb_position_t *x, hb_position_t *y)
187 {
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400188 *x = parent_scale_x_position (*x);
189 *y = parent_scale_y_position (*y);
190 }
191
Behdad Esfahbodb0abbfd2022-12-22 07:26:14 -0700192 void scale_glyph_extents (hb_glyph_extents_t *extents)
193 {
Behdad Esfahbod30adbc22023-01-09 11:54:44 -0700194 float x1 = em_fscale_x (extents->x_bearing);
195 float y1 = em_fscale_y (extents->y_bearing);
196 float x2 = em_fscale_x (extents->x_bearing + extents->width);
197 float y2 = em_fscale_y (extents->y_bearing + extents->height);
Behdad Esfahbod9194e132022-12-22 07:31:16 -0700198
199 /* Apply slant. */
Behdad Esfahbodd2aa2392023-01-09 13:43:56 -0700200 if (slant_xy)
201 {
202 x1 += hb_min (y1 * slant_xy, y2 * slant_xy);
203 x2 += hb_max (y1 * slant_xy, y2 * slant_xy);
204 }
Behdad Esfahbod30adbc22023-01-09 11:54:44 -0700205
206 extents->x_bearing = floorf (x1);
207 extents->y_bearing = floorf (y1);
208 extents->width = ceilf (x2) - extents->x_bearing;
209 extents->height = ceilf (y2) - extents->y_bearing;
210
Behdad Esfahbod560a65e2023-02-07 13:46:13 -0700211 if (x_strength || y_strength)
212 {
213 /* Y */
214 int y_shift = y_strength;
215 if (y_scale < 0) y_shift = -y_shift;
216 extents->y_bearing += y_shift;
217 extents->height -= y_shift;
218
219 /* X */
220 int x_shift = x_strength;
221 if (x_scale < 0) x_shift = -x_shift;
222 if (embolden_in_place)
223 extents->x_bearing -= x_shift / 2;
224 extents->width += x_shift;
225 }
Behdad Esfahbodb0abbfd2022-12-22 07:26:14 -0700226 }
227
Behdad Esfahbod63d646f2011-05-11 00:15:37 -0400228
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400229 /* Public getters */
230
Behdad Esfahbod762770c2015-11-04 21:42:55 -0800231 HB_INTERNAL bool has_func (unsigned int i);
Behdad Esfahbod08b71722018-10-19 19:12:33 -0700232 HB_INTERNAL bool has_func_set (unsigned int i);
Behdad Esfahbod762770c2015-11-04 21:42:55 -0800233
234 /* has_* ... */
Matthias Clasen0f287e72022-12-19 13:45:45 -0500235#define HB_FONT_FUNC_IMPLEMENT(get_,name) \
Behdad Esfahbod762770c2015-11-04 21:42:55 -0800236 bool \
Ebrahim Byagowie4120082018-12-17 21:31:01 +0330237 has_##name##_func () \
Behdad Esfahbod762770c2015-11-04 21:42:55 -0800238 { \
239 hb_font_funcs_t *funcs = this->klass; \
240 unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
241 return has_func (i); \
Behdad Esfahbod08b71722018-10-19 19:12:33 -0700242 } \
243 bool \
Ebrahim Byagowie4120082018-12-17 21:31:01 +0330244 has_##name##_func_set () \
Behdad Esfahbod08b71722018-10-19 19:12:33 -0700245 { \
246 hb_font_funcs_t *funcs = this->klass; \
247 unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
248 return has_func_set (i); \
Behdad Esfahbod762770c2015-11-04 21:42:55 -0800249 }
250 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
251#undef HB_FONT_FUNC_IMPLEMENT
252
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330253 hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900254 {
Behdad Esfahbodac0efaf2022-11-22 12:50:36 -0700255 hb_memset (extents, 0, sizeof (*extents));
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900256 return klass->get.f.font_h_extents (this, user_data,
257 extents,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600258 !klass->user_data ? nullptr : klass->user_data->font_h_extents);
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900259 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330260 hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900261 {
Behdad Esfahbodac0efaf2022-11-22 12:50:36 -0700262 hb_memset (extents, 0, sizeof (*extents));
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900263 return klass->get.f.font_v_extents (this, user_data,
264 extents,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600265 !klass->user_data ? nullptr : klass->user_data->font_v_extents);
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900266 }
267
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330268 bool has_glyph (hb_codepoint_t unicode)
Behdad Esfahbod8de20b12014-01-02 14:30:45 +0800269 {
270 hb_codepoint_t glyph;
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900271 return get_nominal_glyph (unicode, &glyph);
Behdad Esfahbod8de20b12014-01-02 14:30:45 +0800272 }
273
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330274 hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
Behdad Esfahbodda500562021-10-26 08:02:29 -0600275 hb_codepoint_t *glyph,
276 hb_codepoint_t not_found = 0)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400277 {
Behdad Esfahbodda500562021-10-26 08:02:29 -0600278 *glyph = not_found;
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900279 return klass->get.f.nominal_glyph (this, user_data,
280 unicode, glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600281 !klass->user_data ? nullptr : klass->user_data->nominal_glyph);
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900282 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330283 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)
Behdad Esfahbodb314c4e2018-10-09 09:23:51 -0400288 {
289 return klass->get.f.nominal_glyphs (this, user_data,
290 count,
291 first_unicode, unicode_stride,
292 first_glyph, glyph_stride,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600293 !klass->user_data ? nullptr : klass->user_data->nominal_glyphs);
Behdad Esfahbodb314c4e2018-10-09 09:23:51 -0400294 }
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900295
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330296 hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
Behdad Esfahbodda500562021-10-26 08:02:29 -0600297 hb_codepoint_t *glyph,
298 hb_codepoint_t not_found = 0)
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900299 {
Behdad Esfahbodda500562021-10-26 08:02:29 -0600300 *glyph = not_found;
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900301 return klass->get.f.variation_glyph (this, user_data,
302 unicode, variation_selector, glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600303 !klass->user_data ? nullptr : klass->user_data->variation_glyph);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400304 }
305
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330306 hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400307 {
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800308 return klass->get.f.glyph_h_advance (this, user_data,
309 glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600310 !klass->user_data ? nullptr : klass->user_data->glyph_h_advance);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400311 }
312
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330313 hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400314 {
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800315 return klass->get.f.glyph_v_advance (this, user_data,
316 glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600317 !klass->user_data ? nullptr : klass->user_data->glyph_v_advance);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400318 }
319
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330320 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)
Behdad Esfahbod79e21982018-08-06 09:45:17 -0700325 {
326 return klass->get.f.glyph_h_advances (this, user_data,
327 count,
328 first_glyph, glyph_stride,
329 first_advance, advance_stride,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600330 !klass->user_data ? nullptr : klass->user_data->glyph_h_advances);
Behdad Esfahbod79e21982018-08-06 09:45:17 -0700331 }
332
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330333 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)
Behdad Esfahbod79e21982018-08-06 09:45:17 -0700338 {
339 return klass->get.f.glyph_v_advances (this, user_data,
340 count,
341 first_glyph, glyph_stride,
342 first_advance, advance_stride,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600343 !klass->user_data ? nullptr : klass->user_data->glyph_v_advances);
Behdad Esfahbod79e21982018-08-06 09:45:17 -0700344 }
345
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330346 hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
Ebrahim Byagowi2dda6dd2020-04-20 14:12:45 +0430347 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400348 {
349 *x = *y = 0;
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800350 return klass->get.f.glyph_h_origin (this, user_data,
351 glyph, x, y,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600352 !klass->user_data ? nullptr : klass->user_data->glyph_h_origin);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400353 }
354
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330355 hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
356 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400357 {
358 *x = *y = 0;
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800359 return klass->get.f.glyph_v_origin (this, user_data,
360 glyph, x, y,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600361 !klass->user_data ? nullptr : klass->user_data->glyph_v_origin);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400362 }
363
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330364 hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
365 hb_codepoint_t right_glyph)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400366 {
Behdad Esfahbodfca27862019-05-11 00:37:01 -0700367#ifdef HB_DISABLE_DEPRECATED
368 return 0;
369#else
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800370 return klass->get.f.glyph_h_kerning (this, user_data,
371 left_glyph, right_glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600372 !klass->user_data ? nullptr : klass->user_data->glyph_h_kerning);
Behdad Esfahbodfca27862019-05-11 00:37:01 -0700373#endif
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400374 }
375
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330376 hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
377 hb_codepoint_t bottom_glyph)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400378 {
Behdad Esfahbodfca27862019-05-11 00:37:01 -0700379#ifdef HB_DISABLE_DEPRECATED
380 return 0;
381#else
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800382 return klass->get.f.glyph_v_kerning (this, user_data,
383 top_glyph, bottom_glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600384 !klass->user_data ? nullptr : klass->user_data->glyph_v_kerning);
Behdad Esfahbodfca27862019-05-11 00:37:01 -0700385#endif
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400386 }
387
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330388 hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
Ebrahim Byagowi05584132019-10-01 13:49:55 +0330389 hb_glyph_extents_t *extents)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400390 {
Behdad Esfahbodac0efaf2022-11-22 12:50:36 -0700391 hb_memset (extents, 0, sizeof (*extents));
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800392 return klass->get.f.glyph_extents (this, user_data,
393 glyph,
394 extents,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600395 !klass->user_data ? nullptr : klass->user_data->glyph_extents);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400396 }
397
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330398 hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
Ebrahim Byagowid0e2add2020-07-18 22:14:52 +0430399 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400400 {
401 *x = *y = 0;
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800402 return klass->get.f.glyph_contour_point (this, user_data,
403 glyph, point_index,
404 x, y,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600405 !klass->user_data ? nullptr : klass->user_data->glyph_contour_point);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400406 }
407
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330408 hb_bool_t get_glyph_name (hb_codepoint_t glyph,
409 char *name, unsigned int size)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400410 {
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400411 if (size) *name = '\0';
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800412 return klass->get.f.glyph_name (this, user_data,
413 glyph,
414 name, size,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600415 !klass->user_data ? nullptr : klass->user_data->glyph_name);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400416 }
417
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330418 hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
419 hb_codepoint_t *glyph)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400420 {
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400421 *glyph = 0;
422 if (len == -1) len = strlen (name);
Behdad Esfahbod88e9a9b2015-11-04 21:16:26 -0800423 return klass->get.f.glyph_from_name (this, user_data,
424 name, len,
425 glyph,
Behdad Esfahbod88ccbd22022-06-01 08:44:07 -0600426 !klass->user_data ? nullptr : klass->user_data->glyph_from_name);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400427 }
428
Matthias Clasen14b026f2022-12-19 13:53:49 -0500429 void draw_glyph (hb_codepoint_t glyph,
430 hb_draw_funcs_t *draw_funcs, void *draw_data)
Behdad Esfahbod8b4f4292022-02-03 01:14:47 -0600431 {
Matthias Clasen14b026f2022-12-19 13:53:49 -0500432 klass->get.f.draw_glyph (this, user_data,
433 glyph,
434 draw_funcs, draw_data,
435 !klass->user_data ? nullptr : klass->user_data->draw_glyph);
Behdad Esfahbod8b4f4292022-02-03 01:14:47 -0600436 }
437
Matthias Clasen0f287e72022-12-19 13:45:45 -0500438 void paint_glyph (hb_codepoint_t glyph,
Matthias Clasen9be01b62022-12-21 14:04:32 -0500439 hb_paint_funcs_t *paint_funcs, void *paint_data,
440 unsigned int palette,
441 hb_color_t foreground)
Matthias Clasen71efa0d2022-12-14 06:22:00 -0500442 {
Matthias Clasen0f287e72022-12-19 13:45:45 -0500443 klass->get.f.paint_glyph (this, user_data,
Matthias Clasen71efa0d2022-12-14 06:22:00 -0500444 glyph,
445 paint_funcs, paint_data,
Matthias Clasen9be01b62022-12-21 14:04:32 -0500446 palette, foreground,
Matthias Clasen0f287e72022-12-19 13:45:45 -0500447 !klass->user_data ? nullptr : klass->user_data->paint_glyph);
Matthias Clasen71efa0d2022-12-14 06:22:00 -0500448 }
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400449
450 /* A bit higher-level, and with fallback */
451
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330452 void get_h_extents_with_fallback (hb_font_extents_t *extents)
Behdad Esfahboda7b32f22016-10-26 18:08:41 +0200453 {
454 if (!get_font_h_extents (extents))
455 {
456 extents->ascender = y_scale * .8;
457 extents->descender = extents->ascender - y_scale;
458 extents->line_gap = 0;
459 }
460 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330461 void get_v_extents_with_fallback (hb_font_extents_t *extents)
Behdad Esfahboda7b32f22016-10-26 18:08:41 +0200462 {
463 if (!get_font_v_extents (extents))
464 {
465 extents->ascender = x_scale / 2;
466 extents->descender = extents->ascender - x_scale;
467 extents->line_gap = 0;
468 }
469 }
470
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330471 void get_extents_for_direction (hb_direction_t direction,
472 hb_font_extents_t *extents)
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900473 {
Behdad Esfahboda7b32f22016-10-26 18:08:41 +0200474 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
475 get_h_extents_with_fallback (extents);
476 else
477 get_v_extents_with_fallback (extents);
Simon Cozens6f2e6de2015-10-26 16:23:22 +0900478 }
479
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330480 void get_glyph_advance_for_direction (hb_codepoint_t glyph,
481 hb_direction_t direction,
482 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400483 {
Behdad Esfahbod99677512018-08-07 09:44:01 -0700484 *x = *y = 0;
485 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400486 *x = get_glyph_h_advance (glyph);
Behdad Esfahbod99677512018-08-07 09:44:01 -0700487 else
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400488 *y = get_glyph_v_advance (glyph);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400489 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330490 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)
Behdad Esfahbodb0ff79a2018-08-07 09:52:06 -0700496 {
497 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
498 get_glyph_h_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
499 else
500 get_glyph_v_advances (count, first_glyph, glyph_stride, first_advance, advance_stride);
501 }
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400502
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330503 void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
504 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400505 {
506 *x = get_glyph_h_advance (glyph) / 2;
507
Behdad Esfahbod2b117722016-10-26 18:12:50 +0200508 hb_font_extents_t extents;
509 get_h_extents_with_fallback (&extents);
510 *y = extents.ascender;
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400511 }
512
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330513 void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph,
514 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200515 {
516 if (!get_glyph_h_origin (glyph, x, y) &&
517 get_glyph_v_origin (glyph, x, y))
518 {
519 hb_position_t dx, dy;
520 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
521 *x -= dx; *y -= dy;
522 }
523 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330524 void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph,
525 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200526 {
527 if (!get_glyph_v_origin (glyph, x, y) &&
528 get_glyph_h_origin (glyph, x, y))
529 {
530 hb_position_t dx, dy;
531 guess_v_origin_minus_h_origin (glyph, &dx, &dy);
532 *x += dx; *y += dy;
533 }
534 }
535
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330536 void get_glyph_origin_for_direction (hb_codepoint_t glyph,
537 hb_direction_t direction,
538 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400539 {
Behdad Esfahbod7235f332013-06-10 14:39:51 -0400540 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200541 get_glyph_h_origin_with_fallback (glyph, x, y);
Behdad Esfahbod7235f332013-06-10 14:39:51 -0400542 else
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200543 get_glyph_v_origin_with_fallback (glyph, x, y);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400544 }
545
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330546 void add_glyph_h_origin (hb_codepoint_t glyph,
547 hb_position_t *x, hb_position_t *y)
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800548 {
549 hb_position_t origin_x, origin_y;
550
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200551 get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800552
553 *x += origin_x;
554 *y += origin_y;
555 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330556 void add_glyph_v_origin (hb_codepoint_t glyph,
557 hb_position_t *x, hb_position_t *y)
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800558 {
559 hb_position_t origin_x, origin_y;
560
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200561 get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800562
563 *x += origin_x;
564 *y += origin_y;
565 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330566 void add_glyph_origin_for_direction (hb_codepoint_t glyph,
567 hb_direction_t direction,
568 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400569 {
570 hb_position_t origin_x, origin_y;
571
572 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
573
574 *x += origin_x;
575 *y += origin_y;
576 }
577
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330578 void subtract_glyph_h_origin (hb_codepoint_t glyph,
Ebrahim Byagowi05584132019-10-01 13:49:55 +0330579 hb_position_t *x, hb_position_t *y)
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800580 {
581 hb_position_t origin_x, origin_y;
582
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200583 get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y);
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800584
585 *x -= origin_x;
586 *y -= origin_y;
587 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330588 void subtract_glyph_v_origin (hb_codepoint_t glyph,
589 hb_position_t *x, hb_position_t *y)
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800590 {
591 hb_position_t origin_x, origin_y;
592
Behdad Esfahbod9ee23c42016-10-26 17:44:16 +0200593 get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y);
Behdad Esfahbodbee901b2015-11-04 19:28:17 -0800594
595 *x -= origin_x;
596 *y -= origin_y;
597 }
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330598 void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
599 hb_direction_t direction,
600 hb_position_t *x, hb_position_t *y)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400601 {
602 hb_position_t origin_x, origin_y;
603
604 get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
605
606 *x -= origin_x;
607 *y -= origin_y;
608 }
609
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330610 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)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400613 {
614 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400615 *y = 0;
Behdad Esfahbod683c3a92018-10-08 23:09:48 -0400616 *x = get_glyph_h_kerning (first_glyph, second_glyph);
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400617 } else {
618 *x = 0;
619 *y = get_glyph_v_kerning (first_glyph, second_glyph);
620 }
621 }
622
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330623 hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
624 hb_direction_t direction,
625 hb_glyph_extents_t *extents)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400626 {
627 hb_bool_t ret = get_glyph_extents (glyph, extents);
628
629 if (ret)
630 subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
631
632 return ret;
633 }
634
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330635 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)
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400638 {
639 hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
640
641 if (ret)
642 subtract_glyph_origin_for_direction (glyph, direction, x, y);
643
644 return ret;
645 }
646
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400647 /* Generates gidDDD if glyph has no name. */
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330648 void
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400649 glyph_to_string (hb_codepoint_t glyph,
650 char *s, unsigned int size)
651 {
652 if (get_glyph_name (glyph, s, size)) return;
653
Behdad Esfahbod38b8b402013-08-27 11:44:09 -0400654 if (size && snprintf (s, size, "gid%u", glyph) < 0)
655 *s = '\0';
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400656 }
657
658 /* Parses gidDDD and uniUUUU strings automatically. */
Ebrahim Byagowib2ebaa92018-12-16 22:38:10 +0330659 hb_bool_t
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400660 glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
661 hb_codepoint_t *glyph)
662 {
663 if (get_glyph_from_name (s, len, glyph)) return true;
664
665 if (len == -1) len = strlen (s);
666
667 /* Straight glyph index. */
668 if (hb_codepoint_parse (s, len, 10, glyph))
669 return true;
670
671 if (len > 3)
672 {
673 /* gidDDD syntax for glyph indices. */
674 if (0 == strncmp (s, "gid", 3) &&
675 hb_codepoint_parse (s + 3, len - 3, 10, glyph))
676 return true;
677
678 /* uniUUUU and other Unicode character indices. */
679 hb_codepoint_t unichar;
680 if (0 == strncmp (s, "uni", 3) &&
681 hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
Behdad Esfahbod8b5bc142016-02-24 19:05:23 +0900682 get_nominal_glyph (unichar, glyph))
Behdad Esfahbod6f3a3002012-08-07 22:13:25 -0400683 return true;
684 }
685
686 return false;
687 }
Behdad Esfahbod8fbfda92012-08-01 19:03:46 -0400688
Behdad Esfahbodb8477692019-07-05 13:52:09 -0700689 void mults_changed ()
690 {
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600691 float upem = face->get_upem ();
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700692
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600693 x_multf = x_scale / upem;
694 y_multf = y_scale / upem;
Behdad Esfahbodcd05d182022-06-01 07:27:30 -0600695 bool x_neg = x_scale < 0;
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600696 x_mult = (x_neg ? -((int64_t) -x_scale << 16) : ((int64_t) x_scale << 16)) / upem;
Behdad Esfahbodcd05d182022-06-01 07:27:30 -0600697 bool y_neg = y_scale < 0;
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600698 y_mult = (y_neg ? -((int64_t) -y_scale << 16) : ((int64_t) y_scale << 16)) / upem;
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700699
Behdad Esfahbod8c1b47d2023-02-19 20:38:43 -0700700 x_strength = fabsf (roundf (x_scale * x_embolden));
701 y_strength = fabsf (roundf (y_scale * y_embolden));
Behdad Esfahbode39104b2023-02-01 16:56:56 -0700702
Behdad Esfahbodff697de2021-12-19 07:25:37 -0700703 slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
Behdad Esfahbodc1c78ad2022-06-28 13:19:12 -0600704
705 data.fini ();
Behdad Esfahbodb8477692019-07-05 13:52:09 -0700706 }
707
Behdad Esfahbodf18ea1d2019-07-05 13:56:45 -0700708 hb_position_t em_mult (int16_t v, int64_t mult)
Behdad Esfahbodbbaccf22021-11-01 16:45:36 -0600709 { return (hb_position_t) ((v * mult + 32768) >> 16); }
Behdad Esfahbodd3308f42022-06-27 11:28:44 -0600710 hb_position_t em_multf (float v, float mult)
711 { return (hb_position_t) roundf (em_fmultf (v, mult)); }
712 float em_fmultf (float v, float mult)
713 { return v * mult; }
714 float em_fmult (int16_t v, float mult)
715 { return (float) v * mult; }
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400716};
Behdad Esfahbod35066722018-08-06 06:17:48 -0700717DECLARE_NULL_INSTANCE (hb_font_t);
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400718
Behdad Esfahbodc62b5032009-08-01 19:54:49 -0400719
Behdad Esfahbodc77ae402018-08-25 22:36:36 -0700720#endif /* HB_FONT_HH */