parent
343a0e4e74
commit
903648437c
10 changed files with 283 additions and 53 deletions
@ -0,0 +1,260 @@ |
||||
/*
|
||||
* 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" |
||||
|
||||
#include "hb-ot-hhea-table.hh" |
||||
#include "hb-ot-hmtx-table.hh" |
||||
|
||||
|
||||
|
||||
struct hb_ot_font_t |
||||
{ |
||||
unsigned int num_glyphs; |
||||
unsigned int num_hmetrics; |
||||
const OT::hmtx *hmtx; |
||||
hb_blob_t *hmtx_blob; |
||||
}; |
||||
|
||||
|
||||
static hb_ot_font_t * |
||||
_hb_ot_font_create (hb_font_t *font) |
||||
{ |
||||
hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); |
||||
|
||||
if (unlikely (!ot_font)) |
||||
return NULL; |
||||
|
||||
ot_font->num_glyphs = font->face->get_num_glyphs (); |
||||
|
||||
{ |
||||
hb_blob_t *hhea_blob = OT::Sanitizer<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea)); |
||||
const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob); |
||||
ot_font->num_hmetrics = hhea->numberOfHMetrics; |
||||
hb_blob_destroy (hhea_blob); |
||||
} |
||||
ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx)); |
||||
if (unlikely (!ot_font->num_hmetrics || |
||||
2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob))) |
||||
{ |
||||
hb_blob_destroy (ot_font->hmtx_blob); |
||||
free (ot_font); |
||||
return NULL; |
||||
} |
||||
|
||||
ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob); |
||||
|
||||
return ot_font; |
||||
} |
||||
|
||||
static void |
||||
_hb_ot_font_destroy (hb_ot_font_t *ot_font) |
||||
{ |
||||
hb_blob_destroy (ot_font->hmtx_blob); |
||||
|
||||
free (ot_font); |
||||
} |
||||
|
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_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) |
||||
|
||||
{ |
||||
#if 0 |
||||
FT_Face ft_face = (FT_Face) font_data; |
||||
|
||||
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX |
||||
if (unlikely (variation_selector)) { |
||||
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); |
||||
return *glyph != 0; |
||||
} |
||||
#endif |
||||
|
||||
*glyph = FT_Get_Char_Index (ft_face, unicode); |
||||
return *glyph != 0; |
||||
#endif |
||||
return true; |
||||
} |
||||
|
||||
static hb_position_t |
||||
hb_ot_get_glyph_h_advance (hb_font_t *font, |
||||
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; |
||||
|
||||
if (unlikely (glyph >= ot_font->num_glyphs)) |
||||
return 0; /* Maybe better to return notdef's advance instead? */ |
||||
|
||||
if (glyph >= ot_font->num_hmetrics) |
||||
glyph = ot_font->num_hmetrics - 1; |
||||
|
||||
return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advanceWidth); |
||||
} |
||||
|
||||
static hb_position_t |
||||
hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, |
||||
void *font_data, |
||||
hb_codepoint_t glyph, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* TODO */ |
||||
return 0; |
||||
} |
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED, |
||||
void *font_data HB_UNUSED, |
||||
hb_codepoint_t glyph HB_UNUSED, |
||||
hb_position_t *x HB_UNUSED, |
||||
hb_position_t *y HB_UNUSED, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* We always work in the horizontal coordinates. */ |
||||
return true; |
||||
} |
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED, |
||||
void *font_data, |
||||
hb_codepoint_t glyph, |
||||
hb_position_t *x, |
||||
hb_position_t *y, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* TODO */ |
||||
return false; |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
/* TODO */ |
||||
return 0; |
||||
} |
||||
|
||||
static hb_position_t |
||||
hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, |
||||
void *font_data HB_UNUSED, |
||||
hb_codepoint_t top_glyph HB_UNUSED, |
||||
hb_codepoint_t bottom_glyph HB_UNUSED, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
return 0; |
||||
} |
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, |
||||
void *font_data, |
||||
hb_codepoint_t glyph, |
||||
hb_glyph_extents_t *extents, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* TODO */ |
||||
return false; |
||||
} |
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED, |
||||
void *font_data, |
||||
hb_codepoint_t glyph, |
||||
unsigned int point_index, |
||||
hb_position_t *x, |
||||
hb_position_t *y, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* TODO */ |
||||
return false; |
||||
} |
||||
|
||||
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) |
||||
{ |
||||
/* TODO */ |
||||
return false; |
||||
} |
||||
|
||||
static hb_bool_t |
||||
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, |
||||
void *font_data, |
||||
const char *name, int len, /* -1 means nul-terminated */ |
||||
hb_codepoint_t *glyph, |
||||
void *user_data HB_UNUSED) |
||||
{ |
||||
/* TODO */ |
||||
return false; |
||||
} |
||||
|
||||
|
||||
static hb_font_funcs_t * |
||||
_hb_ot_get_font_funcs (void) |
||||
{ |
||||
static const hb_font_funcs_t ot_ffuncs = { |
||||
HB_OBJECT_HEADER_STATIC, |
||||
|
||||
true, /* immutable */ |
||||
|
||||
{ |
||||
#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name, |
||||
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS |
||||
#undef HB_FONT_FUNC_IMPLEMENT |
||||
} |
||||
}; |
||||
|
||||
return const_cast<hb_font_funcs_t *> (&ot_ffuncs); |
||||
} |
||||
|
||||
|
||||
void |
||||
hb_ot_font_set_funcs (hb_font_t *font) |
||||
{ |
||||
hb_ot_font_t *ot_font = _hb_ot_font_create (font); |
||||
if (unlikely (!ot_font)) |
||||
return; |
||||
|
||||
hb_font_set_funcs (font, |
||||
_hb_ot_get_font_funcs (), |
||||
ot_font, |
||||
(hb_destroy_func_t) _hb_ot_font_destroy); |
||||
} |
Loading…
Reference in new issue