From 4fe3b55d0b3b4046b51b29101f9597c50e1913d1 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Fri, 11 Dec 2015 08:08:48 +0100 Subject: [PATCH] [autofit] Restore OpenType feature check. This was removed while rewriting the HarfBuzz interface. * src/autofit/afglobal.h (AF_FaceGlobalsRec): Add `hb_buf' field to hold internal HarfBuzz buffer, needed for feature comparison. * src/autofit/afglobal.c (af_face_globals_new, af_face_globals_free): Initialize and destroy `hb_buf'. * src/autofit/afshaper.c (af_shaper_get_cluster): Compare character (cluster) with and without applied feature. * src/autofit/aflatin.c (af_latin_metrics_init_blues): Fix tracing message. --- ChangeLog | 18 ++++++++++++++++++ src/autofit/afglobal.c | 4 ++++ src/autofit/afglobal.h | 1 + src/autofit/aflatin.c | 6 ++++++ src/autofit/afshaper.c | 42 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5cda52d32..3ab437a63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2015-12-10 Werner Lemberg + + [autofit] Restore OpenType feature check. + + This was removed while rewriting the HarfBuzz interface. + + * src/autofit/afglobal.h (AF_FaceGlobalsRec): Add `hb_buf' field to + hold internal HarfBuzz buffer, needed for feature comparison. + + * src/autofit/afglobal.c (af_face_globals_new, + af_face_globals_free): Initialize and destroy `hb_buf'. + + * src/autofit/afshaper.c (af_shaper_get_cluster): Compare character + (cluster) with and without applied feature. + + * src/autofit/aflatin.c (af_latin_metrics_init_blues): Fix tracing + message. + 2015-12-10 Werner Lemberg [autofit] Remove redundant code. diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 207b41cb7..322335811 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -364,6 +364,7 @@ #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ globals->hb_font = hb_ft_font_create( face, NULL ); + globals->hb_buf = hb_buffer_create(); #endif error = af_face_globals_compute_style_coverage( globals ); @@ -410,6 +411,9 @@ #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ hb_font_destroy( globals->hb_font ); globals->hb_font = NULL; + + hb_buffer_destroy( globals->hb_buf ); + globals->hb_buf = NULL; #endif globals->glyph_count = 0; diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index c1170d4d6..5b4e4393c 100644 --- a/src/autofit/afglobal.h +++ b/src/autofit/afglobal.h @@ -110,6 +110,7 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ hb_font_t* hb_font; + hb_buffer_t* hb_buf; /* for feature comparison */ #endif /* per-face auto-hinter properties */ diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index 3358c9900..fa285f77d 100644 --- a/src/autofit/aflatin.c +++ b/src/autofit/aflatin.c @@ -396,6 +396,12 @@ p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( !num_idx ) + { + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; + } + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) best_y_extremum = FT_INT_MIN; else diff --git a/src/autofit/afshaper.c b/src/autofit/afshaper.c index e72fe495e..6ba919006 100644 --- a/src/autofit/afshaper.c +++ b/src/autofit/afshaper.c @@ -466,7 +466,7 @@ while ( *p == ' ' ) p++; - /* count characters up to next space (or end of buffer) */ + /* count bytes up to next space (or end of buffer) */ q = p; while ( !( *q == ' ' || *q == '\0' ) ) GET_UTF8_CHAR( dummy, q ); @@ -483,6 +483,46 @@ /* glyph indices, possibly applying a feature */ hb_shape( font, buf, feature, feature ? 1 : 0 ); + if ( feature ) + { + hb_buffer_t* hb_buf = metrics->globals->hb_buf; + + unsigned int gcount; + hb_glyph_info_t* ginfo; + + unsigned int hb_gcount; + hb_glyph_info_t* hb_ginfo; + + + /* we have to check whether applying a feature does actually change */ + /* glyph indices; otherwise the affected glyph or glyphs aren't */ + /* available at all in the feature */ + + hb_buffer_clear_contents( hb_buf ); + hb_buffer_add_utf8( hb_buf, p, len, 0, len ); + hb_buffer_guess_segment_properties( hb_buf ); + hb_shape( font, hb_buf, NULL, 0 ); + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount ); + + if ( gcount == hb_gcount ) + { + unsigned int i; + + + for (i = 0; i < gcount; i++ ) + if ( ginfo[i].codepoint != hb_ginfo[i].codepoint ) + break; + + if ( i == gcount ) + { + /* both buffers have identical glyph indices */ + hb_buffer_clear_contents( buf ); + } + } + } + *count = hb_buffer_get_length( buf ); #ifdef FT_DEBUG_LEVEL_TRACE