1c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2009  Red Hat, Inc.
32409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2011  Google, Inc.
4c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod *
5c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
6c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod *
7c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * Permission is hereby granted, without written agreement and without
8c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
9c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * software and its documentation for any purpose, provided that the
10c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * above copyright notice and the following two paragraphs appear in
11c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * all copies of this software.
12c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod *
13c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * DAMAGE.
18c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod *
19c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod *
25c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
262409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Google Author(s): Behdad Esfahbod
27c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod */
28c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
29c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#ifndef HB_FONT_PRIVATE_HH
30c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#define HB_FONT_PRIVATE_HH
31c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
32c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#include "hb-private.hh"
33c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
34fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod#include "hb-object-private.hh"
352e3a07abdf97b0ad2105c3a52f3ff0e0b60b29c4Behdad Esfahbod#include "hb-face-private.hh"
36027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#include "hb-shaper-private.hh"
37c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
38c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
39acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
40c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod/*
415c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * hb_font_funcs_t
42c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod */
43c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
44744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
456f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
466f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
478b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
488b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
49744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
50744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
517e2c85de305be59e1a6afa7d2061e4b7dd00acf7Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
52744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
537e2c85de305be59e1a6afa7d2061e4b7dd00acf7Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
547e2c85de305be59e1a6afa7d2061e4b7dd00acf7Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
55744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
564b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
57bce095524b3e69a47f8e88a2fb02d6ab537f9b0aBehdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_name) \
58bce095524b3e69a47f8e88a2fb02d6ab537f9b0aBehdad Esfahbod  HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \
594b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  /* ^--- Add new callbacks here */
60744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod
611bc1cb3603167f5da309336f7018c8b0608ac104Behdad Esfahbodstruct hb_font_funcs_t {
624b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  hb_object_header_t header;
636220e5fc0dad728e67a92e838d3ac275d032f2c7Behdad Esfahbod  ASSERT_POD ();
644b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod
654b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  hb_bool_t immutable;
664b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod
67b9d975b931d6310f25fab5ac280f523cdc27bf94Behdad Esfahbod  struct {
68744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
69744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
70744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod#undef HB_FONT_FUNC_IMPLEMENT
71b9d975b931d6310f25fab5ac280f523cdc27bf94Behdad Esfahbod  } user_data;
72b9d975b931d6310f25fab5ac280f523cdc27bf94Behdad Esfahbod
73bf36a1074ab23abeab0a7a6c47db26770dc1ab0aBehdad Esfahbod  struct {
74744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
75744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod    HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
76744970af4d884cc87ffa645804578fec8df674a9Behdad Esfahbod#undef HB_FONT_FUNC_IMPLEMENT
77b9d975b931d6310f25fab5ac280f523cdc27bf94Behdad Esfahbod  } destroy;
7828de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod
7928de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod  /* Don't access these directly.  Call font->get_*() instead. */
8028de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod  union get_t {
8128de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod    struct get_funcs_t {
8228de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
8328de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod      HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
8428de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod#undef HB_FONT_FUNC_IMPLEMENT
8528de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod    } f;
86a13b023dbfd0532e8cd74c356fbbd4453d0ffaa0Steven R. Loomis    void (*array[VAR]) (void);
8728de104f15b80df4b678267c4488b7d09a42720cBehdad Esfahbod  } get;
88c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod};
89c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
90c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
91c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
92c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod/*
93c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod * hb_font_t
94c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod */
95c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
961bc1cb3603167f5da309336f7018c8b0608ac104Behdad Esfahbodstruct hb_font_t {
97fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod  hb_object_header_t header;
986220e5fc0dad728e67a92e838d3ac275d032f2c7Behdad Esfahbod  ASSERT_POD ();
99c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
10074f1d896f2479500d65649cf3ec86dd201f0663aBehdad Esfahbod  hb_bool_t immutable;
10174f1d896f2479500d65649cf3ec86dd201f0663aBehdad Esfahbod
102defc45be6d75aba4a67fa7814b91b73bad953fe6Behdad Esfahbod  hb_font_t *parent;
10372657e4ce757dcb055a8db7291b68f96f0d34bfbBehdad Esfahbod  hb_face_t *face;
10472657e4ce757dcb055a8db7291b68f96f0d34bfbBehdad Esfahbod
10511bb8fe7b3925bc9b019ad0c0218a231e581f152Behdad Esfahbod  int x_scale;
10611bb8fe7b3925bc9b019ad0c0218a231e581f152Behdad Esfahbod  int y_scale;
107c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
108c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod  unsigned int x_ppem;
109c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod  unsigned int y_ppem;
1105c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1118fb3d1aa4e613cdf965a83bd650c668884c58ad8Behdad Esfahbod  hb_font_funcs_t   *klass;
1128fb3d1aa4e613cdf965a83bd650c668884c58ad8Behdad Esfahbod  void              *user_data;
1135668189c12c264e8d2caf0d12dac918363ef6f80Behdad Esfahbod  hb_destroy_func_t  destroy;
114abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod
115027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod  struct hb_shaper_data_t shaper_data;
116027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod
117abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod
118abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  /* Convert from font-space to user-space */
119b6f902a1a9c8b72b5d6a241a14a7bacfaea3a56aBehdad Esfahbod  inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
120b6f902a1a9c8b72b5d6a241a14a7bacfaea3a56aBehdad Esfahbod  inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); }
121abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod
12263d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  /* Convert from parent-font user-space to our user-space */
12363d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline hb_position_t parent_scale_x_distance (hb_position_t v) {
12463d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    if (unlikely (parent && parent->x_scale != x_scale))
12583408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod      return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
12663d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    return v;
12763d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
12863d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline hb_position_t parent_scale_y_distance (hb_position_t v) {
12963d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    if (unlikely (parent && parent->y_scale != y_scale))
13083408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod      return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
13163d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    return v;
13263d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
13363d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline hb_position_t parent_scale_x_position (hb_position_t v) {
13460fbb36096e344e9af79409ce8cfe3f1f7b0d321Behdad Esfahbod    return parent_scale_x_distance (v);
13563d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
13663d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline hb_position_t parent_scale_y_position (hb_position_t v) {
13760fbb36096e344e9af79409ce8cfe3f1f7b0d321Behdad Esfahbod    return parent_scale_y_distance (v);
13863d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
13963d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod
14063d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline void parent_scale_distance (hb_position_t *x, hb_position_t *y) {
14163d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    *x = parent_scale_x_distance (*x);
14263d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    *y = parent_scale_y_distance (*y);
14363d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
14463d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  inline void parent_scale_position (hb_position_t *x, hb_position_t *y) {
14563d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    *x = parent_scale_x_position (*x);
14663d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod    *y = parent_scale_y_position (*y);
14763d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod  }
14863d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod
14963d646fb2933c2765ce526d321a498d0f7fae2f5Behdad Esfahbod
1508fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  /* Public getters */
1518fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
152762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  HB_INTERNAL bool has_func (unsigned int i);
153762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod
154762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  /* has_* ... */
155762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod#define HB_FONT_FUNC_IMPLEMENT(name) \
156762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  bool \
157762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  has_##name##_func (void) \
158762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  { \
159762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod    hb_font_funcs_t *funcs = this->klass; \
160762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod    unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \
161762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod    return has_func (i); \
162762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  }
163762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod  HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
164762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod#undef HB_FONT_FUNC_IMPLEMENT
165762770c964f9f0591bf4c44427f73ea3e1c51733Behdad Esfahbod
1666f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents)
1676f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  {
1686f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    memset (extents, 0, sizeof (*extents));
1696f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    return klass->get.f.font_h_extents (this, user_data,
1706f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens					extents,
1716f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens					klass->user_data.font_h_extents);
1726f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  }
1736f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents)
1746f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  {
1756f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    memset (extents, 0, sizeof (*extents));
1766f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    return klass->get.f.font_v_extents (this, user_data,
1776f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens					extents,
1786f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens					klass->user_data.font_v_extents);
1796f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  }
1806f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens
181ea512f71084296be3bd893f78650def894066de0Behdad Esfahbod  inline bool has_glyph (hb_codepoint_t unicode)
1828de20b1e8a1c4d2081f64e695045e6e4da7ce144Behdad Esfahbod  {
1838de20b1e8a1c4d2081f64e695045e6e4da7ce144Behdad Esfahbod    hb_codepoint_t glyph;
1848b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod    return get_nominal_glyph (unicode, &glyph);
1858de20b1e8a1c4d2081f64e695045e6e4da7ce144Behdad Esfahbod  }
1868de20b1e8a1c4d2081f64e695045e6e4da7ce144Behdad Esfahbod
1878b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  inline hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
1888b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod				      hb_codepoint_t *glyph)
1898fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
1908fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *glyph = 0;
1918b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod    return klass->get.f.nominal_glyph (this, user_data,
1928b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod				       unicode, glyph,
1938b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod				       klass->user_data.nominal_glyph);
1948b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  }
1958b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod
1968b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
1978b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod					hb_codepoint_t *glyph)
1988b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod  {
1998b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod    *glyph = 0;
2008b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod    return klass->get.f.variation_glyph (this, user_data,
2018b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod					 unicode, variation_selector, glyph,
2028b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod					 klass->user_data.variation_glyph);
2038fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2048fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2058fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph)
2068fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
20788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_h_advance (this, user_data,
20888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 glyph,
20988e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 klass->user_data.glyph_h_advance);
2108fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2118fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2128fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph)
2138fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
21488e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_v_advance (this, user_data,
21588e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 glyph,
21688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 klass->user_data.glyph_v_advance);
2178fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2188fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2198fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
2208fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod				       hb_position_t *x, hb_position_t *y)
2218fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2228fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x = *y = 0;
22388e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_h_origin (this, user_data,
22488e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					glyph, x, y,
22588e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					klass->user_data.glyph_h_origin);
2268fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2278fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2288fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph,
2298fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod				       hb_position_t *x, hb_position_t *y)
2308fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2318fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x = *y = 0;
23288e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_v_origin (this, user_data,
23388e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					glyph, x, y,
23488e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					klass->user_data.glyph_v_origin);
2358fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2368fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2378fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
2388fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
23988e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_h_kerning (this, user_data,
24088e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 left_glyph, right_glyph,
24188e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 klass->user_data.glyph_h_kerning);
2428fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2438fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
244288f2899979bcc9e68f8115cb76e3271ed0e17bcBehdad Esfahbod  inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
2458fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
24688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_v_kerning (this, user_data,
24788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 top_glyph, bottom_glyph,
24888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 klass->user_data.glyph_v_kerning);
2498fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2508fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2518fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
2528fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod				      hb_glyph_extents_t *extents)
2538fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2548fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    memset (extents, 0, sizeof (*extents));
25588e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_extents (this, user_data,
25688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				       glyph,
25788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				       extents,
25888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				       klass->user_data.glyph_extents);
2598fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2608fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2618fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index,
2628fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					    hb_position_t *x, hb_position_t *y)
2638fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2648fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x = *y = 0;
26588e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_contour_point (this, user_data,
26688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					     glyph, point_index,
26788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					     x, y,
26888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					     klass->user_data.glyph_contour_point);
2698fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2708fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2718fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_name (hb_codepoint_t glyph,
2728fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod				   char *name, unsigned int size)
2738fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2746f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (size) *name = '\0';
27588e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_name (this, user_data,
27688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				    glyph,
27788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				    name, size,
27888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod				    klass->user_data.glyph_name);
2798fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2808fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2818fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */
2828fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					hb_codepoint_t *glyph)
2838fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
2846f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    *glyph = 0;
2856f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (len == -1) len = strlen (name);
28688e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod    return klass->get.f.glyph_from_name (this, user_data,
28788e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 name, len,
28888e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 glyph,
28988e9a9bcae61421d9dd65715d25e5f20b2847c03Behdad Esfahbod					 klass->user_data.glyph_from_name);
2908fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
2918fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2928fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2938fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  /* A bit higher-level, and with fallback */
2948fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
2956f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  inline void get_extents_for_direction (hb_direction_t direction,
2966f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens					 hb_font_extents_t *extents)
2976f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  {
2986f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
2996f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      if (!get_font_h_extents (extents))
3006f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      {
3016f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->ascender = y_scale * .8;
3026f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->descender = y_scale - extents->ascender;
3036f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->line_gap = 0;
3046f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      }
3056f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    } else {
3066f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      if (!get_font_v_extents (extents))
3076f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      {
3086f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->ascender = x_scale / 2;
3096f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->descender = x_scale - extents->ascender;
3106f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens	extents->line_gap = 0;
3116f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens      }
3126f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    }
3136f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens  }
3146f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens
3158fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void get_glyph_advance_for_direction (hb_codepoint_t glyph,
3168fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					       hb_direction_t direction,
3178fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					       hb_position_t *x, hb_position_t *y)
3188fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
3198fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
3208fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *x = get_glyph_h_advance (glyph);
3218fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *y = 0;
3228fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    } else {
3238fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *x = 0;
3248fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *y = get_glyph_v_advance (glyph);
3258fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    }
3268fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
3278fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
3288fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  /* Internal only */
3298fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph,
3308fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					     hb_position_t *x, hb_position_t *y)
3318fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
3328fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x = get_glyph_h_advance (glyph) / 2;
3338fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
3346f2e6de1fae0ab2269b472a750788817de6c2a6eSimon Cozens    /* TODO use font_extents.ascender */
3358fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *y = y_scale;
3368fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
3378fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
3388fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void get_glyph_origin_for_direction (hb_codepoint_t glyph,
3398fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					      hb_direction_t direction,
3408fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					      hb_position_t *x, hb_position_t *y)
3418fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
3427235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
3437235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod    {
3447235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod      if (!get_glyph_h_origin (glyph, x, y) &&
3457235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod	   get_glyph_v_origin (glyph, x, y))
3467235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod      {
3478fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	hb_position_t dx, dy;
3488fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	guess_v_origin_minus_h_origin (glyph, &dx, &dy);
3498fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	*x -= dx; *y -= dy;
3508fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      }
3517235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod    }
3527235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod    else
3537235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod    {
3547235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod      if (!get_glyph_v_origin (glyph, x, y) &&
3557235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod	   get_glyph_h_origin (glyph, x, y))
3567235f33f9e5e031622a00a84f4b2e98f16803579Behdad Esfahbod      {
3578fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	hb_position_t dx, dy;
3588fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	guess_v_origin_minus_h_origin (glyph, &dx, &dy);
3598fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod	*x += dx; *y += dy;
3608fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      }
3618fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    }
3628fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
3638fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
364bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  inline void add_glyph_h_origin (hb_codepoint_t glyph,
365bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod				  hb_position_t *x, hb_position_t *y)
366bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  {
367bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    hb_position_t origin_x, origin_y;
368bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
369bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    get_glyph_h_origin (glyph, &origin_x, &origin_y);
370bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
371bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *x += origin_x;
372bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *y += origin_y;
373bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  }
374bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  inline void add_glyph_v_origin (hb_codepoint_t glyph,
375bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod				  hb_position_t *x, hb_position_t *y)
376bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  {
377bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    hb_position_t origin_x, origin_y;
378bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
379bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    get_glyph_v_origin (glyph, &origin_x, &origin_y);
380bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
381bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *x += origin_x;
382bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *y += origin_y;
383bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  }
3848fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void add_glyph_origin_for_direction (hb_codepoint_t glyph,
3858fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					      hb_direction_t direction,
3868fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					      hb_position_t *x, hb_position_t *y)
3878fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
3888fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    hb_position_t origin_x, origin_y;
3898fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
3908fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
3918fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
3928fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x += origin_x;
3938fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *y += origin_y;
3948fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
3958fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
396bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  inline void subtract_glyph_h_origin (hb_codepoint_t glyph,
397bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod				       hb_position_t *x, hb_position_t *y)
398bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  {
399bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    hb_position_t origin_x, origin_y;
400bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
401bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    get_glyph_h_origin (glyph, &origin_x, &origin_y);
402bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
403bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *x -= origin_x;
404bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *y -= origin_y;
405bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  }
406bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  inline void subtract_glyph_v_origin (hb_codepoint_t glyph,
407bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod				       hb_position_t *x, hb_position_t *y)
408bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  {
409bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    hb_position_t origin_x, origin_y;
410bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
411bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    get_glyph_v_origin (glyph, &origin_x, &origin_y);
412bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod
413bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *x -= origin_x;
414bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod    *y -= origin_y;
415bee901b38ef3c26a04f69c299c8d5e028a0090e9Behdad Esfahbod  }
4168fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph,
4178fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						   hb_direction_t direction,
4188fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						   hb_position_t *x, hb_position_t *y)
4198fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
4208fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    hb_position_t origin_x, origin_y;
4218fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4228fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y);
4238fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4248fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *x -= origin_x;
4258fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    *y -= origin_y;
4268fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
4278fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4288fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
4298fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					       hb_direction_t direction,
4308fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod					       hb_position_t *x, hb_position_t *y)
4318fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
4328fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
4338fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *x = get_glyph_h_kerning (first_glyph, second_glyph);
4348fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *y = 0;
4358fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    } else {
4368fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *x = 0;
4378fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      *y = get_glyph_v_kerning (first_glyph, second_glyph);
4388fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    }
4398fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
4408fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4418fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph,
4428fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						 hb_direction_t direction,
4438fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						 hb_glyph_extents_t *extents)
4448fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
4458fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    hb_bool_t ret = get_glyph_extents (glyph, extents);
4468fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4478fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    if (ret)
4488fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing);
4498fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4508fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    return ret;
4518fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
4528fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4538fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index,
4548fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						       hb_direction_t direction,
4558fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod						       hb_position_t *x, hb_position_t *y)
4568fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  {
4578fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y);
4588fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4598fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    if (ret)
4608fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod      subtract_glyph_origin_for_direction (glyph, direction, x, y);
4618fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4628fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod    return ret;
4638fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod  }
4648fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
4656f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  /* Generates gidDDD if glyph has no name. */
4666f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  inline void
4676f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  glyph_to_string (hb_codepoint_t glyph,
4686f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod		   char *s, unsigned int size)
4696f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  {
4706f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (get_glyph_name (glyph, s, size)) return;
4716f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
47238b8b40526a85f33521542e24d1e0c82588efc85Behdad Esfahbod    if (size && snprintf (s, size, "gid%u", glyph) < 0)
47338b8b40526a85f33521542e24d1e0c82588efc85Behdad Esfahbod      *s = '\0';
4746f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  }
4756f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
4766f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  /* Parses gidDDD and uniUUUU strings automatically. */
4776f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  inline hb_bool_t
4786f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  glyph_from_string (const char *s, int len, /* -1 means nul-terminated */
4796f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod		     hb_codepoint_t *glyph)
4806f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  {
4816f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (get_glyph_from_name (s, len, glyph)) return true;
4826f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
4836f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (len == -1) len = strlen (s);
4846f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
4856f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    /* Straight glyph index. */
4866f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (hb_codepoint_parse (s, len, 10, glyph))
4876f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      return true;
4886f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
4896f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    if (len > 3)
4906f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    {
4916f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      /* gidDDD syntax for glyph indices. */
4926f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      if (0 == strncmp (s, "gid", 3) &&
4936f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod	  hb_codepoint_parse (s + 3, len - 3, 10, glyph))
4946f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod	return true;
4956f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
4966f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      /* uniUUUU and other Unicode character indices. */
4976f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      hb_codepoint_t unichar;
4986f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod      if (0 == strncmp (s, "uni", 3) &&
4996f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod	  hb_codepoint_parse (s + 3, len - 3, 16, &unichar) &&
5008b5bc141cd3a6bfcea3c91a882a630426876ceb3Behdad Esfahbod	  get_nominal_glyph (unichar, glyph))
5016f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod	return true;
5026f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    }
5036f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod
5046f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod    return false;
5056f3a300138f659020c21c3e08b7981c78df5f332Behdad Esfahbod  }
5068fbfda920e0b3bb4ab7afb732826026964b79be9Behdad Esfahbod
507abcfe9b59b4475eb02dd679aac4bc59616713b28Behdad Esfahbod  private:
50883408cf804a6908873c41b70bb7c43448e66ddd2Behdad Esfahbod  inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
509c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod};
510c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
5115b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
512027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
513027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#include "hb-shaper-list.hh"
514027857d0412477fb4427dcb8a8c45287c272e143Behdad Esfahbod#undef HB_SHAPER_IMPLEMENT
5155b95c148cc485f79fd7018bc4520b4cb5f728a18Behdad Esfahbod#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
516c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
517c62b503770325819f249885dfc9d4683a69c9efdBehdad Esfahbod
518c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#endif /* HB_FONT_PRIVATE_HH */
519