| Index: third_party/harfbuzz-ng/src/hb-ft.cc
|
| diff --git a/third_party/harfbuzz-ng/src/hb-ft.cc b/third_party/harfbuzz-ng/src/hb-ft.cc
|
| index 468742cfd05fef35dd256b6a264ea9ca8a21973d..b695f81ab08475d4fa00ab63dd18c50af863ec4c 100644
|
| --- a/third_party/harfbuzz-ng/src/hb-ft.cc
|
| +++ b/third_party/harfbuzz-ng/src/hb-ft.cc
|
| @@ -1,6 +1,7 @@
|
| /*
|
| * Copyright © 2009 Red Hat, Inc.
|
| * Copyright © 2009 Keith Stribley
|
| + * Copyright © 2015 Google, Inc.
|
| *
|
| * This is part of HarfBuzz, a text shaping library.
|
| *
|
| @@ -23,6 +24,7 @@
|
| * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
| *
|
| * Red Hat Author(s): Behdad Esfahbod
|
| + * Google Author(s): Behdad Esfahbod
|
| */
|
|
|
| #include "hb-private.hh"
|
| @@ -46,17 +48,15 @@
|
| * In general, this file does a fine job of what it's supposed to do.
|
| * There are, however, things that need more work:
|
| *
|
| - * - We don't handle any load_flags. That definitely has API implications. :(
|
| - * I believe hb_ft_font_create() should take load_flags input.
|
| - * In particular, FT_Get_Advance() without the NO_HINTING flag seems to be
|
| - * buggy.
|
| + * - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy.
|
| + * Have not investigated.
|
| *
|
| - * FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
|
| + * - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
|
| * would work fine. However, we also abuse this API for performing in font-space,
|
| * but don't pass the correct flags to FreeType. We just abuse the no-hinting mode
|
| * for that, such that no rounding etc happens. As such, we don't set ppem, and
|
| - * pass NO_HINTING around. This seems to work best, until we go ahead and add a full
|
| - * load_flags API.
|
| + * pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale
|
| + * ourselves, like we do in uniscribe, etc.
|
| *
|
| * - We don't handle / allow for emboldening / obliqueing.
|
| *
|
| @@ -66,6 +66,94 @@
|
| */
|
|
|
|
|
| +struct hb_ft_font_t
|
| +{
|
| + FT_Face ft_face;
|
| + int load_flags;
|
| + bool unref; /* Whether to destroy ft_face when done. */
|
| +};
|
| +
|
| +static hb_ft_font_t *
|
| +_hb_ft_font_create (FT_Face ft_face, bool unref)
|
| +{
|
| + hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
|
| +
|
| + if (unlikely (!ft_font))
|
| + return NULL;
|
| +
|
| + ft_font->ft_face = ft_face;
|
| + ft_font->unref = unref;
|
| +
|
| + ft_font->load_flags = FT_LOAD_DEFAULT;
|
| +
|
| + return ft_font;
|
| +}
|
| +
|
| +static void
|
| +_hb_ft_font_destroy (hb_ft_font_t *ft_font)
|
| +{
|
| + if (ft_font->unref)
|
| + FT_Done_Face (ft_font->ft_face);
|
| +
|
| + free (ft_font);
|
| +}
|
| +
|
| +/**
|
| + * hb_ft_font_set_load_flags:
|
| + * @font:
|
| + * @load_flags:
|
| + *
|
| + *
|
| + *
|
| + * Since: 1.0.5
|
| + **/
|
| +void
|
| +hb_ft_font_set_load_flags (hb_font_t *font, int load_flags)
|
| +{
|
| + if (font->immutable)
|
| + return;
|
| +
|
| + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
| + return;
|
| +
|
| + hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data;
|
| +
|
| + ft_font->load_flags = load_flags;
|
| +}
|
| +
|
| +/**
|
| + * hb_ft_font_get_load_flags:
|
| + * @font:
|
| + *
|
| + *
|
| + *
|
| + * Return value:
|
| + * Since: 1.0.5
|
| + **/
|
| +int
|
| +hb_ft_font_get_load_flags (hb_font_t *font)
|
| +{
|
| + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
| + return 0;
|
| +
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
|
| +
|
| + return ft_font->load_flags;
|
| +}
|
| +
|
| +FT_Face
|
| +hb_ft_font_get_face (hb_font_t *font)
|
| +{
|
| + if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy)
|
| + return NULL;
|
| +
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data;
|
| +
|
| + return ft_font->ft_face;
|
| +}
|
| +
|
| +
|
| +
|
| static hb_bool_t
|
| hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
|
| void *font_data,
|
| @@ -75,13 +163,13 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
|
| void *user_data HB_UNUSED)
|
|
|
| {
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| unsigned int g;
|
| - FT_Face ft_face = (FT_Face) font_data;
|
|
|
| if (likely (!variation_selector))
|
| - g = FT_Get_Char_Index (ft_face, unicode);
|
| + g = FT_Get_Char_Index (ft_font->ft_face, unicode);
|
| else
|
| - g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
|
| + g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
|
|
|
| if (unlikely (!g))
|
| return false;
|
| @@ -96,11 +184,10 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
| hb_codepoint_t glyph,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| - int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| FT_Fixed v;
|
|
|
| - if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
| + if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v)))
|
| return 0;
|
|
|
| if (font->x_scale < 0)
|
| @@ -115,11 +202,10 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
| hb_codepoint_t glyph,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| - int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_VERTICAL_LAYOUT;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| FT_Fixed v;
|
|
|
| - if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
| + if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
|
| return 0;
|
|
|
| if (font->y_scale < 0)
|
| @@ -150,10 +236,10 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
|
| hb_position_t *y,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| - int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| + FT_Face ft_face = ft_font->ft_face;
|
|
|
| - if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
|
| + if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
| return false;
|
|
|
| /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
| @@ -176,11 +262,11 @@ hb_ft_get_glyph_h_kerning (hb_font_t *font,
|
| hb_codepoint_t right_glyph,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| FT_Vector kerningv;
|
|
|
| FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
|
| - if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, mode, &kerningv))
|
| + if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
|
| return 0;
|
|
|
| return kerningv.x;
|
| @@ -204,10 +290,10 @@ hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
| hb_glyph_extents_t *extents,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| - int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| + FT_Face ft_face = ft_font->ft_face;
|
|
|
| - if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
|
| + if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
| return false;
|
|
|
| extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
|
| @@ -226,10 +312,10 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
|
| hb_position_t *y,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| - int load_flags = FT_LOAD_DEFAULT;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| + FT_Face ft_face = ft_font->ft_face;
|
|
|
| - if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
|
| + if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
| return false;
|
|
|
| if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
|
| @@ -251,9 +337,9 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
|
| char *name, unsigned int size,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
|
|
| - hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
|
| + hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size);
|
| if (ret && (size && !*name))
|
| ret = false;
|
|
|
| @@ -267,7 +353,8 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
| hb_codepoint_t *glyph,
|
| void *user_data HB_UNUSED)
|
| {
|
| - FT_Face ft_face = (FT_Face) font_data;
|
| + const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
| + FT_Face ft_face = ft_font->ft_face;
|
|
|
| if (len < 0)
|
| *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name);
|
| @@ -293,8 +380,8 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
| }
|
|
|
|
|
| -static hb_font_funcs_t *
|
| -_hb_ft_get_font_funcs (void)
|
| +static void
|
| +_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
|
| {
|
| static const hb_font_funcs_t ft_ffuncs = {
|
| HB_OBJECT_HEADER_STATIC,
|
| @@ -308,7 +395,10 @@ _hb_ft_get_font_funcs (void)
|
| }
|
| };
|
|
|
| - return const_cast<hb_font_funcs_t *> (&ft_ffuncs);
|
| + hb_font_set_funcs (font,
|
| + const_cast<hb_font_funcs_t *> (&ft_ffuncs),
|
| + _hb_ft_font_create (ft_face, unref),
|
| + (hb_destroy_func_t) _hb_ft_font_destroy);
|
| }
|
|
|
|
|
| @@ -347,7 +437,7 @@ reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
|
| *
|
| *
|
| * Return value: (transfer full):
|
| - * Since: 1.0
|
| + * Since: 0.9.2
|
| **/
|
| hb_face_t *
|
| hb_ft_face_create (FT_Face ft_face,
|
| @@ -403,7 +493,7 @@ hb_ft_face_finalize (FT_Face ft_face)
|
| *
|
| *
|
| * Return value: (transfer full):
|
| - * Since: 1.0
|
| + * Since: 0.9.2
|
| **/
|
| hb_face_t *
|
| hb_ft_face_create_cached (FT_Face ft_face)
|
| @@ -420,11 +510,6 @@ hb_ft_face_create_cached (FT_Face ft_face)
|
| return hb_face_reference ((hb_face_t *) ft_face->generic.data);
|
| }
|
|
|
| -static void
|
| -_do_nothing (void)
|
| -{
|
| -}
|
| -
|
|
|
| /**
|
| * hb_ft_font_create:
|
| @@ -434,7 +519,7 @@ _do_nothing (void)
|
| *
|
| *
|
| * Return value: (transfer full):
|
| - * Since: 1.0
|
| + * Since: 0.9.2
|
| **/
|
| hb_font_t *
|
| hb_ft_font_create (FT_Face ft_face,
|
| @@ -446,9 +531,7 @@ hb_ft_font_create (FT_Face ft_face,
|
| face = hb_ft_face_create (ft_face, destroy);
|
| font = hb_font_create (face);
|
| hb_face_destroy (face);
|
| - hb_font_set_funcs (font,
|
| - _hb_ft_get_font_funcs (),
|
| - ft_face, (hb_destroy_func_t) _do_nothing);
|
| + _hb_ft_font_set_funcs (font, ft_face, false);
|
| hb_font_set_scale (font,
|
| (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
|
| (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
|
| @@ -562,18 +645,6 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
| ft_face->generic.data = blob;
|
| ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
|
|
|
| - hb_font_set_funcs (font,
|
| - _hb_ft_get_font_funcs (),
|
| - ft_face,
|
| - (hb_destroy_func_t) FT_Done_Face);
|
| -}
|
| -
|
| -FT_Face
|
| -hb_ft_font_get_face (hb_font_t *font)
|
| -{
|
| - if (font->destroy == (hb_destroy_func_t) FT_Done_Face ||
|
| - font->destroy == (hb_destroy_func_t) _do_nothing)
|
| - return (FT_Face) font->user_data;
|
| -
|
| - return NULL;
|
| + _hb_ft_font_set_funcs (font, ft_face, true);
|
| + hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
|
| }
|
|
|