hb-ft.cc revision e715784be35f0846c0e084b7c53c7556ce933a45
1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org/*
2750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * Copyright © 2009  Red Hat, Inc.
3750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * Copyright © 2009  Keith Stribley
4750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *
5750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *  This is part of HarfBuzz, a text shaping library.
6750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *
7750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * Permission is hereby granted, without written agreement and without
8750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * license or royalty fees, to use, copy, modify, and distribute this
9750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * software and its documentation for any purpose, provided that the
10750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * above copyright notice and the following two paragraphs appear in
11750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * all copies of this software.
12750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *
13750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * DAMAGE.
18750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *
19750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org *
25750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org * Red Hat Author(s): Behdad Esfahbod
26750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org */
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "hb-private.hh"
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "hb-ft.h"
319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org#include "hb-font-private.hh"
339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include FT_TRUETYPE_TABLES_H
359a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com/* TODO:
399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com *
409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * In general, this file does a fine job of what it's supposed to do.
419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com * There are, however, things that need more work:
429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com *
43e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org *   - We don't handle any load_flags.  That definitely has API implications. :(
44e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org *     I believe hb_ft_font_create() should take load_flags input.
456e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org *
46e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org *   - We don't handle / allow for emboldening / obliqueing.
476e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org *
486e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org *   - In the future, we should add constructors to create fonts in font space.
496e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org *
505323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org *   - I believe transforms are not correctly implemented.  FreeType does not
515323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org *     provide any API to get to the transform/delta set on the face. :(
525323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org *
535323a9c29497eb5a52821d396990c6d75a37baf7jkummerow@chromium.org *   - Always use FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH?
54e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org */
55e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
56e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org
57e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orgstatic hb_bool_t
58e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.orghb_ft_get_glyph (hb_font_t *font HB_UNUSED,
59e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org		 void *font_data,
60e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org		 hb_codepoint_t unicode,
61e4ee6de0de64744d55b63da83156827c989c7099verwaest@chromium.org		 hb_codepoint_t variation_selector,
629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com		 hb_codepoint_t *glyph,
639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com		 void *user_data HB_UNUSED)
649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
65ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org{
669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  FT_Face ft_face = (FT_Face) font_data;
67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (unlikely (variation_selector)) {
709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    if (*glyph)
729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com      return TRUE;
739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
74e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
75ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
76ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  *glyph = FT_Get_Char_Index (ft_face, unicode);
77ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return *glyph != 0;
78ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_position_t
819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comhb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
8209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org			   void *font_data,
839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   hb_codepoint_t glyph,
849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   void *user_data HB_UNUSED)
8509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org{
8609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  FT_Face ft_face = (FT_Face) font_data;
8759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  int load_flags = FT_LOAD_DEFAULT;
889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    return 0;
9109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return ft_face->glyph->metrics.horiAdvance;
939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
9409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
9559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgstatic hb_position_t
969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comhb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   void *font_data,
989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   hb_codepoint_t glyph,
9909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org			   void *user_data HB_UNUSED)
100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org{
1019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  FT_Face ft_face = (FT_Face) font_data;
1029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int load_flags = FT_LOAD_DEFAULT;
10309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
10409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
10559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return 0;
1069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
1089a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com   * have a Y growing upward.  Hence the extra negation. */
10909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return -ft_face->glyph->metrics.vertAdvance;
1109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_bool_t
11309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orghb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED,
1149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  void *font_data HB_UNUSED,
1159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_codepoint_t glyph HB_UNUSED,
1169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_position_t *x HB_UNUSED,
1179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_position_t *y HB_UNUSED,
1189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  void *user_data HB_UNUSED)
11909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org{
12009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  /* We always work in the horizontal coordinates. */
121303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  return TRUE;
122303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org}
12309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
1249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_bool_t
1259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comhb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
1269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  void *font_data,
1279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_codepoint_t glyph,
1289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_position_t *x,
1299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			  hb_position_t *y,
130ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org			  void *user_data HB_UNUSED)
1319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com{
1329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  FT_Face ft_face = (FT_Face) font_data;
1339a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int load_flags = FT_LOAD_DEFAULT;
13409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
135303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
136303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    return FALSE;
13709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
1389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
1399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com   * have a Y growing upward.  Hence the extra negation. */
140ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  *x = ft_face->glyph->metrics.horiBearingX -   ft_face->glyph->metrics.vertBearingX;
141ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
1429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return TRUE;
1449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_position_t
147e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orghb_ft_get_glyph_h_kerning (hb_font_t *font HB_UNUSED,
14809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org			   void *font_data,
149d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org			   hb_codepoint_t left_glyph,
15009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org			   hb_codepoint_t right_glyph,
1519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   void *user_data HB_UNUSED)
1522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org{
15309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  FT_Face ft_face = (FT_Face) font_data;
1549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  FT_Vector kerningv;
1559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerningv))
1579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    return 0;
15809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
1599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return kerningv.x;
1609a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1619a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_position_t
16309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orghb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED,
1649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   void *font_data HB_UNUSED,
1659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   hb_codepoint_t top_glyph HB_UNUSED,
1669a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   hb_codepoint_t bottom_glyph HB_UNUSED,
1679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   void *user_data HB_UNUSED)
16809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org{
1699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  /* FreeType API doesn't support vertical kerning */
1709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return 0;
1719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
17309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgstatic hb_bool_t
1749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comhb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
1759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			 void *font_data,
1769a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			 hb_codepoint_t glyph,
1779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			 hb_glyph_extents_t *extents,
1789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com			 void *user_data HB_UNUSED)
1799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com{
18009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  FT_Face ft_face = (FT_Face) font_data;
1819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int load_flags = FT_LOAD_DEFAULT;
1829a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
1849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com    return FALSE;
1859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
186303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
18709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
188303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  extents->width = ft_face->glyph->metrics.width;
1899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  extents->height = ft_face->glyph->metrics.height;
1909a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return TRUE;
1919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com}
1929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
1939a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_bool_t
19409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orghb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
19559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       void *font_data,
19659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       hb_codepoint_t glyph,
19759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       unsigned int point_index,
19859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       hb_position_t *x,
19959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       hb_position_t *y,
20059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org			       void *user_data HB_UNUSED)
2019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com{
20209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  FT_Face ft_face = (FT_Face) font_data;
20377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  int load_flags = FT_LOAD_DEFAULT;
2049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
205d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
206ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      return FALSE;
207ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2089a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
2094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return FALSE;
210ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
21146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
2124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org      return FALSE;
2139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  *x = ft_face->glyph->outline.points[point_index].x;
21509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  *y = ft_face->glyph->outline.points[point_index].y;
21609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
21709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  return TRUE;
21809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org}
2199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_font_funcs_t ft_ffuncs = {
22109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  HB_OBJECT_HEADER_STATIC,
22209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
22309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  TRUE, /* immutable */
2249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  {
22609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    hb_ft_get_glyph,
2279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_ft_get_glyph_h_advance,
22809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org    hb_ft_get_glyph_v_advance,
2299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_ft_get_glyph_h_origin,
2309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_ft_get_glyph_v_origin,
2319a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_ft_get_glyph_h_kerning,
2329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_ft_get_glyph_v_kerning,
233e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    hb_ft_get_glyph_extents,
23471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org    hb_ft_get_glyph_contour_point,
23530ce411529579186181838984710b0b0980857aaricow@chromium.org  }
2369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com};
2374a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org
23871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orghb_font_funcs_t *
2394a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orghb_ft_get_font_funcs (void)
2409258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org{
2414a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  return &ft_ffuncs;
2429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic hb_blob_t *
2469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comreference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
2479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com{
2489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  FT_Face ft_face = (FT_Face) user_data;
249e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  FT_Byte *buffer;
250c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  FT_ULong  length = 0;
251c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  FT_Error error;
252c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org
2539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (unlikely (tag == HB_TAG_NONE))
2542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    return NULL;
255ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
256c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  error = FT_Load_Sfnt_Table (ft_face, tag, 0, NULL, &length);
2579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  if (error)
2584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    return NULL;
2594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
2604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  buffer = (FT_Byte *) malloc (length);
2614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  if (buffer == NULL)
262ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return NULL;
263ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
264c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  error = FT_Load_Sfnt_Table (ft_face, tag, 0, buffer, &length);
265ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (error)
266ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    return NULL;
267c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org
268ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return hb_blob_create ((const char *) buffer, length,
269c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org			 HB_MEMORY_MODE_WRITABLE,
270ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org			 buffer, free);
27146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
2729ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
273ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
274c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orghb_face_t *
2759ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orghb_ft_face_create (FT_Face           ft_face,
2769ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org		   hb_destroy_func_t destroy)
2779ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org{
2789ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  hb_face_t *face;
279ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
280ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (ft_face->stream->read == NULL) {
281ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    hb_blob_t *blob;
282ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    blob = hb_blob_create ((const char *) ft_face->stream->base,
284c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org			   (unsigned int) ft_face->stream->size,
2859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com			   /* TODO: We assume that it's mmap()'ed, but FreeType code
286ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org			    * suggests that there are cases we reach here but font is
28746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org			    * not mmapped.  For example, when mmap() fails.  No idea
28846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org			    * how to deal with it better here. */
289ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org			   HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
29046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org			   ft_face, destroy);
291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    face = hb_face_create (blob, ft_face->face_index);
2929a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    hb_blob_destroy (blob);
293ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else {
294ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    face = hb_face_create_for_tables (reference_table, ft_face, destroy);
295ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
296c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org
297ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return face;
298c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org}
29946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
3009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgstatic void
3019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orghb_ft_face_finalize (FT_Face ft_face)
3029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org{
303ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  hb_face_destroy ((hb_face_t *) ft_face->generic.data);
3049a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
305ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
306c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orghb_face_t *
3079a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comhb_ft_face_create_cached (FT_Face ft_face)
30846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org{
30946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (unlikely (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer) hb_ft_face_finalize))
31046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  {
311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (ft_face->generic.finalizer)
31246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      ft_face->generic.finalizer (ft_face);
313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
314303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    ft_face->generic.data = hb_ft_face_create (ft_face, NULL);
315303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    ft_face->generic.finalizer = (FT_Generic_Finalizer) hb_ft_face_finalize;
3169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
3179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  return hb_face_reference ((hb_face_t *) ft_face->generic.data);
3192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org}
3202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
3212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
322c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orghb_font_t *
323bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orghb_ft_font_create (FT_Face           ft_face,
324ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org		   hb_destroy_func_t destroy)
325ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org{
3269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  hb_font_t *font;
3279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  hb_face_t *face;
3289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  face = hb_ft_face_create (ft_face, destroy);
330e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  font = hb_font_create (face);
331e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  hb_face_destroy (face);
3329a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  hb_font_set_funcs (font,
3332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org		     hb_ft_get_font_funcs (),
3342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org		     ft_face, NULL);
3352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  hb_font_set_scale (font,
3362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org		     ((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM) >> 16,
3372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org		     ((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM) >> 16);
3389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  hb_font_set_ppem (font,
3399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com		    ft_face->size->metrics.x_ppem,
3409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com		    ft_face->size->metrics.y_ppem);
3419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
342e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return font;
343d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
344d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
3459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
346e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org