[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.
This commit is contained in:
Werner Lemberg 2019-05-16 12:15:54 +02:00
parent ac335cd586
commit 37580053b4
5 changed files with 40 additions and 14 deletions

View File

@ -1,3 +1,22 @@
2019-05-16 Werner Lemberg <wl@gnu.org>
[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 <wl@gnu.org> 2019-05-16 Werner Lemberg <wl@gnu.org>
* src/truetype/ttgload.c (load_truetype_glyph): Init `unrounded'. * src/truetype/ttgload.c (load_truetype_glyph): Init `unrounded'.

View File

@ -1395,8 +1395,10 @@ FT_BEGIN_HEADER
* *
* cvt :: * cvt ::
* The face's original control value table. Coordinates are expressed * The face's original control value table. Coordinates are expressed
* in unscaled font units. Comes from the 'cvt~' table. Ignored for * in unscaled font units (in 26.6 format). Comes from the 'cvt~'
* Type 2 fonts. * table. Ignored for Type 2 fonts.
*
* If varied by the `CVAR' table, non-integer values are possible.
* *
* interpreter :: * interpreter ::
* A pointer to the TrueType bytecode interpreters field is also used * A pointer to the TrueType bytecode interpreters field is also used
@ -1633,7 +1635,7 @@ FT_BEGIN_HEADER
/* the original, unscaled, control value table */ /* the original, unscaled, control value table */
FT_ULong cvt_size; FT_ULong cvt_size;
FT_Short* cvt; FT_Int32* cvt;
/* A pointer to the bytecode interpreter to use. This is also */ /* A pointer to the bytecode interpreter to use. This is also */
/* used to hook the debugger for the `ttdebug' utility. */ /* used to hook the debugger for the `ttdebug' utility. */

View File

@ -72,6 +72,8 @@
( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
#define FT_intToFixed( i ) \ #define FT_intToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) ( (FT_Fixed)( (FT_ULong)(i) << 16 ) )
#define FT_fdot6ToFixed( i ) \
( (FT_Fixed)( (FT_ULong)(i) << 10 ) )
#define FT_fixedToInt( x ) \ #define FT_fixedToInt( x ) \
( (FT_Short)( ( (FT_ULong)(x) + 0x8000U ) >> 16 ) ) ( (FT_Short)( ( (FT_ULong)(x) + 0x8000U ) >> 16 ) )
#define FT_fixedToFdot6( x ) \ #define FT_fixedToFdot6( x ) \
@ -3367,9 +3369,9 @@
{ {
FT_TRACE7(( " %d: %f -> %f\n", FT_TRACE7(( " %d: %f -> %f\n",
j, j,
( FT_intToFixed( face->cvt[j] ) + ( FT_fdot6ToFixed( face->cvt[j] ) +
old_cvt_delta ) / 65536.0, old_cvt_delta ) / 65536.0,
( FT_intToFixed( face->cvt[j] ) + ( FT_fdot6ToFixed( face->cvt[j] ) +
cvt_deltas[j] ) / 65536.0 )); cvt_deltas[j] ) / 65536.0 ));
count++; count++;
} }
@ -3409,9 +3411,9 @@
{ {
FT_TRACE7(( " %d: %f -> %f\n", FT_TRACE7(( " %d: %f -> %f\n",
pindex, pindex,
( FT_intToFixed( face->cvt[pindex] ) + ( FT_fdot6ToFixed( face->cvt[pindex] ) +
old_cvt_delta ) / 65536.0, old_cvt_delta ) / 65536.0,
( FT_intToFixed( face->cvt[pindex] ) + ( FT_fdot6ToFixed( face->cvt[pindex] ) +
cvt_deltas[pindex] ) / 65536.0 )); cvt_deltas[pindex] ) / 65536.0 ));
count++; count++;
} }
@ -3436,7 +3438,7 @@
FT_TRACE5(( "\n" )); FT_TRACE5(( "\n" ));
for ( i = 0; i < face->cvt_size; i++ ) 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: FExit:
FT_FRAME_EXIT(); FT_FRAME_EXIT();

View File

@ -939,15 +939,18 @@
FT_Error error; FT_Error error;
FT_UInt i; 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. */ /* Scale the cvt values to the new ppem. */
/* By default, we use the y ppem value for scaling. */ /* By default, we use the y ppem value for scaling. */
FT_TRACE6(( "CVT values:\n" )); FT_TRACE6(( "CVT values:\n" ));
for ( i = 0; i < size->cvt_size; i++ ) for ( i = 0; i < size->cvt_size; i++ )
{ {
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); size->cvt[i] = FT_MulFix( face->cvt[i], scale );
FT_TRACE6(( " %3d: %d (%f)\n", FT_TRACE6(( " %3d: %f (%f)\n",
i, face->cvt[i], size->cvt[i] / 64.0 )); i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 ));
} }
FT_TRACE6(( "\n" )); FT_TRACE6(( "\n" ));

View File

@ -352,12 +352,12 @@
goto Exit; goto Exit;
{ {
FT_Short* cur = face->cvt; FT_Int32* cur = face->cvt;
FT_Short* limit = cur + face->cvt_size; FT_Int32* limit = cur + face->cvt_size;
for ( ; cur < limit; cur++ ) for ( ; cur < limit; cur++ )
*cur = FT_GET_SHORT(); *cur = FT_GET_SHORT() * 64;
} }
FT_FRAME_EXIT(); FT_FRAME_EXIT();