michael@0: /* michael@0: * Copyright © 2009 Red Hat, Inc. michael@0: * Copyright © 2012 Google, Inc. michael@0: * michael@0: * This is part of HarfBuzz, a text shaping library. michael@0: * michael@0: * Permission is hereby granted, without written agreement and without michael@0: * license or royalty fees, to use, copy, modify, and distribute this michael@0: * software and its documentation for any purpose, provided that the michael@0: * above copyright notice and the following two paragraphs appear in michael@0: * all copies of this software. michael@0: * michael@0: * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR michael@0: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES michael@0: * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN michael@0: * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH michael@0: * DAMAGE. michael@0: * michael@0: * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, michael@0: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND michael@0: * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS michael@0: * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO michael@0: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. michael@0: * michael@0: * Red Hat Author(s): Behdad Esfahbod michael@0: * Google Author(s): Behdad Esfahbod michael@0: */ michael@0: michael@0: #include "hb-private.hh" michael@0: michael@0: #include "hb-ot-layout-private.hh" michael@0: michael@0: #include "hb-font-private.hh" michael@0: #include "hb-open-file-private.hh" michael@0: #include "hb-ot-head-table.hh" michael@0: #include "hb-ot-maxp-table.hh" michael@0: michael@0: #include "hb-cache-private.hh" michael@0: michael@0: #include michael@0: michael@0: michael@0: /* michael@0: * hb_font_funcs_t michael@0: */ michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t unicode, michael@0: hb_codepoint_t variation_selector, michael@0: hb_codepoint_t *glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent->get_glyph (unicode, variation_selector, glyph); michael@0: michael@0: *glyph = 0; michael@0: return false; michael@0: } michael@0: michael@0: static hb_position_t michael@0: hb_font_get_glyph_h_advance_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); michael@0: michael@0: return font->x_scale; michael@0: } michael@0: michael@0: static hb_position_t michael@0: hb_font_get_glyph_v_advance_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); michael@0: michael@0: return font->y_scale; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_h_origin_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: hb_position_t *x, michael@0: hb_position_t *y, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) { michael@0: hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); michael@0: if (ret) michael@0: font->parent_scale_position (x, y); michael@0: return ret; michael@0: } michael@0: michael@0: *x = *y = 0; michael@0: return false; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_v_origin_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: hb_position_t *x, michael@0: hb_position_t *y, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) { michael@0: hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); michael@0: if (ret) michael@0: font->parent_scale_position (x, y); michael@0: return ret; michael@0: } michael@0: michael@0: *x = *y = 0; michael@0: return false; michael@0: } michael@0: michael@0: static hb_position_t michael@0: hb_font_get_glyph_h_kerning_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t left_glyph, michael@0: hb_codepoint_t right_glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static hb_position_t michael@0: hb_font_get_glyph_v_kerning_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t top_glyph, michael@0: hb_codepoint_t bottom_glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_extents_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: hb_glyph_extents_t *extents, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) { michael@0: hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); michael@0: if (ret) { michael@0: font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); michael@0: font->parent_scale_distance (&extents->width, &extents->height); michael@0: } michael@0: return ret; michael@0: } michael@0: michael@0: memset (extents, 0, sizeof (*extents)); michael@0: return false; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_contour_point_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: unsigned int point_index, michael@0: hb_position_t *x, michael@0: hb_position_t *y, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) { michael@0: hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); michael@0: if (ret) michael@0: font->parent_scale_position (x, y); michael@0: return ret; michael@0: } michael@0: michael@0: *x = *y = 0; michael@0: return false; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_name_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: hb_codepoint_t glyph, michael@0: char *name, unsigned int size, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent->get_glyph_name (glyph, name, size); michael@0: michael@0: if (size) *name = '\0'; michael@0: return false; michael@0: } michael@0: michael@0: static hb_bool_t michael@0: hb_font_get_glyph_from_name_nil (hb_font_t *font, michael@0: void *font_data HB_UNUSED, michael@0: const char *name, int len, /* -1 means nul-terminated */ michael@0: hb_codepoint_t *glyph, michael@0: void *user_data HB_UNUSED) michael@0: { michael@0: if (font->parent) michael@0: return font->parent->get_glyph_from_name (name, len, glyph); michael@0: michael@0: *glyph = 0; michael@0: return false; michael@0: } michael@0: michael@0: michael@0: static const hb_font_funcs_t _hb_font_funcs_nil = { michael@0: HB_OBJECT_HEADER_STATIC, michael@0: michael@0: true, /* immutable */ michael@0: michael@0: { michael@0: #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, michael@0: HB_FONT_FUNCS_IMPLEMENT_CALLBACKS michael@0: #undef HB_FONT_FUNC_IMPLEMENT michael@0: } michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * hb_font_funcs_create: (Xconstructor) michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_funcs_t * michael@0: hb_font_funcs_create (void) michael@0: { michael@0: hb_font_funcs_t *ffuncs; michael@0: michael@0: if (!(ffuncs = hb_object_create ())) michael@0: return hb_font_funcs_get_empty (); michael@0: michael@0: ffuncs->get = _hb_font_funcs_nil.get; michael@0: michael@0: return ffuncs; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_get_empty: michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_funcs_t * michael@0: hb_font_funcs_get_empty (void) michael@0: { michael@0: return const_cast (&_hb_font_funcs_nil); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_reference: (skip) michael@0: * @ffuncs: font functions. michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_funcs_t * michael@0: hb_font_funcs_reference (hb_font_funcs_t *ffuncs) michael@0: { michael@0: return hb_object_reference (ffuncs); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_destroy: (skip) michael@0: * @ffuncs: font functions. michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) michael@0: { michael@0: if (!hb_object_destroy (ffuncs)) return; michael@0: michael@0: #define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) \ michael@0: ffuncs->destroy.name (ffuncs->user_data.name); michael@0: HB_FONT_FUNCS_IMPLEMENT_CALLBACKS michael@0: #undef HB_FONT_FUNC_IMPLEMENT michael@0: michael@0: free (ffuncs); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_set_user_data: (skip) michael@0: * @ffuncs: font functions. michael@0: * @key: michael@0: * @data: michael@0: * @destroy: michael@0: * @replace: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, michael@0: hb_user_data_key_t *key, michael@0: void * data, michael@0: hb_destroy_func_t destroy, michael@0: hb_bool_t replace) michael@0: { michael@0: return hb_object_set_user_data (ffuncs, key, data, destroy, replace); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_get_user_data: (skip) michael@0: * @ffuncs: font functions. michael@0: * @key: michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer none): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void * michael@0: hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, michael@0: hb_user_data_key_t *key) michael@0: { michael@0: return hb_object_get_user_data (ffuncs, key); michael@0: } michael@0: michael@0: michael@0: /** michael@0: * hb_font_funcs_make_immutable: michael@0: * @ffuncs: font functions. michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) michael@0: { michael@0: if (hb_object_is_inert (ffuncs)) michael@0: return; michael@0: michael@0: ffuncs->immutable = true; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_funcs_is_immutable: michael@0: * @ffuncs: font functions. michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) michael@0: { michael@0: return ffuncs->immutable; michael@0: } michael@0: michael@0: michael@0: #define HB_FONT_FUNC_IMPLEMENT(name) \ michael@0: \ michael@0: void \ michael@0: hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ michael@0: hb_font_get_##name##_func_t func, \ michael@0: void *user_data, \ michael@0: hb_destroy_func_t destroy) \ michael@0: { \ michael@0: if (ffuncs->immutable) { \ michael@0: if (destroy) \ michael@0: destroy (user_data); \ michael@0: return; \ michael@0: } \ michael@0: \ michael@0: if (ffuncs->destroy.name) \ michael@0: ffuncs->destroy.name (ffuncs->user_data.name); \ michael@0: \ michael@0: if (func) { \ michael@0: ffuncs->get.name = func; \ michael@0: ffuncs->user_data.name = user_data; \ michael@0: ffuncs->destroy.name = destroy; \ michael@0: } else { \ michael@0: ffuncs->get.name = hb_font_get_##name##_nil; \ michael@0: ffuncs->user_data.name = NULL; \ michael@0: ffuncs->destroy.name = NULL; \ michael@0: } \ michael@0: } michael@0: michael@0: HB_FONT_FUNCS_IMPLEMENT_CALLBACKS michael@0: #undef HB_FONT_FUNC_IMPLEMENT michael@0: michael@0: michael@0: /* Public getters */ michael@0: michael@0: /** michael@0: * hb_font_get_glyph: michael@0: * @font: a font. michael@0: * @unicode: michael@0: * @variation_selector: michael@0: * @glyph: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph (hb_font_t *font, michael@0: hb_codepoint_t unicode, hb_codepoint_t variation_selector, michael@0: hb_codepoint_t *glyph) michael@0: { michael@0: return font->get_glyph (unicode, variation_selector, glyph); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_h_advance: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_position_t michael@0: hb_font_get_glyph_h_advance (hb_font_t *font, michael@0: hb_codepoint_t glyph) michael@0: { michael@0: return font->get_glyph_h_advance (glyph); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_v_advance: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_position_t michael@0: hb_font_get_glyph_v_advance (hb_font_t *font, michael@0: hb_codepoint_t glyph) michael@0: { michael@0: return font->get_glyph_v_advance (glyph); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_h_origin: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_h_origin (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_h_origin (glyph, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_v_origin: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_v_origin (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_v_origin (glyph, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_h_kerning: michael@0: * @font: a font. michael@0: * @left_glyph: michael@0: * @right_glyph: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_position_t michael@0: hb_font_get_glyph_h_kerning (hb_font_t *font, michael@0: hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) michael@0: { michael@0: return font->get_glyph_h_kerning (left_glyph, right_glyph); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_v_kerning: michael@0: * @font: a font. michael@0: * @top_glyph: michael@0: * @bottom_glyph: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_position_t michael@0: hb_font_get_glyph_v_kerning (hb_font_t *font, michael@0: hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) michael@0: { michael@0: return font->get_glyph_v_kerning (top_glyph, bottom_glyph); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_extents: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @extents: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_extents (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_glyph_extents_t *extents) michael@0: { michael@0: return font->get_glyph_extents (glyph, extents); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_contour_point: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @point_index: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_contour_point (hb_font_t *font, michael@0: hb_codepoint_t glyph, unsigned int point_index, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_contour_point (glyph, point_index, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_name: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @name: (array length=size): michael@0: * @size: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_name (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: char *name, unsigned int size) michael@0: { michael@0: return font->get_glyph_name (glyph, name, size); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_from_name: michael@0: * @font: a font. michael@0: * @name: (array length=len): michael@0: * @len: michael@0: * @glyph: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_from_name (hb_font_t *font, michael@0: const char *name, int len, /* -1 means nul-terminated */ michael@0: hb_codepoint_t *glyph) michael@0: { michael@0: return font->get_glyph_from_name (name, len, glyph); michael@0: } michael@0: michael@0: michael@0: /* A bit higher-level, and with fallback */ michael@0: michael@0: /** michael@0: * hb_font_get_glyph_advance_for_direction: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_get_glyph_advance_for_direction (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_advance_for_direction (glyph, direction, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_origin_for_direction: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_get_glyph_origin_for_direction (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_origin_for_direction (glyph, direction, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_add_glyph_origin_for_direction: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_add_glyph_origin_for_direction (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->add_glyph_origin_for_direction (glyph, direction, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_subtract_glyph_origin_for_direction: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->subtract_glyph_origin_for_direction (glyph, direction, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_kerning_for_direction: michael@0: * @font: a font. michael@0: * @first_glyph: michael@0: * @second_glyph: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_get_glyph_kerning_for_direction (hb_font_t *font, michael@0: hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_extents_for_origin: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @direction: michael@0: * @extents: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_extents_for_origin (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: hb_direction_t direction, michael@0: hb_glyph_extents_t *extents) michael@0: { michael@0: return font->get_glyph_extents_for_origin (glyph, direction, extents); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_glyph_contour_point_for_origin: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @point_index: michael@0: * @direction: michael@0: * @x: (out): michael@0: * @y: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, michael@0: hb_codepoint_t glyph, unsigned int point_index, michael@0: hb_direction_t direction, michael@0: hb_position_t *x, hb_position_t *y) michael@0: { michael@0: return font->get_glyph_contour_point_for_origin (glyph, point_index, direction, x, y); michael@0: } michael@0: michael@0: /* Generates gidDDD if glyph has no name. */ michael@0: /** michael@0: * hb_font_glyph_to_string: michael@0: * @font: a font. michael@0: * @glyph: michael@0: * @s: (array length=size): michael@0: * @size: michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_glyph_to_string (hb_font_t *font, michael@0: hb_codepoint_t glyph, michael@0: char *s, unsigned int size) michael@0: { michael@0: font->glyph_to_string (glyph, s, size); michael@0: } michael@0: michael@0: /* Parses gidDDD and uniUUUU strings automatically. */ michael@0: /** michael@0: * hb_font_glyph_from_string: michael@0: * @font: a font. michael@0: * @s: (array length=len): michael@0: * @len: michael@0: * @glyph: (out): michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_glyph_from_string (hb_font_t *font, michael@0: const char *s, int len, /* -1 means nul-terminated */ michael@0: hb_codepoint_t *glyph) michael@0: { michael@0: return font->glyph_from_string (s, len, glyph); michael@0: } michael@0: michael@0: michael@0: /* michael@0: * hb_font_t michael@0: */ michael@0: michael@0: /** michael@0: * hb_font_create: (Xconstructor) michael@0: * @face: a face. michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_t * michael@0: hb_font_create (hb_face_t *face) michael@0: { michael@0: hb_font_t *font; michael@0: michael@0: if (unlikely (!face)) michael@0: face = hb_face_get_empty (); michael@0: if (unlikely (hb_object_is_inert (face))) michael@0: return hb_font_get_empty (); michael@0: if (!(font = hb_object_create ())) michael@0: return hb_font_get_empty (); michael@0: michael@0: hb_face_make_immutable (face); michael@0: font->face = hb_face_reference (face); michael@0: font->klass = hb_font_funcs_get_empty (); michael@0: michael@0: return font; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_create_sub_font: michael@0: * @parent: parent font. michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_t * michael@0: hb_font_create_sub_font (hb_font_t *parent) michael@0: { michael@0: if (unlikely (!parent)) michael@0: return hb_font_get_empty (); michael@0: michael@0: hb_font_t *font = hb_font_create (parent->face); michael@0: michael@0: if (unlikely (hb_object_is_inert (font))) michael@0: return font; michael@0: michael@0: hb_font_make_immutable (parent); michael@0: font->parent = hb_font_reference (parent); michael@0: michael@0: font->x_scale = parent->x_scale; michael@0: font->y_scale = parent->y_scale; michael@0: font->x_ppem = parent->x_ppem; michael@0: font->y_ppem = parent->y_ppem; michael@0: michael@0: return font; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_empty: michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full) michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_t * michael@0: hb_font_get_empty (void) michael@0: { michael@0: static const hb_font_t _hb_font_nil = { michael@0: HB_OBJECT_HEADER_STATIC, michael@0: michael@0: true, /* immutable */ michael@0: michael@0: NULL, /* parent */ michael@0: const_cast (&_hb_face_nil), michael@0: michael@0: 0, /* x_scale */ michael@0: 0, /* y_scale */ michael@0: michael@0: 0, /* x_ppem */ michael@0: 0, /* y_ppem */ michael@0: michael@0: const_cast (&_hb_font_funcs_nil), /* klass */ michael@0: NULL, /* user_data */ michael@0: NULL, /* destroy */ michael@0: michael@0: { michael@0: #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, michael@0: #include "hb-shaper-list.hh" michael@0: #undef HB_SHAPER_IMPLEMENT michael@0: } michael@0: }; michael@0: michael@0: return const_cast (&_hb_font_nil); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_reference: (skip) michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer full): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_t * michael@0: hb_font_reference (hb_font_t *font) michael@0: { michael@0: return hb_object_reference (font); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_destroy: (skip) michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_destroy (hb_font_t *font) michael@0: { michael@0: if (!hb_object_destroy (font)) return; michael@0: michael@0: #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font); michael@0: #include "hb-shaper-list.hh" michael@0: #undef HB_SHAPER_IMPLEMENT michael@0: michael@0: if (font->destroy) michael@0: font->destroy (font->user_data); michael@0: michael@0: hb_font_destroy (font->parent); michael@0: hb_face_destroy (font->face); michael@0: hb_font_funcs_destroy (font->klass); michael@0: michael@0: free (font); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_set_user_data: (skip) michael@0: * @font: a font. michael@0: * @key: michael@0: * @data: michael@0: * @destroy: michael@0: * @replace: michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_set_user_data (hb_font_t *font, michael@0: hb_user_data_key_t *key, michael@0: void * data, michael@0: hb_destroy_func_t destroy, michael@0: hb_bool_t replace) michael@0: { michael@0: return hb_object_set_user_data (font, key, data, destroy, replace); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_user_data: (skip) michael@0: * @font: a font. michael@0: * @key: michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer none): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void * michael@0: hb_font_get_user_data (hb_font_t *font, michael@0: hb_user_data_key_t *key) michael@0: { michael@0: return hb_object_get_user_data (font, key); michael@0: } michael@0: michael@0: /** michael@0: * hb_font_make_immutable: michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_make_immutable (hb_font_t *font) michael@0: { michael@0: if (hb_object_is_inert (font)) michael@0: return; michael@0: michael@0: font->immutable = true; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_is_immutable: michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Return value: michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_bool_t michael@0: hb_font_is_immutable (hb_font_t *font) michael@0: { michael@0: return font->immutable; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_parent: michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer none): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_font_t * michael@0: hb_font_get_parent (hb_font_t *font) michael@0: { michael@0: return font->parent; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_face: michael@0: * @font: a font. michael@0: * michael@0: * michael@0: * michael@0: * Return value: (transfer none): michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: hb_face_t * michael@0: hb_font_get_face (hb_font_t *font) michael@0: { michael@0: return font->face; michael@0: } michael@0: michael@0: michael@0: /** michael@0: * hb_font_set_funcs: michael@0: * @font: a font. michael@0: * @klass: (closure font_data) (destroy destroy) (scope notified): michael@0: * @font_data: michael@0: * @destroy: michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_set_funcs (hb_font_t *font, michael@0: hb_font_funcs_t *klass, michael@0: void *font_data, michael@0: hb_destroy_func_t destroy) michael@0: { michael@0: if (font->immutable) { michael@0: if (destroy) michael@0: destroy (font_data); michael@0: return; michael@0: } michael@0: michael@0: if (font->destroy) michael@0: font->destroy (font->user_data); michael@0: michael@0: if (!klass) michael@0: klass = hb_font_funcs_get_empty (); michael@0: michael@0: hb_font_funcs_reference (klass); michael@0: hb_font_funcs_destroy (font->klass); michael@0: font->klass = klass; michael@0: font->user_data = font_data; michael@0: font->destroy = destroy; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_set_funcs_data: michael@0: * @font: a font. michael@0: * @font_data: (destroy destroy) (scope notified): michael@0: * @destroy: michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_set_funcs_data (hb_font_t *font, michael@0: void *font_data, michael@0: hb_destroy_func_t destroy) michael@0: { michael@0: /* Destroy user_data? */ michael@0: if (font->immutable) { michael@0: if (destroy) michael@0: destroy (font_data); michael@0: return; michael@0: } michael@0: michael@0: if (font->destroy) michael@0: font->destroy (font->user_data); michael@0: michael@0: font->user_data = font_data; michael@0: font->destroy = destroy; michael@0: } michael@0: michael@0: michael@0: /** michael@0: * hb_font_set_scale: michael@0: * @font: a font. michael@0: * @x_scale: michael@0: * @y_scale: michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_set_scale (hb_font_t *font, michael@0: int x_scale, michael@0: int y_scale) michael@0: { michael@0: if (font->immutable) michael@0: return; michael@0: michael@0: font->x_scale = x_scale; michael@0: font->y_scale = y_scale; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_scale: michael@0: * @font: a font. michael@0: * @x_scale: (out): michael@0: * @y_scale: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_get_scale (hb_font_t *font, michael@0: int *x_scale, michael@0: int *y_scale) michael@0: { michael@0: if (x_scale) *x_scale = font->x_scale; michael@0: if (y_scale) *y_scale = font->y_scale; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_set_ppem: michael@0: * @font: a font. michael@0: * @x_ppem: michael@0: * @y_ppem: michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_set_ppem (hb_font_t *font, michael@0: unsigned int x_ppem, michael@0: unsigned int y_ppem) michael@0: { michael@0: if (font->immutable) michael@0: return; michael@0: michael@0: font->x_ppem = x_ppem; michael@0: font->y_ppem = y_ppem; michael@0: } michael@0: michael@0: /** michael@0: * hb_font_get_ppem: michael@0: * @font: a font. michael@0: * @x_ppem: (out): michael@0: * @y_ppem: (out): michael@0: * michael@0: * michael@0: * michael@0: * Since: 1.0 michael@0: **/ michael@0: void michael@0: hb_font_get_ppem (hb_font_t *font, michael@0: unsigned int *x_ppem, michael@0: unsigned int *y_ppem) michael@0: { michael@0: if (x_ppem) *x_ppem = font->x_ppem; michael@0: if (y_ppem) *y_ppem = font->y_ppem; michael@0: }