| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Red Hat, Inc. | 2 * Copyright © 2009 Red Hat, Inc. |
| 3 * | 3 * |
| 4 * This is part of HarfBuzz, a text shaping library. | 4 * This is part of HarfBuzz, a text shaping library. |
| 5 * | 5 * |
| 6 * Permission is hereby granted, without written agreement and without | 6 * Permission is hereby granted, without written agreement and without |
| 7 * license or royalty fees, to use, copy, modify, and distribute this | 7 * license or royalty fees, to use, copy, modify, and distribute this |
| 8 * software and its documentation for any purpose, provided that the | 8 * software and its documentation for any purpose, provided that the |
| 9 * above copyright notice and the following two paragraphs appear in | 9 * above copyright notice and the following two paragraphs appear in |
| 10 * all copies of this software. | 10 * all copies of this software. |
| 11 * | 11 * |
| 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
| 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
| 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
| 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
| 16 * DAMAGE. | 16 * DAMAGE. |
| 17 * | 17 * |
| 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
| 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
| 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
| 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 23 * | 23 * |
| 24 * Red Hat Author(s): Behdad Esfahbod | 24 * Red Hat Author(s): Behdad Esfahbod |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "hb-private.h" | 27 #include "hb-private.hh" |
| 28 | 28 |
| 29 #include "hb-font-private.h" | 29 #include "hb-ot-layout-private.hh" |
| 30 #include "hb-blob-private.h" | 30 |
| 31 #include "hb-font-private.hh" |
| 32 #include "hb-blob.h" |
| 31 #include "hb-open-file-private.hh" | 33 #include "hb-open-file-private.hh" |
| 32 | 34 #include "hb-ot-head-table.hh" |
| 33 #include "hb-ot-layout-private.hh" | |
| 34 | 35 |
| 35 #include <string.h> | 36 #include <string.h> |
| 36 | 37 |
| 37 HB_BEGIN_DECLS | |
| 38 | 38 |
| 39 | 39 |
| 40 /* | 40 /* |
| 41 * hb_font_funcs_t | 41 * hb_font_funcs_t |
| 42 */ | 42 */ |
| 43 | 43 |
| 44 static hb_codepoint_t | 44 static hb_bool_t |
| 45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, | 45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, |
| 46 » » hb_face_t *face HB_UNUSED, | 46 » » void *font_data HB_UNUSED, |
| 47 » » const void *user_data HB_UNUSED, | 47 » » hb_codepoint_t unicode, |
| 48 » » hb_codepoint_t unicode HB_UNUSED, | 48 » » hb_codepoint_t variation_selector, |
| 49 » » hb_codepoint_t variation_selector HB_UNUSED) | 49 » » hb_codepoint_t *glyph, |
| 50 { return 0; } | 50 » » void *user_data HB_UNUSED) |
| 51 | 51 { |
| 52 static void | 52 if (font->parent) |
| 53 hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED, | 53 return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph); |
| 54 » » » hb_face_t *face HB_UNUSED, | 54 |
| 55 » » » const void *user_data HB_UNUSED, | 55 *glyph = 0; |
| 56 » » » hb_codepoint_t glyph HB_UNUSED, | 56 return FALSE; |
| 57 » » » hb_position_t *x_advance HB_UNUSED, | 57 } |
| 58 » » » hb_position_t *y_advance HB_UNUSED) | 58 |
| 59 { } | 59 static hb_position_t |
| 60 | 60 hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, |
| 61 static void | 61 » » » » void *font_data HB_UNUSED, |
| 62 » » » » hb_codepoint_t glyph, |
| 63 » » » » void *user_data HB_UNUSED) |
| 64 { |
| 65 if (font->parent) |
| 66 return font->parent_scale_x_distance (hb_font_get_glyph_h_advance (font->par
ent, glyph)); |
| 67 |
| 68 return font->x_scale; |
| 69 } |
| 70 |
| 71 static hb_position_t |
| 72 hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, |
| 73 » » » » void *font_data HB_UNUSED, |
| 74 » » » » hb_codepoint_t glyph, |
| 75 » » » » void *user_data HB_UNUSED) |
| 76 { |
| 77 if (font->parent) |
| 78 return font->parent_scale_y_distance (hb_font_get_glyph_v_advance (font->par
ent, glyph)); |
| 79 |
| 80 return font->y_scale; |
| 81 } |
| 82 |
| 83 static hb_bool_t |
| 84 hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, |
| 85 » » » » void *font_data HB_UNUSED, |
| 86 » » » » hb_codepoint_t glyph, |
| 87 » » » » hb_position_t *x, |
| 88 » » » » hb_position_t *y, |
| 89 » » » » void *user_data HB_UNUSED) |
| 90 { |
| 91 if (font->parent) { |
| 92 hb_bool_t ret = hb_font_get_glyph_h_origin (font->parent, |
| 93 » » » » » » glyph, |
| 94 » » » » » » x, y); |
| 95 if (ret) |
| 96 font->parent_scale_position (x, y); |
| 97 return ret; |
| 98 } |
| 99 |
| 100 *x = *y = 0; |
| 101 return FALSE; |
| 102 } |
| 103 |
| 104 static hb_bool_t |
| 105 hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, |
| 106 » » » » void *font_data HB_UNUSED, |
| 107 » » » » hb_codepoint_t glyph, |
| 108 » » » » hb_position_t *x, |
| 109 » » » » hb_position_t *y, |
| 110 » » » » void *user_data HB_UNUSED) |
| 111 { |
| 112 if (font->parent) { |
| 113 hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent, |
| 114 » » » » » » glyph, |
| 115 » » » » » » x, y); |
| 116 if (ret) |
| 117 font->parent_scale_position (x, y); |
| 118 return ret; |
| 119 } |
| 120 |
| 121 *x = *y = 0; |
| 122 return FALSE; |
| 123 } |
| 124 |
| 125 static hb_position_t |
| 126 hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, |
| 127 » » » » void *font_data HB_UNUSED, |
| 128 » » » » hb_codepoint_t left_glyph, |
| 129 » » » » hb_codepoint_t right_glyph, |
| 130 » » » » void *user_data HB_UNUSED) |
| 131 { |
| 132 if (font->parent) |
| 133 return font->parent_scale_x_distance (hb_font_get_glyph_h_kerning (font->par
ent, left_glyph, right_glyph)); |
| 134 |
| 135 return 0; |
| 136 } |
| 137 |
| 138 static hb_position_t |
| 139 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, |
| 140 » » » » void *font_data HB_UNUSED, |
| 141 » » » » hb_codepoint_t top_glyph, |
| 142 » » » » hb_codepoint_t bottom_glyph, |
| 143 » » » » void *user_data HB_UNUSED) |
| 144 { |
| 145 if (font->parent) |
| 146 return font->parent_scale_y_distance (hb_font_get_glyph_v_kerning (font->par
ent, top_glyph, bottom_glyph)); |
| 147 |
| 148 return 0; |
| 149 } |
| 150 |
| 151 static hb_bool_t |
| 62 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, | 152 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, |
| 63 » » » hb_face_t *face HB_UNUSED, | 153 » » » void *font_data HB_UNUSED, |
| 64 » » » const void *user_data HB_UNUSED, | 154 » » » hb_codepoint_t glyph, |
| 65 » » » hb_codepoint_t glyph HB_UNUSED, | 155 » » » hb_glyph_extents_t *extents, |
| 66 » » » hb_glyph_extents_t *extents HB_UNUSED) | 156 » » » void *user_data HB_UNUSED) |
| 67 { } | 157 { |
| 68 | 158 if (font->parent) { |
| 69 static hb_bool_t | 159 hb_bool_t ret = hb_font_get_glyph_extents (font->parent, |
| 70 hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED, | 160 » » » » » glyph, |
| 71 » » » hb_face_t *face HB_UNUSED, | 161 » » » » » extents); |
| 72 » » » const void *user_data HB_UNUSED, | 162 if (ret) { |
| 73 » » » unsigned int point_index HB_UNUSED, | 163 font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); |
| 74 » » » hb_codepoint_t glyph HB_UNUSED, | 164 font->parent_scale_distance (&extents->width, &extents->height); |
| 75 » » » hb_position_t *x HB_UNUSED, | 165 } |
| 76 » » » hb_position_t *y HB_UNUSED) | 166 return ret; |
| 77 { return false; } | 167 } |
| 78 | 168 |
| 79 static hb_position_t | 169 memset (extents, 0, sizeof (*extents)); |
| 80 hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED, | 170 return FALSE; |
| 81 » » » hb_face_t *face HB_UNUSED, | 171 } |
| 82 » » » const void *user_data HB_UNUSED, | 172 |
| 83 » » » hb_codepoint_t first_glyph HB_UNUSED, | 173 static hb_bool_t |
| 84 » » » hb_codepoint_t second_glyph HB_UNUSED) | 174 hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, |
| 85 { return 0; } | 175 » » » » void *font_data HB_UNUSED, |
| 86 | 176 » » » » hb_codepoint_t glyph, |
| 87 hb_font_funcs_t _hb_font_funcs_nil = { | 177 » » » » unsigned int point_index, |
| 88 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 178 » » » » hb_position_t *x, |
| 89 TRUE, /* immutable */ | 179 » » » » hb_position_t *y, |
| 180 » » » » void *user_data HB_UNUSED) |
| 181 { |
| 182 if (font->parent) { |
| 183 hb_bool_t ret = hb_font_get_glyph_contour_point (font->parent, |
| 184 » » » » » » glyph, point_index, |
| 185 » » » » » » x, y); |
| 186 if (ret) |
| 187 font->parent_scale_position (x, y); |
| 188 return ret; |
| 189 } |
| 190 |
| 191 *x = *y = 0; |
| 192 return FALSE; |
| 193 } |
| 194 |
| 195 |
| 196 static hb_font_funcs_t _hb_font_funcs_nil = { |
| 197 HB_OBJECT_HEADER_STATIC, |
| 198 |
| 199 TRUE, /* immutable */ |
| 200 |
| 90 { | 201 { |
| 91 hb_font_get_glyph_nil, | 202 #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, |
| 92 hb_font_get_glyph_advance_nil, | 203 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
| 93 hb_font_get_glyph_extents_nil, | 204 #undef HB_FONT_FUNC_IMPLEMENT |
| 94 hb_font_get_contour_point_nil, | |
| 95 hb_font_get_kerning_nil | |
| 96 } | 205 } |
| 97 }; | 206 }; |
| 98 | 207 |
| 208 |
| 99 hb_font_funcs_t * | 209 hb_font_funcs_t * |
| 100 hb_font_funcs_create (void) | 210 hb_font_funcs_create (void) |
| 101 { | 211 { |
| 102 hb_font_funcs_t *ffuncs; | 212 hb_font_funcs_t *ffuncs; |
| 103 | 213 |
| 104 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) | 214 if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) |
| 105 return &_hb_font_funcs_nil; | 215 return &_hb_font_funcs_nil; |
| 106 | 216 |
| 107 ffuncs->v = _hb_font_funcs_nil.v; | 217 ffuncs->get = _hb_font_funcs_nil.get; |
| 108 | 218 |
| 109 return ffuncs; | 219 return ffuncs; |
| 110 } | 220 } |
| 111 | 221 |
| 112 hb_font_funcs_t * | 222 hb_font_funcs_t * |
| 223 hb_font_funcs_get_empty (void) |
| 224 { |
| 225 return &_hb_font_funcs_nil; |
| 226 } |
| 227 |
| 228 hb_font_funcs_t * |
| 113 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) | 229 hb_font_funcs_reference (hb_font_funcs_t *ffuncs) |
| 114 { | 230 { |
| 115 HB_OBJECT_DO_REFERENCE (ffuncs); | 231 return hb_object_reference (ffuncs); |
| 116 } | |
| 117 | |
| 118 unsigned int | |
| 119 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs) | |
| 120 { | |
| 121 HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs); | |
| 122 } | 232 } |
| 123 | 233 |
| 124 void | 234 void |
| 125 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) | 235 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) |
| 126 { | 236 { |
| 127 HB_OBJECT_DO_DESTROY (ffuncs); | 237 if (!hb_object_destroy (ffuncs)) return; |
| 238 |
| 239 #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ |
| 240 ffuncs->destroy.name (ffuncs->user_data.name); |
| 241 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
| 242 #undef HB_FONT_FUNC_IMPLEMENT |
| 128 | 243 |
| 129 free (ffuncs); | 244 free (ffuncs); |
| 130 } | 245 } |
| 131 | 246 |
| 132 hb_font_funcs_t * | 247 hb_bool_t |
| 133 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs) | 248 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, |
| 134 { | 249 » » » hb_user_data_key_t *key, |
| 135 hb_font_funcs_t *ffuncs; | 250 » » » void * data, |
| 136 | 251 » » » hb_destroy_func_t destroy, |
| 137 if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs)) | 252 » » » hb_bool_t replace) |
| 138 return &_hb_font_funcs_nil; | 253 { |
| 139 | 254 return hb_object_set_user_data (ffuncs, key, data, destroy, replace); |
| 140 ffuncs->v = other_ffuncs->v; | 255 } |
| 141 | 256 |
| 142 return ffuncs; | 257 void * |
| 143 } | 258 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, |
| 259 » » » hb_user_data_key_t *key) |
| 260 { |
| 261 return hb_object_get_user_data (ffuncs, key); |
| 262 } |
| 263 |
| 144 | 264 |
| 145 void | 265 void |
| 146 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) | 266 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) |
| 147 { | 267 { |
| 148 if (HB_OBJECT_IS_INERT (ffuncs)) | 268 if (hb_object_is_inert (ffuncs)) |
| 149 return; | 269 return; |
| 150 | 270 |
| 151 ffuncs->immutable = TRUE; | 271 ffuncs->immutable = TRUE; |
| 152 } | 272 } |
| 153 | 273 |
| 154 hb_bool_t | 274 hb_bool_t |
| 155 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) | 275 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) |
| 156 { | 276 { |
| 157 return ffuncs->immutable; | 277 return ffuncs->immutable; |
| 158 } | 278 } |
| 159 | 279 |
| 160 | 280 |
| 161 void | 281 #define HB_FONT_FUNC_IMPLEMENT(name) \ |
| 162 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, | 282 \ |
| 163 » » » hb_font_get_glyph_func_t glyph_func) | 283 void \ |
| 164 { | 284 hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ |
| 165 if (ffuncs->immutable) | 285 hb_font_get_##name##_func_t func, \ |
| 166 return; | 286 void *user_data, \ |
| 167 | 287 hb_destroy_func_t destroy) \ |
| 168 ffuncs->v.get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil; | 288 { \ |
| 169 } | 289 if (ffuncs->immutable) { \ |
| 170 | 290 if (destroy) \ |
| 171 void | 291 destroy (user_data); \ |
| 172 hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs, | 292 return; \ |
| 173 » » » » hb_font_get_glyph_advance_func_t glyph_adv
ance_func) | 293 } \ |
| 174 { | 294 \ |
| 175 if (ffuncs->immutable) | 295 if (ffuncs->destroy.name) \ |
| 176 return; | 296 ffuncs->destroy.name (ffuncs->user_data.name); \ |
| 177 | 297 \ |
| 178 ffuncs->v.get_glyph_advance = glyph_advance_func ? glyph_advance_func : hb_fon
t_get_glyph_advance_nil; | 298 if (func) { \ |
| 179 } | 299 ffuncs->get.name = func; \ |
| 180 | 300 ffuncs->user_data.name = user_data; \ |
| 181 void | 301 ffuncs->destroy.name = destroy; \ |
| 182 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, | 302 } else { \ |
| 183 » » » » hb_font_get_glyph_extents_func_t glyph_ext
ents_func) | 303 ffuncs->get.name = hb_font_get_##name##_nil; \ |
| 184 { | 304 ffuncs->user_data.name = NULL; \ |
| 185 if (ffuncs->immutable) | 305 ffuncs->destroy.name = NULL; \ |
| 186 return; | 306 } \ |
| 187 | 307 } |
| 188 ffuncs->v.get_glyph_extents = glyph_extents_func ? glyph_extents_func : hb_fon
t_get_glyph_extents_nil; | 308 |
| 189 } | 309 HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
| 190 | 310 #undef HB_FONT_FUNC_IMPLEMENT |
| 191 void | 311 |
| 192 hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs, | 312 |
| 193 » » » » hb_font_get_contour_point_func_t contour_p
oint_func) | 313 hb_bool_t |
| 194 { | 314 hb_font_get_glyph (hb_font_t *font, |
| 195 if (ffuncs->immutable) | 315 » » hb_codepoint_t unicode, hb_codepoint_t variation_selector, |
| 196 return; | 316 » » hb_codepoint_t *glyph) |
| 197 | 317 { |
| 198 ffuncs->v.get_contour_point = contour_point_func ? contour_point_func : hb_fon
t_get_contour_point_nil; | 318 *glyph = 0; |
| 199 } | 319 return font->klass->get.glyph (font, font->user_data, |
| 200 | 320 » » » » unicode, variation_selector, glyph, |
| 201 void | 321 » » » » font->klass->user_data.glyph); |
| 202 hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs, | 322 } |
| 203 » » » » hb_font_get_kerning_func_t kerning_func) | 323 |
| 204 { | 324 hb_position_t |
| 205 if (ffuncs->immutable) | 325 hb_font_get_glyph_h_advance (hb_font_t *font, |
| 206 return; | 326 » » » hb_codepoint_t glyph) |
| 207 | 327 { |
| 208 ffuncs->v.get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil; | 328 return font->klass->get.glyph_h_advance (font, font->user_data, |
| 209 } | 329 » » » » » glyph, |
| 210 | 330 » » » » » font->klass->user_data.glyph_h_advanc
e); |
| 211 | 331 } |
| 212 hb_font_get_glyph_func_t | 332 |
| 213 hb_font_funcs_get_glyph_func (hb_font_funcs_t *ffuncs) | 333 hb_position_t |
| 214 { | 334 hb_font_get_glyph_v_advance (hb_font_t *font, |
| 215 return ffuncs->v.get_glyph; | 335 » » » hb_codepoint_t glyph) |
| 216 } | 336 { |
| 217 | 337 return font->klass->get.glyph_v_advance (font, font->user_data, |
| 218 hb_font_get_glyph_advance_func_t | 338 » » » » » glyph, |
| 219 hb_font_funcs_get_glyph_advance_func (hb_font_funcs_t *ffuncs) | 339 » » » » » font->klass->user_data.glyph_v_advanc
e); |
| 220 { | 340 } |
| 221 return ffuncs->v.get_glyph_advance; | 341 |
| 222 } | 342 hb_bool_t |
| 223 | 343 hb_font_get_glyph_h_origin (hb_font_t *font, |
| 224 hb_font_get_glyph_extents_func_t | 344 » » » hb_codepoint_t glyph, |
| 225 hb_font_funcs_get_glyph_extents_func (hb_font_funcs_t *ffuncs) | 345 » » » hb_position_t *x, hb_position_t *y) |
| 226 { | 346 { |
| 227 return ffuncs->v.get_glyph_extents; | 347 *x = *y = 0; |
| 228 } | 348 return font->klass->get.glyph_h_origin (font, font->user_data, |
| 229 | 349 » » » » » glyph, x, y, |
| 230 hb_font_get_contour_point_func_t | 350 » » » » » font->klass->user_data.glyph_h_origin
); |
| 231 hb_font_funcs_get_contour_point_func (hb_font_funcs_t *ffuncs) | 351 } |
| 232 { | 352 |
| 233 return ffuncs->v.get_contour_point; | 353 hb_bool_t |
| 234 } | 354 hb_font_get_glyph_v_origin (hb_font_t *font, |
| 235 | 355 » » » hb_codepoint_t glyph, |
| 236 hb_font_get_kerning_func_t | 356 » » » hb_position_t *x, hb_position_t *y) |
| 237 hb_font_funcs_get_kerning_func (hb_font_funcs_t *ffuncs) | 357 { |
| 238 { | 358 *x = *y = 0; |
| 239 return ffuncs->v.get_kerning; | 359 return font->klass->get.glyph_v_origin (font, font->user_data, |
| 240 } | 360 » » » » » glyph, x, y, |
| 241 | 361 » » » » » font->klass->user_data.glyph_v_origin
); |
| 242 | 362 } |
| 243 | 363 |
| 244 hb_codepoint_t | 364 hb_position_t |
| 245 hb_font_get_glyph (hb_font_t *font, hb_face_t *face, | 365 hb_font_get_glyph_h_kerning (hb_font_t *font, |
| 246 » » hb_codepoint_t unicode, hb_codepoint_t variation_selector) | 366 » » » hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
| 247 { | 367 { |
| 248 return font->klass->v.get_glyph (font, face, font->user_data, | 368 return font->klass->get.glyph_h_kerning (font, font->user_data, |
| 249 » » » » unicode, variation_selector); | 369 » » » » » left_glyph, right_glyph, |
| 250 } | 370 » » » » » font->klass->user_data.glyph_h_kernin
g); |
| 251 | 371 } |
| 252 void | 372 |
| 253 hb_font_get_glyph_advance (hb_font_t *font, hb_face_t *face, | 373 hb_position_t |
| 374 hb_font_get_glyph_v_kerning (hb_font_t *font, |
| 375 » » » hb_codepoint_t left_glyph, hb_codepoint_t right_gly
ph) |
| 376 { |
| 377 return font->klass->get.glyph_v_kerning (font, font->user_data, |
| 378 » » » » left_glyph, right_glyph, |
| 379 » » » » font->klass->user_data.glyph_v_kerning); |
| 380 } |
| 381 |
| 382 hb_bool_t |
| 383 hb_font_get_glyph_extents (hb_font_t *font, |
| 254 hb_codepoint_t glyph, | 384 hb_codepoint_t glyph, |
| 255 » » » hb_position_t *x_advance, hb_position_t *y_advance) | 385 » » » hb_glyph_extents_t *extents) |
| 256 { | |
| 257 *x_advance = *y_advance = 0; | |
| 258 return font->klass->v.get_glyph_advance (font, face, font->user_data, | |
| 259 » » » » » glyph, x_advance, y_advance); | |
| 260 } | |
| 261 | |
| 262 void | |
| 263 hb_font_get_glyph_extents (hb_font_t *font, hb_face_t *face, | |
| 264 » » » hb_codepoint_t glyph, hb_glyph_extents_t *extents) | |
| 265 { | 386 { |
| 266 memset (extents, 0, sizeof (*extents)); | 387 memset (extents, 0, sizeof (*extents)); |
| 267 return font->klass->v.get_glyph_extents (font, face, font->user_data, | 388 return font->klass->get.glyph_extents (font, font->user_data, |
| 268 » » » » » glyph, extents); | 389 » » » » » glyph, |
| 269 } | 390 » » » » » extents, |
| 270 | 391 » » » » » font->klass->user_data.glyph_extents); |
| 271 hb_bool_t | 392 } |
| 272 hb_font_get_contour_point (hb_font_t *font, hb_face_t *face, | 393 |
| 273 » » » unsigned int point_index, | 394 hb_bool_t |
| 274 » » » hb_codepoint_t glyph, hb_position_t *x, hb_position_t
*y) | 395 hb_font_get_glyph_contour_point (hb_font_t *font, |
| 275 { | 396 » » » » hb_codepoint_t glyph, unsigned int point_index, |
| 276 *x = 0; *y = 0; | 397 » » » » hb_position_t *x, hb_position_t *y) |
| 277 return font->klass->v.get_contour_point (font, face, font->user_data, | 398 { |
| 278 » » » » » point_index, | 399 *x = *y = 0; |
| 279 » » » » » glyph, x, y); | 400 return font->klass->get.glyph_contour_point (font, font->user_data, |
| 280 } | 401 » » » » » glyph, point_index, |
| 281 | 402 » » » » » x, y, |
| 282 hb_position_t | 403 » » » » » font->klass->user_data.glyph_cont
our_point); |
| 283 hb_font_get_kerning (hb_font_t *font, hb_face_t *face, | 404 } |
| 284 » » hb_codepoint_t first_glyph, hb_codepoint_t second_glyph) | 405 |
| 285 { | 406 |
| 286 return font->klass->v.get_kerning (font, face, font->user_data, | 407 /* A bit higher-level, and with fallback */ |
| 287 » » » » first_glyph, second_glyph); | 408 |
| 288 } | 409 void |
| 289 | 410 hb_font_get_glyph_advance_for_direction (hb_font_t *font, |
| 290 | 411 » » » » » hb_codepoint_t glyph, |
| 412 » » » » » hb_direction_t direction, |
| 413 » » » » » hb_position_t *x, hb_position_t *y) |
| 414 { |
| 415 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 416 *x = hb_font_get_glyph_h_advance (font, glyph); |
| 417 *y = 0; |
| 418 } else { |
| 419 *x = 0; |
| 420 *y = hb_font_get_glyph_v_advance (font, glyph); |
| 421 } |
| 422 } |
| 423 |
| 424 static void |
| 425 guess_v_origin_minus_h_origin (hb_font_t *font, |
| 426 » » » hb_codepoint_t glyph, |
| 427 » » » hb_position_t *x, hb_position_t *y) |
| 428 { |
| 429 *x = hb_font_get_glyph_h_advance (font, glyph) / 2; |
| 430 |
| 431 /* TODO use font_metics.ascent */ |
| 432 *y = font->y_scale; |
| 433 } |
| 434 |
| 435 |
| 436 void |
| 437 hb_font_get_glyph_origin_for_direction (hb_font_t *font, |
| 438 » » » » » hb_codepoint_t glyph, |
| 439 » » » » » hb_direction_t direction, |
| 440 » » » » » hb_position_t *x, hb_position_t *y) |
| 441 { |
| 442 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 443 hb_bool_t ret = hb_font_get_glyph_h_origin (font, glyph, x, y); |
| 444 if (!ret && (ret = hb_font_get_glyph_v_origin (font, glyph, x, y))) { |
| 445 hb_position_t dx, dy; |
| 446 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); |
| 447 *x -= dx; *y -= dy; |
| 448 } |
| 449 } else { |
| 450 hb_bool_t ret = hb_font_get_glyph_v_origin (font, glyph, x, y); |
| 451 if (!ret && (ret = hb_font_get_glyph_h_origin (font, glyph, x, y))) { |
| 452 hb_position_t dx, dy; |
| 453 guess_v_origin_minus_h_origin (font, glyph, &dx, &dy); |
| 454 *x += dx; *y += dy; |
| 455 } |
| 456 } |
| 457 } |
| 458 |
| 459 void |
| 460 hb_font_add_glyph_origin_for_direction (hb_font_t *font, |
| 461 » » » » » hb_codepoint_t glyph, |
| 462 » » » » » hb_direction_t direction, |
| 463 » » » » » hb_position_t *x, hb_position_t *y) |
| 464 { |
| 465 hb_position_t origin_x, origin_y; |
| 466 |
| 467 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); |
| 468 |
| 469 *x += origin_x; |
| 470 *y += origin_y; |
| 471 } |
| 472 |
| 473 void |
| 474 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, |
| 475 » » » » » hb_codepoint_t glyph, |
| 476 » » » » » hb_direction_t direction, |
| 477 » » » » » hb_position_t *x, hb_position_t *y) |
| 478 { |
| 479 hb_position_t origin_x, origin_y; |
| 480 |
| 481 hb_font_get_glyph_origin_for_direction (font, glyph, direction, &origin_x, &or
igin_y); |
| 482 |
| 483 *x -= origin_x; |
| 484 *y -= origin_y; |
| 485 } |
| 486 |
| 487 void |
| 488 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, |
| 489 » » » » » hb_codepoint_t first_glyph, hb_codepoin
t_t second_glyph, |
| 490 » » » » » hb_direction_t direction, |
| 491 » » » » » hb_position_t *x, hb_position_t *y) |
| 492 { |
| 493 if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
| 494 *x = hb_font_get_glyph_h_kerning (font, first_glyph, second_glyph); |
| 495 *y = 0; |
| 496 } else { |
| 497 *x = 0; |
| 498 *y = hb_font_get_glyph_v_kerning (font, first_glyph, second_glyph); |
| 499 } |
| 500 } |
| 501 |
| 502 hb_bool_t |
| 503 hb_font_get_glyph_extents_for_origin (hb_font_t *font, |
| 504 » » » » hb_codepoint_t glyph, |
| 505 » » » » hb_direction_t direction, |
| 506 » » » » hb_glyph_extents_t *extents) |
| 507 { |
| 508 hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, extents); |
| 509 |
| 510 if (ret) |
| 511 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, &extent
s->x_bearing, &extents->y_bearing); |
| 512 |
| 513 return ret; |
| 514 } |
| 515 |
| 516 hb_bool_t |
| 517 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, |
| 518 » » » » » hb_codepoint_t glyph, unsigned int p
oint_index, |
| 519 » » » » » hb_direction_t direction, |
| 520 » » » » » hb_position_t *x, hb_position_t *y) |
| 521 { |
| 522 hb_bool_t ret = hb_font_get_glyph_contour_point (font, glyph, point_index, x,
y); |
| 523 |
| 524 if (ret) |
| 525 hb_font_subtract_glyph_origin_for_direction (font, glyph, direction, x, y); |
| 526 |
| 527 return ret; |
| 528 } |
| 529 |
| 530 |
| 291 /* | 531 /* |
| 292 * hb_face_t | 532 * hb_face_t |
| 293 */ | 533 */ |
| 294 | 534 |
| 295 static hb_face_t _hb_face_nil = { | 535 static hb_face_t _hb_face_nil = { |
| 296 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 536 HB_OBJECT_HEADER_STATIC, |
| 297 | 537 |
| 298 NULL, /* get_table */ | 538 TRUE, /* immutable */ |
| 539 |
| 540 NULL, /* reference_table */ |
| 541 NULL, /* user_data */ |
| 299 NULL, /* destroy */ | 542 NULL, /* destroy */ |
| 300 NULL, /* user_data */ | |
| 301 | 543 |
| 302 NULL, /* head_blob */ | 544 NULL, /* ot_layout */ |
| 303 NULL, /* head_table */ | |
| 304 | 545 |
| 305 NULL /* ot_layout */ | 546 0, /* index */ |
| 547 1000 /* upem */ |
| 306 }; | 548 }; |
| 307 | 549 |
| 308 | 550 |
| 309 hb_face_t * | 551 hb_face_t * |
| 310 hb_face_create_for_tables (hb_get_table_func_t get_table, | 552 hb_face_create_for_tables (hb_reference_table_func_t reference_table, |
| 311 » » » hb_destroy_func_t destroy, | 553 » » » void *user_data, |
| 312 » » » void *user_data) | 554 » » » hb_destroy_func_t destroy) |
| 313 { | 555 { |
| 314 hb_face_t *face; | 556 hb_face_t *face; |
| 315 | 557 |
| 316 if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) { | 558 if (!reference_table || !(face = hb_object_create<hb_face_t> ())) { |
| 317 if (destroy) | 559 if (destroy) |
| 318 destroy (user_data); | 560 destroy (user_data); |
| 319 return &_hb_face_nil; | 561 return &_hb_face_nil; |
| 320 } | 562 } |
| 321 | 563 |
| 322 face->get_table = get_table; | 564 face->reference_table = reference_table; |
| 565 face->user_data = user_data; |
| 323 face->destroy = destroy; | 566 face->destroy = destroy; |
| 324 face->user_data = user_data; | |
| 325 | 567 |
| 326 face->ot_layout = _hb_ot_layout_new (face); | 568 face->ot_layout = _hb_ot_layout_create (face); |
| 327 | 569 |
| 328 face->head_blob = Sanitizer<head>::sanitize (hb_face_get_table (face, HB_OT_TA
G_head)); | 570 face->upem = 0; |
| 329 face->head_table = Sanitizer<head>::lock_instance (face->head_blob); | |
| 330 | 571 |
| 331 return face; | 572 return face; |
| 332 } | 573 } |
| 333 | 574 |
| 334 | 575 |
| 335 typedef struct _hb_face_for_data_closure_t { | 576 typedef struct _hb_face_for_data_closure_t { |
| 336 hb_blob_t *blob; | 577 hb_blob_t *blob; |
| 337 unsigned int index; | 578 unsigned int index; |
| 338 } hb_face_for_data_closure_t; | 579 } hb_face_for_data_closure_t; |
| 339 | 580 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 353 } | 594 } |
| 354 | 595 |
| 355 static void | 596 static void |
| 356 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) | 597 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) |
| 357 { | 598 { |
| 358 hb_blob_destroy (closure->blob); | 599 hb_blob_destroy (closure->blob); |
| 359 free (closure); | 600 free (closure); |
| 360 } | 601 } |
| 361 | 602 |
| 362 static hb_blob_t * | 603 static hb_blob_t * |
| 363 _hb_face_for_data_get_table (hb_tag_t tag, void *user_data) | 604 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
*user_data) |
| 364 { | 605 { |
| 365 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; | 606 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; |
| 366 | 607 |
| 608 if (tag == HB_TAG_NONE) |
| 609 return hb_blob_reference (data->blob); |
| 610 |
| 367 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); | 611 const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance
(data->blob); |
| 368 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); | 612 const OpenTypeFontFace &ot_face = ot_file.get_face (data->index); |
| 369 | 613 |
| 370 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); | 614 const OpenTypeTable &table = ot_face.get_table_by_tag (tag); |
| 371 | 615 |
| 372 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); | 616 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.len
gth); |
| 373 | 617 |
| 374 hb_blob_unlock (data->blob); | |
| 375 | |
| 376 return blob; | 618 return blob; |
| 377 } | 619 } |
| 378 | 620 |
| 379 hb_face_t * | 621 hb_face_t * |
| 380 hb_face_create_for_data (hb_blob_t *blob, | 622 hb_face_create (hb_blob_t *blob, |
| 381 » » » unsigned int index) | 623 » » unsigned int index) |
| 382 { | 624 { |
| 625 hb_face_t *face; |
| 626 |
| 627 if (unlikely (!blob || !hb_blob_get_length (blob))) |
| 628 return &_hb_face_nil; |
| 629 |
| 383 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); | 630 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Saniti
zer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); |
| 384 | 631 |
| 385 if (unlikely (!closure)) | 632 if (unlikely (!closure)) |
| 386 return &_hb_face_nil; | 633 return &_hb_face_nil; |
| 387 | 634 |
| 388 return hb_face_create_for_tables (_hb_face_for_data_get_table, | 635 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, |
| 389 » » » » (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy, | 636 » » » » closure, |
| 390 » » » » closure); | 637 » » » » (hb_destroy_func_t) _hb_face_for_data_closur
e_destroy); |
| 638 |
| 639 hb_face_set_index (face, index); |
| 640 |
| 641 return face; |
| 642 } |
| 643 |
| 644 hb_face_t * |
| 645 hb_face_get_empty (void) |
| 646 { |
| 647 return &_hb_face_nil; |
| 391 } | 648 } |
| 392 | 649 |
| 393 | 650 |
| 394 hb_face_t * | 651 hb_face_t * |
| 395 hb_face_reference (hb_face_t *face) | 652 hb_face_reference (hb_face_t *face) |
| 396 { | 653 { |
| 397 HB_OBJECT_DO_REFERENCE (face); | 654 return hb_object_reference (face); |
| 398 } | |
| 399 | |
| 400 unsigned int | |
| 401 hb_face_get_reference_count (hb_face_t *face) | |
| 402 { | |
| 403 HB_OBJECT_DO_GET_REFERENCE_COUNT (face); | |
| 404 } | 655 } |
| 405 | 656 |
| 406 void | 657 void |
| 407 hb_face_destroy (hb_face_t *face) | 658 hb_face_destroy (hb_face_t *face) |
| 408 { | 659 { |
| 409 HB_OBJECT_DO_DESTROY (face); | 660 if (!hb_object_destroy (face)) return; |
| 410 | 661 |
| 411 _hb_ot_layout_free (face->ot_layout); | 662 _hb_ot_layout_destroy (face->ot_layout); |
| 412 | |
| 413 hb_blob_unlock (face->head_blob); | |
| 414 hb_blob_destroy (face->head_blob); | |
| 415 | 663 |
| 416 if (face->destroy) | 664 if (face->destroy) |
| 417 face->destroy (face->user_data); | 665 face->destroy (face->user_data); |
| 418 | 666 |
| 419 free (face); | 667 free (face); |
| 420 } | 668 } |
| 421 | 669 |
| 670 hb_bool_t |
| 671 hb_face_set_user_data (hb_face_t *face, |
| 672 hb_user_data_key_t *key, |
| 673 void * data, |
| 674 hb_destroy_func_t destroy, |
| 675 hb_bool_t replace) |
| 676 { |
| 677 return hb_object_set_user_data (face, key, data, destroy, replace); |
| 678 } |
| 679 |
| 680 void * |
| 681 hb_face_get_user_data (hb_face_t *face, |
| 682 hb_user_data_key_t *key) |
| 683 { |
| 684 return hb_object_get_user_data (face, key); |
| 685 } |
| 686 |
| 687 void |
| 688 hb_face_make_immutable (hb_face_t *face) |
| 689 { |
| 690 if (hb_object_is_inert (face)) |
| 691 return; |
| 692 |
| 693 face->immutable = true; |
| 694 } |
| 695 |
| 696 hb_bool_t |
| 697 hb_face_is_immutable (hb_face_t *face) |
| 698 { |
| 699 return face->immutable; |
| 700 } |
| 701 |
| 702 |
| 422 hb_blob_t * | 703 hb_blob_t * |
| 423 hb_face_get_table (hb_face_t *face, | 704 hb_face_reference_table (hb_face_t *face, |
| 424 » » hb_tag_t tag) | 705 » » » hb_tag_t tag) |
| 425 { | 706 { |
| 426 hb_blob_t *blob; | 707 hb_blob_t *blob; |
| 427 | 708 |
| 428 if (unlikely (!face || !face->get_table)) | 709 if (unlikely (!face || !face->reference_table)) |
| 429 return &_hb_blob_nil; | 710 return hb_blob_get_empty (); |
| 430 | 711 |
| 431 blob = face->get_table (tag, face->user_data); | 712 blob = face->reference_table (face, tag, face->user_data); |
| 713 if (unlikely (!blob)) |
| 714 return hb_blob_get_empty (); |
| 432 | 715 |
| 433 return blob; | 716 return blob; |
| 434 } | 717 } |
| 435 | 718 |
| 719 hb_blob_t * |
| 720 hb_face_reference_blob (hb_face_t *face) |
| 721 { |
| 722 return hb_face_reference_table (face, HB_TAG_NONE); |
| 723 } |
| 724 |
| 725 void |
| 726 hb_face_set_index (hb_face_t *face, |
| 727 unsigned int index) |
| 728 { |
| 729 if (hb_object_is_inert (face)) |
| 730 return; |
| 731 |
| 732 face->index = 0; |
| 733 } |
| 734 |
| 735 unsigned int |
| 736 hb_face_get_index (hb_face_t *face) |
| 737 { |
| 738 return face->index; |
| 739 } |
| 740 |
| 741 void |
| 742 hb_face_set_upem (hb_face_t *face, |
| 743 unsigned int upem) |
| 744 { |
| 745 if (hb_object_is_inert (face)) |
| 746 return; |
| 747 |
| 748 face->upem = upem; |
| 749 } |
| 750 |
| 436 unsigned int | 751 unsigned int |
| 437 hb_face_get_upem (hb_face_t *face) | 752 hb_face_get_upem (hb_face_t *face) |
| 438 { | 753 { |
| 439 return (face->head_table ? face->head_table : &Null(head))->get_upem (); | 754 if (unlikely (!face->upem)) { |
| 755 hb_blob_t *head_blob = Sanitizer<head>::sanitize (hb_face_reference_table (f
ace, HB_OT_TAG_head)); |
| 756 const head *head_table = Sanitizer<head>::lock_instance (head_blob); |
| 757 face->upem = head_table->get_upem (); |
| 758 hb_blob_destroy (head_blob); |
| 759 } |
| 760 return face->upem; |
| 440 } | 761 } |
| 441 | 762 |
| 442 | 763 |
| 443 /* | 764 /* |
| 444 * hb_font_t | 765 * hb_font_t |
| 445 */ | 766 */ |
| 446 | 767 |
| 447 static hb_font_t _hb_font_nil = { | 768 static hb_font_t _hb_font_nil = { |
| 448 HB_REFERENCE_COUNT_INVALID, /* ref_count */ | 769 HB_OBJECT_HEADER_STATIC, |
| 770 |
| 771 TRUE, /* immutable */ |
| 772 |
| 773 NULL, /* parent */ |
| 774 &_hb_face_nil, |
| 449 | 775 |
| 450 0, /* x_scale */ | 776 0, /* x_scale */ |
| 451 0, /* y_scale */ | 777 0, /* y_scale */ |
| 452 | 778 |
| 453 0, /* x_ppem */ | 779 0, /* x_ppem */ |
| 454 0, /* y_ppem */ | 780 0, /* y_ppem */ |
| 455 | 781 |
| 456 NULL, /* klass */ | 782 &_hb_font_funcs_nil, /* klass */ |
| 457 NULL, /* destroy */ | 783 NULL, /* user_data */ |
| 458 NULL /* user_data */ | 784 NULL /* destroy */ |
| 459 }; | 785 }; |
| 460 | 786 |
| 461 hb_font_t * | 787 hb_font_t * |
| 462 hb_font_create (void) | 788 hb_font_create (hb_face_t *face) |
| 463 { | 789 { |
| 464 hb_font_t *font; | 790 hb_font_t *font; |
| 465 | 791 |
| 466 if (!HB_OBJECT_DO_CREATE (hb_font_t, font)) | 792 if (unlikely (!face)) |
| 793 face = &_hb_face_nil; |
| 794 if (unlikely (hb_object_is_inert (face))) |
| 467 return &_hb_font_nil; | 795 return &_hb_font_nil; |
| 796 if (!(font = hb_object_create<hb_font_t> ())) |
| 797 return &_hb_font_nil; |
| 798 |
| 799 hb_face_make_immutable (face); |
| 800 font->face = hb_face_reference (face); |
| 801 font->klass = &_hb_font_funcs_nil; |
| 802 |
| 803 return font; |
| 804 } |
| 805 |
| 806 hb_font_t * |
| 807 hb_font_create_sub_font (hb_font_t *parent) |
| 808 { |
| 809 if (unlikely (!parent)) |
| 810 return &_hb_font_nil; |
| 811 |
| 812 hb_font_t *font = hb_font_create (parent->face); |
| 813 |
| 814 if (unlikely (hb_object_is_inert (font))) |
| 815 return font; |
| 816 |
| 817 hb_font_make_immutable (parent); |
| 818 font->parent = hb_font_reference (parent); |
| 819 |
| 820 font->x_scale = parent->x_scale; |
| 821 font->y_scale = parent->y_scale; |
| 822 font->x_ppem = parent->x_ppem; |
| 823 font->y_ppem = parent->y_ppem; |
| 468 | 824 |
| 469 font->klass = &_hb_font_funcs_nil; | 825 font->klass = &_hb_font_funcs_nil; |
| 470 | 826 |
| 471 return font; | 827 return font; |
| 472 } | 828 } |
| 473 | 829 |
| 474 hb_font_t * | 830 hb_font_t * |
| 831 hb_font_get_empty (void) |
| 832 { |
| 833 return &_hb_font_nil; |
| 834 } |
| 835 |
| 836 hb_font_t * |
| 475 hb_font_reference (hb_font_t *font) | 837 hb_font_reference (hb_font_t *font) |
| 476 { | 838 { |
| 477 HB_OBJECT_DO_REFERENCE (font); | 839 return hb_object_reference (font); |
| 478 } | |
| 479 | |
| 480 unsigned int | |
| 481 hb_font_get_reference_count (hb_font_t *font) | |
| 482 { | |
| 483 HB_OBJECT_DO_GET_REFERENCE_COUNT (font); | |
| 484 } | 840 } |
| 485 | 841 |
| 486 void | 842 void |
| 487 hb_font_destroy (hb_font_t *font) | 843 hb_font_destroy (hb_font_t *font) |
| 488 { | 844 { |
| 489 HB_OBJECT_DO_DESTROY (font); | 845 if (!hb_object_destroy (font)) return; |
| 490 | 846 |
| 847 hb_font_destroy (font->parent); |
| 848 hb_face_destroy (font->face); |
| 491 hb_font_funcs_destroy (font->klass); | 849 hb_font_funcs_destroy (font->klass); |
| 492 if (font->destroy) | 850 if (font->destroy) |
| 493 font->destroy (font->user_data); | 851 font->destroy (font->user_data); |
| 494 | 852 |
| 495 free (font); | 853 free (font); |
| 496 } | 854 } |
| 497 | 855 |
| 856 hb_bool_t |
| 857 hb_font_set_user_data (hb_font_t *font, |
| 858 hb_user_data_key_t *key, |
| 859 void * data, |
| 860 hb_destroy_func_t destroy, |
| 861 hb_bool_t replace) |
| 862 { |
| 863 return hb_object_set_user_data (font, key, data, destroy, replace); |
| 864 } |
| 865 |
| 866 void * |
| 867 hb_font_get_user_data (hb_font_t *font, |
| 868 hb_user_data_key_t *key) |
| 869 { |
| 870 return hb_object_get_user_data (font, key); |
| 871 } |
| 872 |
| 873 void |
| 874 hb_font_make_immutable (hb_font_t *font) |
| 875 { |
| 876 if (hb_object_is_inert (font)) |
| 877 return; |
| 878 |
| 879 font->immutable = true; |
| 880 } |
| 881 |
| 882 hb_bool_t |
| 883 hb_font_is_immutable (hb_font_t *font) |
| 884 { |
| 885 return font->immutable; |
| 886 } |
| 887 |
| 888 hb_font_t * |
| 889 hb_font_get_parent (hb_font_t *font) |
| 890 { |
| 891 return font->parent; |
| 892 } |
| 893 |
| 894 hb_face_t * |
| 895 hb_font_get_face (hb_font_t *font) |
| 896 { |
| 897 return font->face; |
| 898 } |
| 899 |
| 900 |
| 498 void | 901 void |
| 499 hb_font_set_funcs (hb_font_t *font, | 902 hb_font_set_funcs (hb_font_t *font, |
| 500 hb_font_funcs_t *klass, | 903 hb_font_funcs_t *klass, |
| 501 » » hb_destroy_func_t destroy, | 904 » » void *user_data, |
| 502 » » void *user_data) | 905 » » hb_destroy_func_t destroy) |
| 503 { | 906 { |
| 504 if (HB_OBJECT_IS_INERT (font)) | 907 if (font->immutable) { |
| 908 if (destroy) |
| 909 destroy (user_data); |
| 505 return; | 910 return; |
| 911 } |
| 506 | 912 |
| 507 if (font->destroy) | 913 if (font->destroy) |
| 508 font->destroy (font->user_data); | 914 font->destroy (font->user_data); |
| 509 | 915 |
| 510 if (!klass) | 916 if (!klass) |
| 511 klass = &_hb_font_funcs_nil; | 917 klass = &_hb_font_funcs_nil; |
| 512 | 918 |
| 513 hb_font_funcs_reference (klass); | 919 hb_font_funcs_reference (klass); |
| 514 hb_font_funcs_destroy (font->klass); | 920 hb_font_funcs_destroy (font->klass); |
| 515 font->klass = klass; | 921 font->klass = klass; |
| 922 font->user_data = user_data; |
| 516 font->destroy = destroy; | 923 font->destroy = destroy; |
| 517 font->user_data = user_data; | |
| 518 } | 924 } |
| 519 | 925 |
| 520 void | 926 void |
| 521 hb_font_unset_funcs (hb_font_t *font, | 927 hb_font_set_funcs_data (hb_font_t *font, |
| 522 » » hb_font_funcs_t **klass, | 928 » » void *user_data, |
| 523 » » hb_destroy_func_t *destroy, | 929 » » hb_destroy_func_t destroy) |
| 524 » » void **user_data) | |
| 525 { | 930 { |
| 526 /* None of the input arguments can be NULL. */ | 931 /* Destroy user_data? */ |
| 932 if (font->immutable) { |
| 933 if (destroy) |
| 934 destroy (user_data); |
| 935 return; |
| 936 } |
| 527 | 937 |
| 528 *klass = font->klass; | 938 if (font->destroy) |
| 529 *destroy = font->destroy; | 939 font->destroy (font->user_data); |
| 530 *user_data = font->user_data; | |
| 531 | 940 |
| 532 if (HB_OBJECT_IS_INERT (font)) | 941 font->user_data = user_data; |
| 533 return; | 942 font->destroy = destroy; |
| 943 } |
| 534 | 944 |
| 535 font->klass = NULL; | |
| 536 font->destroy = NULL; | |
| 537 font->user_data = NULL; | |
| 538 } | |
| 539 | 945 |
| 540 void | 946 void |
| 541 hb_font_set_scale (hb_font_t *font, | 947 hb_font_set_scale (hb_font_t *font, |
| 542 » » unsigned int x_scale, | 948 » » int x_scale, |
| 543 » » unsigned int y_scale) | 949 » » int y_scale) |
| 544 { | 950 { |
| 545 if (HB_OBJECT_IS_INERT (font)) | 951 if (font->immutable) |
| 546 return; | 952 return; |
| 547 | 953 |
| 548 font->x_scale = x_scale; | 954 font->x_scale = x_scale; |
| 549 font->y_scale = y_scale; | 955 font->y_scale = y_scale; |
| 550 } | 956 } |
| 551 | 957 |
| 552 void | 958 void |
| 553 hb_font_get_scale (hb_font_t *font, | 959 hb_font_get_scale (hb_font_t *font, |
| 554 » » unsigned int *x_scale, | 960 » » int *x_scale, |
| 555 » » unsigned int *y_scale) | 961 » » int *y_scale) |
| 556 { | 962 { |
| 557 if (x_scale) *x_scale = font->x_scale; | 963 if (x_scale) *x_scale = font->x_scale; |
| 558 if (y_scale) *y_scale = font->y_scale; | 964 if (y_scale) *y_scale = font->y_scale; |
| 559 } | 965 } |
| 560 | 966 |
| 561 void | 967 void |
| 562 hb_font_set_ppem (hb_font_t *font, | 968 hb_font_set_ppem (hb_font_t *font, |
| 563 unsigned int x_ppem, | 969 unsigned int x_ppem, |
| 564 unsigned int y_ppem) | 970 unsigned int y_ppem) |
| 565 { | 971 { |
| 566 if (HB_OBJECT_IS_INERT (font)) | 972 if (font->immutable) |
| 567 return; | 973 return; |
| 568 | 974 |
| 569 font->x_ppem = x_ppem; | 975 font->x_ppem = x_ppem; |
| 570 font->y_ppem = y_ppem; | 976 font->y_ppem = y_ppem; |
| 571 } | 977 } |
| 572 | 978 |
| 573 void | 979 void |
| 574 hb_font_get_ppem (hb_font_t *font, | 980 hb_font_get_ppem (hb_font_t *font, |
| 575 unsigned int *x_ppem, | 981 unsigned int *x_ppem, |
| 576 unsigned int *y_ppem) | 982 unsigned int *y_ppem) |
| 577 { | 983 { |
| 578 if (x_ppem) *x_ppem = font->x_ppem; | 984 if (x_ppem) *x_ppem = font->x_ppem; |
| 579 if (y_ppem) *y_ppem = font->y_ppem; | 985 if (y_ppem) *y_ppem = font->y_ppem; |
| 580 } | 986 } |
| 581 | 987 |
| 582 | 988 |
| 583 HB_END_DECLS | |
| OLD | NEW |