hb-ot-font.cc 8.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * Copyright © 2011,2014  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
 */

#include "hb-private.hh"

#include "hb-ot.h"

#include "hb-font-private.hh"
32
#include "hb-machinery-private.hh"
33

34
#include "hb-ot-cmap-table.hh"
35
#include "hb-ot-glyf-table.hh"
36
#include "hb-ot-hmtx-table.hh"
37
#include "hb-ot-kern-table.hh"
38
#include "hb-ot-post-table.hh"
39

40 41
#include "hb-ot-color-cbdt-table.hh"

42 43 44

struct hb_ot_font_t
{
B
Behdad Esfahbod 已提交
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  inline void init (hb_face_t *face)
  {
    cmap.init (face);
    h_metrics.init (face);
    v_metrics.init (face, h_metrics.ascender - h_metrics.descender); /* TODO Can we do this lazily? */

    this->face = face;
    glyf.init ();
    cbdt.init ();
    post.init ();
    kern.init ();
  }
  inline void fini (void)
  {
    cmap.fini ();
    h_metrics.fini ();
    v_metrics.fini ();

    glyf.fini ();
    cbdt.fini ();
    post.fini ();
    kern.fini ();
  }

69
  OT::cmap::accelerator_t cmap;
70 71
  OT::hmtx::accelerator_t h_metrics;
  OT::vmtx::accelerator_t v_metrics;
72

B
Minor  
Behdad Esfahbod 已提交
73
  hb_face_t *face; /* MUST be JUST before the lazy loaders. */
B
Behdad Esfahbod 已提交
74 75 76 77
  hb_face_lazy_loader_t<1, OT::glyf::accelerator_t> glyf;
  hb_face_lazy_loader_t<2, OT::CBDT::accelerator_t> cbdt;
  hb_face_lazy_loader_t<3, OT::post::accelerator_t> post;
  hb_face_lazy_loader_t<4, OT::kern::accelerator_t> kern;
78 79 80 81
};


static hb_ot_font_t *
B
Minor  
Behdad Esfahbod 已提交
82
_hb_ot_font_create (hb_face_t *face)
83 84 85 86
{
  hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t));

  if (unlikely (!ot_font))
B
Behdad Esfahbod 已提交
87
    return nullptr;
88

B
Behdad Esfahbod 已提交
89
  ot_font->init (face);
90

91 92 93 94
  return ot_font;
}

static void
95
_hb_ot_font_destroy (void *data)
96
{
97 98
  hb_ot_font_t *ot_font = (hb_ot_font_t *) data;

B
Behdad Esfahbod 已提交
99
  ot_font->fini ();
100 101 102 103 104 105

  free (ot_font);
}


static hb_bool_t
106 107 108 109 110 111 112 113 114 115
hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
			 void *font_data,
			 hb_codepoint_t unicode,
			 hb_codepoint_t *glyph,
			 void *user_data HB_UNUSED)

{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  return ot_font->cmap.get_nominal_glyph (unicode, glyph);
}
116

117 118 119 120 121 122 123
static hb_bool_t
hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
			   void *font_data,
			   hb_codepoint_t unicode,
			   hb_codepoint_t variation_selector,
			   hb_codepoint_t *glyph,
			   void *user_data HB_UNUSED)
124
{
125
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
126
  return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph);
127 128 129
}

static hb_position_t
130
hb_ot_get_glyph_h_advance (hb_font_t *font,
131 132 133 134 135
			   void *font_data,
			   hb_codepoint_t glyph,
			   void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
136
  return font->em_scale_x (ot_font->h_metrics.get_advance (glyph, font));
137 138 139
}

static hb_position_t
140
hb_ot_get_glyph_v_advance (hb_font_t *font,
141 142 143 144
			   void *font_data,
			   hb_codepoint_t glyph,
			   void *user_data HB_UNUSED)
{
145
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
146
  return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font));
147 148
}

B
Behdad Esfahbod 已提交
149 150 151 152 153 154 155 156 157 158 159
static hb_position_t
hb_ot_get_glyph_h_kerning (hb_font_t *font,
			   void *font_data,
			   hb_codepoint_t left_glyph,
			   hb_codepoint_t right_glyph,
			   void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
}

160
static hb_bool_t
161
hb_ot_get_glyph_extents (hb_font_t *font,
162 163 164 165 166
			 void *font_data,
			 hb_codepoint_t glyph,
			 hb_glyph_extents_t *extents,
			 void *user_data HB_UNUSED)
{
167
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
168
  bool ret = ot_font->glyf->get_extents (glyph, extents);
169
  if (!ret)
170
    ret = ot_font->cbdt->get_extents (glyph, extents);
171
  // TODO Hook up side-bearings variations.
172 173 174 175 176
  extents->x_bearing = font->em_scale_x (extents->x_bearing);
  extents->y_bearing = font->em_scale_y (extents->y_bearing);
  extents->width     = font->em_scale_x (extents->width);
  extents->height    = font->em_scale_y (extents->height);
  return ret;
177 178
}

179 180 181 182 183 184 185 186 187 188 189
static hb_bool_t
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
                      void *font_data,
                      hb_codepoint_t glyph,
                      char *name, unsigned int size,
                      void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  return ot_font->post->get_glyph_name (glyph, name, size);
}

190 191 192 193 194 195 196 197 198 199 200
static hb_bool_t
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
                           void *font_data,
                           const char *name, int len,
                           hb_codepoint_t *glyph,
                           void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  return ot_font->post->get_glyph_from_name (name, len, glyph);
}

201
static hb_bool_t
202
hb_ot_get_font_h_extents (hb_font_t *font,
203 204 205 206 207 208 209 210
			  void *font_data,
			  hb_font_extents_t *metrics,
			  void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender);
  metrics->descender = font->em_scale_y (ot_font->h_metrics.descender);
  metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap);
211
  // TODO Hook up variations.
B
Behdad Esfahbod 已提交
212
  return ot_font->h_metrics.has_font_extents;
213 214 215
}

static hb_bool_t
216
hb_ot_get_font_v_extents (hb_font_t *font,
217 218 219 220 221 222 223 224
			  void *font_data,
			  hb_font_extents_t *metrics,
			  void *user_data HB_UNUSED)
{
  const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
  metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender);
  metrics->descender = font->em_scale_x (ot_font->v_metrics.descender);
  metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap);
225
  // TODO Hook up variations.
B
Behdad Esfahbod 已提交
226
  return ot_font->v_metrics.has_font_extents;
227
}
228

229
#ifdef HB_USE_ATEXIT
230
static void free_static_ot_funcs (void);
231
#endif
232

233
static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
234
{
235
  static inline hb_font_funcs_t *create (void)
236
  {
237
    hb_font_funcs_t *funcs = hb_font_funcs_create ();
238

B
Behdad Esfahbod 已提交
239 240 241 242 243 244 245 246
    hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
    hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
    hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
    hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
    hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr);
    hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
    //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
    //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
247
    hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
B
Behdad Esfahbod 已提交
248 249
    //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
    hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
B
Behdad Esfahbod 已提交
250
    //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
251
    hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
252
    hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
253 254 255

    hb_font_funcs_make_immutable (funcs);

256 257 258 259 260 261 262
#ifdef HB_USE_ATEXIT
    atexit (free_static_ot_funcs);
#endif

    return funcs;
  }
} static_ot_funcs;
263 264

#ifdef HB_USE_ATEXIT
265 266 267
static
void free_static_ot_funcs (void)
{
B
Behdad Esfahbod 已提交
268
  static_ot_funcs.free_instance ();
269
}
270
#endif
271

272 273 274
static hb_font_funcs_t *
_hb_ot_get_font_funcs (void)
{
B
Behdad Esfahbod 已提交
275
  return static_ot_funcs.get_unconst ();
276 277 278
}


S
Sascha Brawer 已提交
279
/**
B
Behdad Esfahbod 已提交
280 281
 * hb_ot_font_set_funcs:
 *
S
Sascha Brawer 已提交
282 283
 * Since: 0.9.28
 **/
284 285 286
void
hb_ot_font_set_funcs (hb_font_t *font)
{
B
Minor  
Behdad Esfahbod 已提交
287
  hb_ot_font_t *ot_font = _hb_ot_font_create (font->face);
288 289 290 291 292 293
  if (unlikely (!ot_font))
    return;

  hb_font_set_funcs (font,
		     _hb_ot_get_font_funcs (),
		     ot_font,
294
		     _hb_ot_font_destroy);
295
}