From 73cc8330ede27c73f39706bae2e403b40df1ef63 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 1 Jan 2014 07:10:36 +0100 Subject: [PATCH] [autofit] Implement and use `af_get_char_index' with HarfBuzz. * src/autofit/hbshim.c (COVERAGE) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Redefine to construct HarfBuzz features. (af_get_char_index) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Rewritten. * src/autofit/aflatin.c (af_latin_metrics_init_blues): Use `y_offset' to adjust `best_y'. --- ChangeLog | 13 ++++++- src/autofit/aflatin.c | 8 ++++- src/autofit/hbshim.c | 84 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2580884ff..a6f33909d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2014-01-01 Werner Lemberg + + [autofit] Implement and use `af_get_char_index' with HarfBuzz. + + * src/autofit/hbshim.c (COVERAGE) [FT_CONFIG_OPTION_USE_HARFBUZZ]: + Redefine to construct HarfBuzz features. + (af_get_char_index) [FT_CONFIG_OPTION_USE_HARFBUZZ]: Rewritten. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Use + `y_offset' to adjust `best_y'. + 2013-12-31 Werner Lemberg [autofit] s/AF_STYLE_...._DEFAULT/AF_STYLE_...._DFLT/i. @@ -2595,7 +2606,7 @@ ---------------------------------------------------------------------------- -Copyright 2013 by +Copyright 2013-2014 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, modified, diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index fc1d443fc..8841d9482 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2013 by */ +/* Copyright 2003-2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -620,6 +620,12 @@ } } + /* for computing blue zones, we add the y offset as returned */ + /* by the currently used OpenType feature -- for example, */ + /* superscript glyphs might be identical to subscript glyphs */ + /* with a vertical shift */ + best_y += y_offset; + FT_TRACE5(( " U+%04lX: best_y = %5ld", ch, best_y )); /* now set the `round' flag depending on the segment's kind: */ diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c index d280e5556..7dae08fbc 100644 --- a/src/autofit/hbshim.c +++ b/src/autofit/hbshim.c @@ -4,7 +4,7 @@ /* */ /* HarfBuzz interface for accessing OpenType features (body). */ /* */ -/* Copyright 2013 by */ +/* Copyright 2013, 2014 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -230,22 +230,96 @@ } + /* construct HarfBuzz features */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_feature_t name ## _feature[] = \ + { \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + 1, 0, -1 \ + } \ + }; + + +#include "afcover.h" + + + /* define mapping between HarfBuzz features and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _feature, + + + static const hb_feature_t* features[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + FT_Error af_get_char_index( AF_StyleMetrics metrics, FT_ULong charcode, FT_ULong *codepoint, FT_Long *y_offset ) { - FT_Face face; + AF_StyleClass style_class; + + const hb_feature_t* feature; if ( !metrics ) return FT_THROW( Invalid_Argument ); - face = metrics->globals->face; + style_class = metrics->style_class; - *codepoint = FT_Get_Char_Index( face, charcode ); - *y_offset = 0; + feature = features[style_class->coverage]; + + if ( feature ) + { + hb_font_t* font = metrics->globals->hb_font; + hb_buffer_t* buf = hb_buffer_create(); + + uint32_t c = (uint32_t)charcode; + + hb_glyph_info_t* ginfo; + hb_glyph_position_t* gpos; + unsigned int gcount; + + + /* XXX: is this sufficient for a single character of any script? */ + hb_buffer_set_direction( buf, HB_DIRECTION_LTR ); + hb_buffer_set_script( buf, scripts[style_class->script] ); + + /* we add one character to `buf' ... */ + hb_buffer_add_utf32( buf, &c, 1, 0, 1 ); + + /* ... and apply one feature */ + hb_shape( font, buf, feature, 1 ); + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + gpos = hb_buffer_get_glyph_positions( buf, &gcount ); + + *codepoint = ginfo[0].codepoint; + *y_offset = gpos[0].y_offset; + + hb_buffer_destroy( buf ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( gcount > 1 ) + FT_TRACE1(( "af_get_char_index:" + " input character mapped to multiple glyphs\n" )); +#endif + } + else + { + *codepoint = FT_Get_Char_Index( metrics->globals->face, charcode ); + *y_offset = 0; + } return FT_Err_Ok; }