[truetype] Add bytecode support for GX variation fonts.

This commit implements undocumented (but confirmed) stuff from
Apple's old bytecode engine.

  GETVARIATION[], opcode 0x91
    This opcode pushes normalized variation coordinates for all axes
    onto the stack (in 2.14 format).  Coordinate of first axis gets
    pushed first.

  GETINFO[], selector bit 3
    If GX variation support is enabled, bit 10 of the result is set
    to 1.

* src/truetype/ttinterp.c: Include FT_MULTIPLE_MASTERS_H.
(opcode_name) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Updated.
(Ins_GETINFO) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle selector
bit 3, checking support for variation glyph hinting.
(Ins_GETVARIATION) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: New function
to implement opcode 0x91.
(TT_RunIns) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle opcode 0x91.
This commit is contained in:
Werner Lemberg 2016-07-16 18:46:28 +02:00
parent 32a320625e
commit e084360961
2 changed files with 103 additions and 2 deletions

View File

@ -1,3 +1,27 @@
2016-07-16 Werner Lemberg <wl@gnu.org>
[truetype] Add bytecode support for GX variation fonts.
This commit implements undocumented (but confirmed) stuff from
Apple's old bytecode engine.
GETVARIATION[], opcode 0x91
This opcode pushes normalized variation coordinates for all axes
onto the stack (in 2.14 format). Coordinate of first axis gets
pushed first.
GETINFO[], selector bit 3
If GX variation support is enabled, bit 10 of the result is set
to 1.
* src/truetype/ttinterp.c: Include FT_MULTIPLE_MASTERS_H.
(opcode_name) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Updated.
(Ins_GETINFO) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle selector
bit 3, checking support for variation glyph hinting.
(Ins_GETVARIATION) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: New function
to implement opcode 0x91.
(TT_RunIns) [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Handle opcode 0x91.
2016-07-16 Werner Lemberg <wl@gnu.org>
[truetype] Fix GETINFO bytecode instruction.

View File

@ -26,6 +26,7 @@
#include FT_TRIGONOMETRY_H
#include FT_SYSTEM_H
#include FT_TRUETYPE_DRIVER_H
#include FT_MULTIPLE_MASTERS_H
#include "ttinterp.h"
#include "tterrors.h"
@ -782,7 +783,7 @@
/* INS_$8F */ PACK( 0, 0 ),
/* INS_$90 */ PACK( 0, 0 ),
/* INS_$91 */ PACK( 0, 0 ),
/* GETVAR */ PACK( 0, 0 ), /* will be handled specially */
/* INS_$92 */ PACK( 0, 0 ),
/* INS_$93 */ PACK( 0, 0 ),
/* INS_$94 */ PACK( 0, 0 ),
@ -1065,7 +1066,11 @@
"7 INS_$8F",
"7 INS_$90",
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
"6 GETVAR",
#else
"7 INS_$91",
#endif
"7 INS_$92",
"7 INS_$93",
"7 INS_$94",
@ -7237,6 +7242,17 @@
if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched )
K |= 1 << 9;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
/********************************/
/* VARIATION GLYPH */
/* Selector Bit: 3 */
/* Return Bit(s): 10 */
/* */
/* XXX: UNDOCUMENTED! */
if ( (args[0] & 8 ) != 0 && exc->face->blend )
K |= 1 << 10;
#endif
/********************************/
/* BI-LEVEL HINTING AND */
/* GRAYSCALE RENDERING */
@ -7379,6 +7395,41 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
/*************************************************************************/
/* */
/* GETVARIATION[]: get normalized variation (blend) coordinates */
/* Opcode range: 0x24 */
/* Stack: --> f2.14... */
/* */
/* XXX: UNDOCUMENTED! There is no documentation from Apple for this */
/* bytecode instruction. */
/* */
static void
Ins_GETVARIATION( TT_ExecContext exc,
FT_Long* args )
{
FT_UInt num_axes = exc->face->blend->num_axis;
FT_Fixed* coords = exc->face->blend->normalizedcoords;
FT_UInt i;
if ( BOUNDS( num_axes, exc->stackSize + 1 - exc->top ) )
{
exc->error = FT_THROW( Stack_Overflow );
return;
}
for ( i = 0; i < num_axes; i++ )
args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */
}
#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
static void
Ins_UNKNOWN( TT_ExecContext exc )
{
@ -7565,7 +7616,21 @@
exc->args = 0;
}
exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
if ( exc->opcode == 0x91 )
{
/* this is very special: GETVARIATION returns */
/* a variable number of arguments */
/* it is the job of the application to `activate' GX handling, */
/* this is, calling any of the GX API functions on the current */
/* font to select a variation instance */
if ( exc->face->blend )
exc->new_top = exc->args + exc->face->blend->num_axis;
}
else
#endif
exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 );
/* `new_top' is the new top of the stack, after the instruction's */
/* execution. `top' will be set to `new_top' after the `switch' */
@ -8114,6 +8179,18 @@
Ins_UNKNOWN( exc );
break;
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
case 0x91:
/* it is the job of the application to `activate' GX handling, */
/* this is, calling any of the GX API functions on the current */
/* font to select a variation instance */
if ( exc->face->blend )
Ins_GETVARIATION( exc, args );
else
Ins_UNKNOWN( exc );
break;
#endif
default:
if ( opcode >= 0xE0 )
Ins_MIRP( exc, args );