[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>
* src/truetype/ttgload.c (load_truetype_glyph): Init `unrounded'.

View File

@ -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. */

View File

@ -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();

View File

@ -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" ));

View File

@ -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();