From e0843609616c5f12b3d1697499c839d3e89f96fb Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 16 Jul 2016 18:46:28 +0200 Subject: [PATCH] [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. --- ChangeLog | 24 ++++++++++++ src/truetype/ttinterp.c | 81 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f45e071a..59541b4bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2016-07-16 Werner Lemberg + + [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 [truetype] Fix GETINFO bytecode instruction. diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c index 1ab01ff96..3851b7a2f 100644 --- a/src/truetype/ttinterp.c +++ b/src/truetype/ttinterp.c @@ -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 );