From 37580053b491b69284988ed25cbbf6e884151eb0 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Thu, 16 May 2019 12:15:54 +0200 Subject: [truetype] Use 26.6 format for storing unscaled CVT values. If `CVAR' data is applied to variation fonts, fractional values are possible. * include/freetype/internal/tttypes.h (TT_FaceRec): Change type of `cvt' from `FT_Short' to `FT_Int32'. * src/truetype/ttgxvar.c (FT_fdot6ToFixed): New macro. (tt_face_vary_cvt): Use it to update code to 26.6 format. * src/truetype/ttobjs.c (tt_size_run_prep): Update code to 26.6 format. * src/truetype/ttpload.c (tt_face_load_cvt): Stora data in 26.6 format. --- ChangeLog | 19 +++++++++++++++++++ include/freetype/internal/tttypes.h | 8 +++++--- src/truetype/ttgxvar.c | 12 +++++++----- src/truetype/ttobjs.c | 9 ++++++--- src/truetype/ttpload.c | 6 +++--- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6aab65c50..52ceba81b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2019-05-16 Werner Lemberg + + [truetype] Use 26.6 format for storing unscaled CVT values. + + If `CVAR' data is applied to variation fonts, fractional values are + possible. + + * include/freetype/internal/tttypes.h (TT_FaceRec): Change type of + `cvt' from `FT_Short' to `FT_Int32'. + + * src/truetype/ttgxvar.c (FT_fdot6ToFixed): New macro. + (tt_face_vary_cvt): Use it to update code to 26.6 format. + + * src/truetype/ttobjs.c (tt_size_run_prep): Update code to 26.6 + format. + + * src/truetype/ttpload.c (tt_face_load_cvt): Stora data in 26.6 + format. + 2019-05-16 Werner Lemberg * src/truetype/ttgload.c (load_truetype_glyph): Init `unrounded'. diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 5e9f40ec3..cb03368b3 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1395,8 +1395,10 @@ FT_BEGIN_HEADER * * cvt :: * The face's original control value table. Coordinates are expressed - * in unscaled font units. Comes from the 'cvt~' table. Ignored for - * Type 2 fonts. + * in unscaled font units (in 26.6 format). Comes from the 'cvt~' + * table. Ignored for Type 2 fonts. + * + * If varied by the `CVAR' table, non-integer values are possible. * * interpreter :: * A pointer to the TrueType bytecode interpreters field is also used @@ -1633,7 +1635,7 @@ FT_BEGIN_HEADER /* the original, unscaled, control value table */ FT_ULong cvt_size; - FT_Short* cvt; + FT_Int32* cvt; /* A pointer to the bytecode interpreter to use. This is also */ /* used to hook the debugger for the `ttdebug' utility. */ diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index eab423951..00b91f653 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -72,6 +72,8 @@ ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) #define FT_intToFixed( i ) \ ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) +#define FT_fdot6ToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 10 ) ) #define FT_fixedToInt( x ) \ ( (FT_Short)( ( (FT_ULong)(x) + 0x8000U ) >> 16 ) ) #define FT_fixedToFdot6( x ) \ @@ -3367,9 +3369,9 @@ { FT_TRACE7(( " %d: %f -> %f\n", j, - ( FT_intToFixed( face->cvt[j] ) + + ( FT_fdot6ToFixed( face->cvt[j] ) + old_cvt_delta ) / 65536.0, - ( FT_intToFixed( face->cvt[j] ) + + ( FT_fdot6ToFixed( face->cvt[j] ) + cvt_deltas[j] ) / 65536.0 )); count++; } @@ -3409,9 +3411,9 @@ { FT_TRACE7(( " %d: %f -> %f\n", pindex, - ( FT_intToFixed( face->cvt[pindex] ) + + ( FT_fdot6ToFixed( face->cvt[pindex] ) + old_cvt_delta ) / 65536.0, - ( FT_intToFixed( face->cvt[pindex] ) + + ( FT_fdot6ToFixed( face->cvt[pindex] ) + cvt_deltas[pindex] ) / 65536.0 )); count++; } @@ -3436,7 +3438,7 @@ FT_TRACE5(( "\n" )); for ( i = 0; i < face->cvt_size; i++ ) - face->cvt[i] += FT_fixedToInt( cvt_deltas[i] ); + face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] ); FExit: FT_FRAME_EXIT(); diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 98a9fa476..d2279f1aa 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -939,15 +939,18 @@ FT_Error error; FT_UInt i; + /* unscaled CVT values are already stored in 26.6 format */ + FT_Fixed scale = size->ttmetrics.scale >> 6; + /* Scale the cvt values to the new ppem. */ /* By default, we use the y ppem value for scaling. */ FT_TRACE6(( "CVT values:\n" )); for ( i = 0; i < size->cvt_size; i++ ) { - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - FT_TRACE6(( " %3d: %d (%f)\n", - i, face->cvt[i], size->cvt[i] / 64.0 )); + size->cvt[i] = FT_MulFix( face->cvt[i], scale ); + FT_TRACE6(( " %3d: %f (%f)\n", + i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 )); } FT_TRACE6(( "\n" )); diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c index e7718bf9b..bc954c2db 100644 --- a/src/truetype/ttpload.c +++ b/src/truetype/ttpload.c @@ -352,12 +352,12 @@ goto Exit; { - FT_Short* cur = face->cvt; - FT_Short* limit = cur + face->cvt_size; + FT_Int32* cur = face->cvt; + FT_Int32* limit = cur + face->cvt_size; for ( ; cur < limit; cur++ ) - *cur = FT_GET_SHORT(); + *cur = FT_GET_SHORT() * 64; } FT_FRAME_EXIT(); -- cgit v1.2.1