diff --git a/ChangeLog b/ChangeLog index 05db1d150..886883868 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2017-04-22 Werner Lemberg + + [truetype] Do linear scaling for FT_LOAD_NO_HINTING (#50470). + + * src/truetype/ttobs.h (TT_SizeRec): Add field `hinted_metrics' to + hold hinted metrics. + Make `metrics' a pointer so that `tt_glyph_load' can easily switch + between metrics. + + * src/truetype/ttdriver.c (tt_size_request): Updated. + (tt_glyph_load): Use top-level metrics if FT_LOAD_NO_HINTING is + used. + + * src/truetype/ttgload.c (TT_Hint_Glyph, TT_Process_Simple_Glyph, + TT_Process_Composite_Component, load_truetype_glyph, + compute_glyph_metrics, TT_Load_Glyph): Updated. + + * src/truetype/ttinterp.c (TT_Load_Context): Updated. + + * src/truetype/ttobjs.c (tt_size_reset): Updated. + + * src/truetype/ttsubpix.c (sph_set_tweaks): Updated. + 2017-04-22 Werner Lemberg Add new `slight' auto-hinting mode. diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 9bf0f84fc..c9f682e5e 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -361,9 +361,10 @@ #ifdef TT_USE_BYTECODE_INTERPRETER /* for the `MPS' bytecode instruction we need the point size */ { - FT_UInt resolution = ttsize->metrics.x_ppem > ttsize->metrics.y_ppem - ? req->horiResolution - : req->vertResolution; + FT_UInt resolution = + ttsize->metrics->x_ppem > ttsize->metrics->y_ppem + ? req->horiResolution + : req->vertResolution; /* if we don't have a resolution value, assume 72dpi */ @@ -457,6 +458,11 @@ load_flags |= FT_LOAD_NO_HINTING; } + /* use hinted metrics only if we load a glyph with hinting */ + size->metrics = ( load_flags & FT_LOAD_NO_HINTING ) + ? &ttsize->metrics + : &size->hinted_metrics; + /* now load the glyph outline if necessary */ error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 8962be560..c5d548f0b 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -778,8 +778,8 @@ } else { - loader->exec->metrics.x_scale = loader->size->metrics.x_scale; - loader->exec->metrics.y_scale = loader->size->metrics.y_scale; + loader->exec->metrics.x_scale = loader->size->metrics->x_scale; + loader->exec->metrics.y_scale = loader->size->metrics->y_scale; } #endif @@ -926,7 +926,7 @@ TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics->x_ppem; FT_String* style = face->root.style_name; FT_UInt x_scale_factor = 1000; #endif @@ -955,9 +955,9 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || x_scale_factor != 1000 ) { - x_scale = FT_MulDiv( loader->size->metrics.x_scale, + x_scale = FT_MulDiv( loader->size->metrics->x_scale, (FT_Long)x_scale_factor, 1000 ); - y_scale = loader->size->metrics.y_scale; + y_scale = loader->size->metrics->y_scale; /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ @@ -977,8 +977,8 @@ /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; + x_scale = loader->size->metrics->x_scale; + y_scale = loader->size->metrics->y_scale; do_scale = TRUE; } @@ -1136,8 +1136,8 @@ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - FT_Fixed x_scale = loader->size->metrics.x_scale; - FT_Fixed y_scale = loader->size->metrics.y_scale; + FT_Fixed x_scale = loader->size->metrics->x_scale; + FT_Fixed y_scale = loader->size->metrics->y_scale; x = FT_MulFix( x, x_scale ); @@ -1470,8 +1470,8 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; + x_scale = loader->size->metrics->x_scale; + y_scale = loader->size->metrics->y_scale; } else { @@ -2038,7 +2038,7 @@ y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - y_scale = size->metrics.y_scale; + y_scale = size->metrics->y_scale; if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) FT_Outline_Get_CBox( &glyph->outline, &bbox ); @@ -2070,7 +2070,7 @@ widthp = tt_face_get_device_metrics( face, - size->metrics.x_ppem, + size->metrics->x_ppem, glyph_index ); #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY @@ -2637,11 +2637,11 @@ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance, - size->metrics.x_scale ); + size->metrics->x_scale ); if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance ) glyph->metrics.vertAdvance = FT_MulFix( glyph->linearVertAdvance, - size->metrics.y_scale ); + size->metrics->y_scale ); } return FT_Err_Ok; @@ -2737,7 +2737,7 @@ /* TrueType glyphs at all sizes using the bytecode interpreter. */ /* */ if ( !( load_flags & FT_LOAD_NO_SCALE ) && - size->metrics.y_ppem < 24 ) + size->metrics->y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; Exit: diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index fed377d97..0c51f756d 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -402,7 +402,7 @@ exec->IDefs = size->instruction_defs; exec->pointSize = size->point_size; exec->tt_metrics = size->ttmetrics; - exec->metrics = size->metrics; + exec->metrics = *size->metrics; exec->maxFunc = size->max_func; exec->maxIns = size->max_ins; diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 27e0931a3..64011e86e 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -1220,7 +1220,7 @@ size->ttmetrics.valid = FALSE; - size_metrics = &size->metrics; + size_metrics = &size->hinted_metrics; /* copy the result from base layer */ *size_metrics = size->root.metrics; @@ -1280,6 +1280,8 @@ size->ttmetrics.y_ratio = 0x10000L; } + size->metrics = size_metrics; + #ifdef TT_USE_BYTECODE_INTERPRETER size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h index 65929e592..cdacee75e 100644 --- a/src/truetype/ttobjs.h +++ b/src/truetype/ttobjs.h @@ -278,7 +278,8 @@ FT_BEGIN_HEADER /* we have our own copy of metrics so that we can modify */ /* it without affecting auto-hinting (when used) */ - FT_Size_Metrics metrics; + FT_Size_Metrics* metrics; /* for the current rendering mode */ + FT_Size_Metrics hinted_metrics; /* for the hinted rendering mode */ TT_Size_Metrics ttmetrics; diff --git a/src/truetype/ttsubpix.c b/src/truetype/ttsubpix.c index f8502d2f7..1c8cf0110 100644 --- a/src/truetype/ttsubpix.c +++ b/src/truetype/ttsubpix.c @@ -906,7 +906,7 @@ { TT_Face face = loader->face; FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics->x_ppem; FT_String* style = face->root.style_name;