Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* $Id: Interpreter.java,v 1.1.1.1 2004-12-05 23:15:05 davidsch Exp $
*
* Typecast - The Font Development Environment
*
* Copyright (c) 2004 David Schweinsberg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jogamp.graph.font.typecast.tt.engine;
import jogamp.graph.font.typecast.ot.Mnemonic;
import jogamp.graph.font.typecast.ot.Point;
/**
* The interpreter shall remain ignorant of the table structure - the table
* data will be extracted by supporting classes, whether it be the Parser
* or some other.
* @author David Schweinsberg
* @version $Id: Interpreter.java,v 1.1.1.1 2004-12-05 23:15:05 davidsch Exp $
*/
public class Interpreter {
private Parser parser = null;
private final GraphicsState gs = new GraphicsState();
private final Point[][] zone = new Point[2][];
private int[] stack = null;
private int[] store = null;
private final int[] cvt = new int[256];
private int[] functionMap = null;
private int stackIndex = 0;
private boolean inFuncDef = false;
public Interpreter(final int stackMax, final int storeMax, final int funcMax) {
zone[0] = new Point[256];
zone[1] = new Point[256];
stack = new int[stackMax];
store = new int[storeMax];
functionMap = new int[funcMax];
}
/**
* ABSolute value
*/
private void _abs() {
final int n = pop();
if (n >= 0) {
push(n);
} else {
push(-n);
}
}
/**
* ADD
*/
private void _add() {
final int n1 = pop();
final int n2 = pop();
push(n2 + n1);
}
private void _alignpts() {
pop();
pop();
}
/**
*
*
* USES: loop
*/
private void _alignrp() {
while (gs.loop-- > 0) {
pop();
}
gs.loop = 1;
}
/**
* logical AND
*/
private void _and() {
final int e2 = pop();
final int e1 = pop();
push(((e1 != 0) && (e2 != 0)) ? 1 : 0);
}
/**
* CALL function
*/
private void _call() {
execute(functionMap[pop()]);
}
/**
* CEILING
*/
private void _ceiling() {
final int n = pop();
if (n >= 0) {
push((n & 0xffc0) + (((n & 0x3f) != 0) ? 0x40 : 0));
} else {
push(n & 0xffc0);
}
}
/**
* Copy the INDEXed element to the top of the stack
*/
private void _cindex() {
push(stack[stackIndex - pop()]);
}
/**
* CLEAR the entire stack
*/
private void _clear() {
stackIndex = 0;
}
private void _debug() {
pop();
}
/**
* DELTA exception C1
*/
private void _deltac1() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* DELTA exception C2
*/
private void _deltac2() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* DELTA exception C3
*/
private void _deltac3() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* DELTA exception P1
*/
private void _deltap1() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* DELTA exception P2
*/
private void _deltap2() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* DELTA exception P3
*/
private void _deltap3() {
final int n = pop();
for (int i = 0; i < n; i++) {
pop(); // pn
pop(); // argn
}
}
/**
* Returns the DEPTH of the stack
*/
private void _depth() {
push(stackIndex);
}
/**
* DIVide
*/
private void _div() {
final int n1 = pop();
final int n2 = pop();
push((n2 / n1) >> 6);
}
/**
* DUPlicate top stack element
*/
private void _dup() {
final int n = pop();
push(n);
push(n);
}
/**
* ELSE
*/
private int _else(final int instructionIndex) {
return parser.handleElse(instructionIndex);
}
/**
* EQual
*/
private void _eq() {
final int e2 = pop();
final int e1 = pop();
push((e1 == e2) ? 1 : 0);
}
private void _even() {
pop();
push(0);
}
/**
* Function DEFinition
*/
private void _fdef(final int instructionIndex) {
functionMap[pop()] = instructionIndex;
inFuncDef = true;
}
/**
* Set the auto_FLIP boolean to OFF
*/
private void _flipoff() {
gs.auto_flip = false;
}
/**
* Set the auto_FLIP boolean to ON
*/
private void _flipon() {
gs.auto_flip = true;
}
/**
* FLIP PoinT
*
* USES: loop
*/
private void _flippt() {
while(gs.loop-- > 0) {
final int index = pop();
zone[gs.zp0][index].onCurve = !zone[gs.zp0][index].onCurve;
}
gs.loop = 1;
}
/**
* FLIP RanGe OFF
*/
private void _fliprgoff() {
final int end = pop();
final int start = pop();
for (int i = start; i <= end; i++) {
zone[1][i].onCurve = false;
}
}
/**
* FLIP RanGe ON
*/
private void _fliprgon() {
final int end = pop();
final int start = pop();
for (int i = start; i <= end; i++) {
zone[1][i].onCurve = true;
}
}
/**
* FLOOR
*/
private void _floor() {
final int n = pop();
if (n >= 0) {
push(n & 0xffc0);
} else {
push((n & 0xffc0) - (((n & 0x3f) != 0) ? 0x40 : 0));
}
}
private void _gc(final short param) {
pop();
push(0);
}
private void _getinfo() {
pop();
push(0);
}
/**
* Get Freedom_Vector
*/
private void _gfv() {
push(gs.freedom_vector[0]);
push(gs.freedom_vector[1]);
}
/**
* Get Projection_Vector
*/
private void _gpv() {
push(gs.projection_vector[0]);
push(gs.projection_vector[1]);
}
/**
* Greater Than
*/
private void _gt() {
final int e2 = pop();
final int e1 = pop();
push((e1 > e2) ? 1 : 0);
}
/**
* Greater Than or EQual
*/
private void _gteq() {
final int e2 = pop();
final int e1 = pop();
push((e1 >= e2) ? 1 : 0);
}
/**
* Instruction DEFinition
*/
private void _idef() {
pop();
inFuncDef = true;
}
/**
* IF test
*/
private int _if(final int instructionIndex) {
return parser.handleIf(pop() != 0, instructionIndex);
}
/**
* INSTruction Execution ConTRol
*
* INSTCTRL[]
*
* Code Range
* 0x8E
*
* Pops
* s: selector flag (int32)
* value: USHORT (padded to 32 bits) used to set value of instruction_control.
*
* Pushes
* -
*
* Sets
* instruction_control
*
* Sets the instruction control state variable making it possible to turn on or off
* the execution of instructions and to regulate use of parameters set in the CVT
* program. INSTCTRL[ ] can only be executed in the CVT program.
*
* This instruction clears and sets various control flags in the rasterizer. The
* selector flag determines valid values for the value argument. The value determines
* the new setting of the raterizer control flag. In version 1.0 there are only two
* flags in use:
*
* Selector flag 1 is used to inhibit grid-fitting. If s=1, valid values for the
* value argument are 0 (FALSE) and 1 (TRUE). If the value argument is set to TRUE
* (v=1), any instructions associated with glyphs will not be executed. For example,
* to inhibit grid-fitting when a glyph is being rotated or stretched, use the
* following sequence on the preprogram:
*
* PUSHB[000] 6 ; ask GETINFO to check for stretching or rotation
* GETINFO[] ; will push TRUE if glyph is stretched or rotated
* IF[] ; tests value at top of stack
* PUSHB[000] 1 ; value for INSTCTRL
* PUSHB[000] 1 ; selector for INSTCTRL
* INSTRCTRL[] ; based on selector and value will turn grid-fitting off
* EIF[]
*
* Selector flag 2 is used to establish that any parameters set in the CVT program
* should be ignored when instructions associated with glyphs are executed. These
* include, for example, the values for scantype and the CVT cut-in. If s=1, valid
* values for the value argument are 0 (FALSE) and 2 (TRUE). If the value argument is
* set to TRUE (v=2), the default values of those parameters will be used regardless
* of any changes that may have been made in those values by the preprogram. If the
* value argument is set to FALSE (v=0), parameter values changed by the CVT program
* will be used in glyph instructions.
*/
private void _instctrl() {
final int s = pop();
final int v = pop();
if (s == 1) {
gs.instruction_control |= v;
} else if (s == 2) {
gs.instruction_control |= v;
}
}
private void _ip() {
pop();
}
private void _isect() {
pop();
pop();
pop();
pop();
pop();
}
private void _iup(final short param) {
}
/**
* JuMP Relative
*/
private int _jmpr(final int instructionIndex) {
return instructionIndex + ( pop() - 1 );
}
/**
* Jump Relative On False
*/
private int _jrof(int instructionIndex) {
final boolean test = pop() != 0;
final int offset = pop();
if (!test) {
instructionIndex += offset - 1;
}
return instructionIndex;
}
/**
* Jump Relative On True
*/
private int _jrot(int instructionIndex) {
final boolean test = pop() != 0;
final int offset = pop();
if (test) {
instructionIndex += offset - 1;
}
return instructionIndex;
}
/**
* LOOP and CALL function
*/
private void _loopcall() {
/* final int index = */ pop();
final int count = pop();
for (int i = 0; i < count; i++) {
execute(functionMap[i]);
}
}
/**
* Less Than
*/
private void _lt() {
final int e2 = pop();
final int e1 = pop();
push((e1 < e2) ? 1 : 0);
}
/**
* Less Than or EQual
*/
private void _lteq() {
final int e2 = pop();
final int e1 = pop();
push((e1 <= e2) ? 1 : 0);
}
/**
* MAXimum of top two stack elements
*/
private void _max() {
final int n1 = pop();
final int n2 = pop();
push((n1 > n2) ? n1 : n2);
}
private void _md(final short param) {
pop();
pop();
push(0);
}
private void _mdap(final short param) {
pop();
}
private void _mdrp(final short param) {
pop();
}
private void _miap(final short param) {
pop();
pop();
}
/**
* MINimum of top two stack elements
*/
private void _min() {
final int n1 = pop();
final int n2 = pop();
push((n1 < n2) ? n1 : n2);
}
/**
* Move the INDEXed element to the top of the stack
*/
private void _mindex() {
// Move the indexed element to stackIndex, and shift the others down
final int k = pop();
final int e = stack[stackIndex - k];
for (int i = stackIndex - k; i < stackIndex - 1; i++) {
stack[i] = stack[i+1];
}
stack[stackIndex - 1] = e;
}
private void _mirp(final short param) {
pop();
pop();
}
private void _mppem() {
push(0);
}
private void _mps() {
push(0);
}
private void _msirp(final short param) {
pop();
pop();
}
/**
* MULtiply
*/
private void _mul() {
final int n1 = pop();
final int n2 = pop();
push((n1 * n2) >> 6);
}
/**
* NEGate
*/
private void _neg() {
push(-pop());
}
/**
* Not EQual
*/
private void _neq() {
final int e2 = pop();
final int e1 = pop();
push((e1 != e2) ? 1 : 0);
}
/**
* logical NOT
*/
private void _not() {
push((pop() != 0) ? 0 : 1);
}
private void _nround(final short param) {
pop();
push(0);
}
private void _odd() {
pop();
push(0);
}
/**
* logical OR
*/
private void _or() {
final int e2 = pop();
final int e1 = pop();
push(((e1 != 0) || (e2 != 0)) ? 1 : 0);
}
/**
* PUSH N Bytes
* PUSH N Words
* PUSH Bytes
* PUSH Words
*/
private void _push(final int[] data) {
for (int j = 0; j < data.length; j++) {
push(data[j]);
}
}
/**
* Read Control Value Table
*/
private void _rcvt() {
push(cvt[pop()]);
}
/**
* Round Down To Grid
*/
private void _rdtg() {
gs.round_state = 3;
}
/**
* Round OFF
*/
private void _roff() {
gs.round_state = 5;
}
/**
* ROLL the top three stack elements
*/
private void _roll() {
final int a = pop();
final int b = pop();
final int c = pop();
push(b);
push(a);
push(c);
}
private void _round(final short param) {
pop();
push(0);
}
/**
* Read Store
*/
private void _rs() {
push(store[pop()]);
}
/**
* Round To Double Grid
*/
private void _rtdg() {
gs.round_state = 2;
}
/**
* Round To Grid
*/
private void _rtg() {
gs.round_state = 1;
}
/**
* Round To Half Grid
*/
private void _rthg() {
gs.round_state = 0;
}
/**
* Round Up To Grid
*/
private void _rutg() {
gs.round_state = 4;
}
private void _s45round() {
pop();
}
/**
* SCAN conversion ConTRoL
*
* SCANCTRL[ ]
*
* Code Range
* 0x85
*
* Pops
* n: flags indicating when to turn on dropout control mode (16 bit word padded
* to 32 bits)
*
* Pushes
* -
*
* Sets
* scan_control
*
* SCANCTRL is used to set the value of the Graphics State variable scan_control
* which in turn determines whether the scan converter will activate dropout
* control for this glyph. Use of the dropout control mode is determined by three
* conditions:
*
* Is the glyph rotated?
*
* Is the glyph stretched?
*
* Is the current setting for ppem less than a specified threshold?
*
* The interpreter pops a word from the stack and looks at the lower 16 bits.
*
* Bits 0-7 represent the threshold value for ppem. A value of FF in bits 0-7
* means invoke dropout_control for all sizes. A value of 0 in bits 0-7 means
* never invoke dropout_control.
*
* Bits 8-13 are used to turn on dropout_control in cases where the specified
* conditions are met. Bits 8, 9 and 10 are used to turn on the dropout_control
* mode (assuming other conditions do not block it). Bits 11, 12, and 13 are
* used to turn off the dropout mode unless other conditions force it. Bits 14
* and 15 are reserved for future use.
*
* Bit Meaning if set
* --- --------------
* 8 Set dropout_control to TRUE if other conditions do not block and ppem
* is less than or equal to the threshold value.
*
* 9 Set dropout_control to TRUE if other conditions do not block and the
* glyph is rotated.
*
* 10 Set dropout_control to TRUE if other conditions do not block and the
* glyph is stretched.
*
* 11 Set dropout_control to FALSE unless ppem is less than or equal to the
* threshold value.
*
* 12 Set dropout_control to FALSE unless the glyph is rotated.
*
* 13 Set dropout_control to FALSE unless the glyph is stretched.
*
* 14 Reserved for future use.
*
* 15 Reserved for future use.
*
* For example
* 0x0000 No dropout control is invoked
* 0x01FF Always do dropout control
* 0x0A10 Do dropout control if the glyph is rotated and has less than 16
* pixels per-em
*
* The scan converter can operate in either a "normal" mode or in a "fix dropout"
* mode depending on the value of a set of enabling and disabling flags.
*/
private void _scanctrl() {
gs.scan_control = pop();
}
/**
* SCANTYPE
*
* SCANTYPE[]
*
* Code Range
* 0x8D
*
* Pops
* n: 16 bit integer
*
* Pushes
* -
*
* Sets
* scan_control
*
* Pops a 16-bit integer whose value is used to determine which rules the scan
* converter will use. If the value of the argument is 0, the fast scan converter
* will be used. If the value of the integer is 1 or 2, simple dropout control will
* be used. If the value of the integer is 4 or 5, smart dropout control will be
* used. More specifically,
*
* if n=0 rules 1, 2, and 3 are invoked (simple dropout control scan conversion
* including stubs)
*
* if n=1 rules 1, 2, and 4 are invoked (simple dropout control scan conversion
* excluding stubs)
*
* if n=2 rules 1 and 2 only are invoked (fast scan conversion; dropout control
* turned off)
*
* if n=3 same as n = 2
*
* if n = 4 rules 1, 2, and 5 are invoked (smart dropout control scan conversion
* including stubs)
*
* if n = 5 rules 1, 2, and 6 are invoked (smart dropout control scan conversion
* excluding stubs)
*
* if n = 6 same as n = 2
*
* if n = 7 same as n = 2
*
* The scan conversion rules are shown here:
*
* Rule 1
* If a pixel's center falls within the glyph outline, that pixel is turned on.
*
* Rule 2
* If a contour falls exactly on a pixel's center, that pixel is turned on.
*
* Rule 3
* If a scan line between two adjacent pixel centers (either vertical or
* horizontal) is intersected by both an on-Transition contour and an off-Transition
* contour and neither of the pixels was already turned on by rules 1 and 2, turn on
* the left-most pixel (horizontal scan line) or the bottom-most pixel (vertical scan
* line). This is "Simple" dropout control.
*
* Rule 4
* Apply Rule 3 only if the two contours continue to intersect other scan lines in
* both directions. That is, do not turn on pixels for 'stubs.' The scanline segments
* that form a square with the intersected scan line segment are examined to verify
* that they are intersected by two contours. It is possible that these could be
* different contours than the ones intersecting the dropout scan line segment. This
* is very unlikely but may have to be controlled with grid-fitting in some exotic
* glyphs.
*
* Rule 5
* If a scan line between two adjacent pixel centers (either vertical or horizontal)
* is intersected by both an on-Transition contour and an off-Transition contour and
* neither of the pixels was already turned on by rules 1 and 2, turn on the pixel
* which is closer to the midpoint between the on-Transition contour and off-
* Transition contour. This is "Smart" dropout control.
*
* Rule 6
* Apply Rule 5 only if the two contours continue to intersect other scan lines in
* both directions. That is, do not turn on pixels for 'stubs.'
*
* New fonts wishing to use the new modes of the ScanType instruction, but still
* wishing to work correctly on old rasterizers that don't recognize the new modes
* should:
*
* First execute a ScanType instruction using an old mode which will give the best
* approximation to the desired new mode (e.g. Simple Stubs for Smart Stubs), and
* then
*
* Immediately execute another ScanType instruction with the desired new mode.
*/
private void _scantype() {
pop();
}
private void _scfs() {
pop();
pop();
}
/**
* Set Control Value Table Cut In
*/
private void _scvtci() {
gs.control_value_cut_in = pop();
}
/**
* Set Delta_Base in the graphics state
*/
private void _sdb() {
gs.delta_base = pop();
}
/**
* Set Dual Projection_Vector To Line
*/
private void _sdpvtl(final short param) {
pop();
pop();
}
/**
* Set Delta_Shift in the graphics state
*/
private void _sds() {
gs.delta_shift = pop();
}
/**
* Set Freedom_Vector From Stack
*/
private void _sfvfs() {
gs.freedom_vector[1] = pop(); // y
gs.freedom_vector[0] = pop(); // x
}
/*
* Set Freedom_Vector to Coordinate Axis
*/
private void _sfvtca(final short param) {
if (param == 1) {
gs.freedom_vector[0] = 0x4000;
gs.freedom_vector[1] = 0x0000;
} else {
gs.freedom_vector[0] = 0x0000;
gs.freedom_vector[1] = 0x4000;
}
}
/*
* Set Freedom_Vector To Line
*/
private void _sfvtl(final short param) {
pop();
pop();
// if (param == 1) {
gs.freedom_vector[0] = 0x0000;
gs.freedom_vector[1] = 0x0000;
// } else {
// gs.freedom_vector[0] = 0x0000;
// gs.freedom_vector[1] = 0x0000;
//}
}
/**
* Set Freedom_Vector To Projection Vector
*/
private void _sfvtpv() {
gs.freedom_vector[0] = gs.projection_vector[0];
gs.freedom_vector[1] = gs.projection_vector[1];
}
private void _shc(final short param) {
pop();
}
/**
* SHift Point by the last point
*
* USES: loop
*/
private void _shp(final short param) {
while(gs.loop-- > 0) {
pop();
if(param == 0) {
} else {
}
}
gs.loop = 1;
}
/**
* SHift Point by a PIXel amount
*
* USES: loop
*/
private void _shpix() {
pop(); // amount
while (gs.loop-- > 0) {
pop(); // p
}
gs.loop = 1;
}
private void _shz(final short param) {
pop();
}
/**
* Set LOOP variable
*/
private void _sloop() {
gs.loop = pop();
}
/**
* Set Minimum_Distance
*/
private void _smd() {
gs.minimum_distance = pop();
}
/**
* Set Projection_Vector From Stack
*/
private void _spvfs() {
gs.projection_vector[1] = pop(); // y
gs.projection_vector[0] = pop(); // x
}
/*
* Set Projection_Vector To Coordinate Axis
*/
private void _spvtca(final short param) {
if (param == 1) {
gs.projection_vector[0] = 0x4000;
gs.projection_vector[1] = 0x0000;
} else {
gs.projection_vector[0] = 0x0000;
gs.projection_vector[1] = 0x4000;
}
}
/**
* Set Projection_Vector To Line
*/
private void _spvtl(final short param) {
// below block is dead code, reduce to pop() calls.
pop();
pop();
/**
// We'll get a copy of the line and normalize it -
// divide the x- and y-coords by the vector's dot product.
final Point p1 = zone[gs.zp2][pop()];
final Point p2 = zone[gs.zp1][pop()];
final int x = p2.x - p1.x;
final int y = p2.y - p1.y;
*/
// if(param == 1) {
gs.projection_vector[0] = 0x0000;
gs.projection_vector[1] = 0x0000;
// } else {
// gs.projection_vector[0] = 0x0000;
// gs.projection_vector[1] = 0x0000;
// }
}
private void _sround() {
pop();
}
/**
* Set Reference Point 0
*/
private void _srp0() {
gs.rp0 = pop();
}
/**
* Set Reference Point 1
*/
private void _srp1() {
gs.rp1 = pop();
}
/**
* Set Reference Point 2
*/
private void _srp2() {
gs.rp2 = pop();
}
/**
* Set Single-Width
*/
private void _ssw() {
gs.single_width_value = pop();
}
/**
* Set Single_Width_Cut_In
*/
private void _sswci() {
gs.single_width_cut_in = pop();
}
/**
* SUBtract
*/
private void _sub() {
final int n1 = pop();
final int n2 = pop();
push(n2 - n1);
}
/**
* Set freedom and projection Vectors To Coordinate Axis
*/
private void _svtca(final short param) {
if (param == 1) {
gs.projection_vector[0] = 0x4000;
gs.projection_vector[1] = 0x0000;
gs.freedom_vector[0] = 0x4000;
gs.freedom_vector[1] = 0x0000;
} else {
gs.projection_vector[0] = 0x0000;
gs.projection_vector[1] = 0x4000;
gs.freedom_vector[0] = 0x0000;
gs.freedom_vector[1] = 0x4000;
}
}
/**
* SWAP the top two elements on the stack
*/
private void _swap() {
final int n1 = pop();
final int n2 = pop();
push(n1);
push(n2);
}
/**
* Set Zone Pointer 0
*/
private void _szp0() {
gs.zp0 = pop();
}
/**
* Set Zone Pointer 1
*/
private void _szp1() {
gs.zp1 = pop();
}
/**
* Set Zone Pointer 2
*/
private void _szp2() {
gs.zp2 = pop();
}
/**
* Set Zone PointerS
*/
private void _szps() {
gs.zp0 = gs.zp1 = gs.zp2 = pop();
}
private void _utp() {
pop();
}
/**
* Write Control Value Table in FUnits
*/
private void _wcvtf() {
final int value = pop();
// Conversion of value goes here
cvt[pop()] = value;
}
/**
* Write Control Value Table in Pixel units
*/
private void _wcvtp() {
final int value = pop();
// Conversion of value goes here
cvt[pop()] = value;
}
/**
* Write Store
*/
private void _ws() {
store[pop()] = pop();
}
public void execute(int ip) {
while (ip < ((ip & 0xffff0000) | parser.getISLength(ip >> 16))) {
final short opcode = parser.getOpcode(ip);
if (inFuncDef) {
// We're within a function definition, so don't execute the code
if (opcode == Mnemonic.ENDF) {
inFuncDef = false;
}
ip = parser.advanceIP(ip);
continue;
}
if (opcode >= Mnemonic.MIRP) _mirp((short)(opcode & 31));
else if (opcode >= Mnemonic.MDRP) _mdrp((short)(opcode & 31));
else if (opcode >= Mnemonic.PUSHW) _push(parser.getPushData(ip));
else if (opcode >= Mnemonic.PUSHB) _push(parser.getPushData(ip));
else if (opcode >= Mnemonic.INSTCTRL) _instctrl();
else if (opcode >= Mnemonic.SCANTYPE) _scantype();
else if (opcode >= Mnemonic.MIN) _min();
else if (opcode >= Mnemonic.MAX) _max();
else if (opcode >= Mnemonic.ROLL) _roll();
else if (opcode >= Mnemonic.IDEF) _idef();
else if (opcode >= Mnemonic.GETINFO) _getinfo();
else if (opcode >= Mnemonic.SDPVTL) _sdpvtl((short)(opcode & 1));
else if (opcode >= Mnemonic.SCANCTRL) _scanctrl();
else if (opcode >= Mnemonic.FLIPRGOFF) _fliprgoff();
else if (opcode >= Mnemonic.FLIPRGON) _fliprgon();
else if (opcode >= Mnemonic.FLIPPT) _flippt();
else if (opcode >= Mnemonic.AA); // AA (ignored)
else if (opcode >= Mnemonic.SANGW); // SANGW (ignored)
else if (opcode >= Mnemonic.RDTG) _rdtg();
else if (opcode >= Mnemonic.RUTG) _rutg();
else if (opcode >= Mnemonic.ROFF) _roff();
else if (opcode >= Mnemonic.JROF) ip = _jrof(ip);
else if (opcode >= Mnemonic.JROT) ip = _jrot(ip);
else if (opcode >= Mnemonic.S45ROUND) _s45round();
else if (opcode >= Mnemonic.SROUND) _sround();
else if (opcode >= Mnemonic.DELTAC3) _deltac3();
else if (opcode >= Mnemonic.DELTAC2) _deltac2();
else if (opcode >= Mnemonic.DELTAC1) _deltac1();
else if (opcode >= Mnemonic.DELTAP3) _deltap3();
else if (opcode >= Mnemonic.DELTAP2) _deltap2();
else if (opcode >= Mnemonic.WCVTF) _wcvtf();
else if (opcode >= Mnemonic.NROUND) _nround((short)(opcode & 3));
else if (opcode >= Mnemonic.ROUND) _round((short)(opcode & 3));
else if (opcode >= Mnemonic.CEILING) _ceiling();
else if (opcode >= Mnemonic.FLOOR) _floor();
else if (opcode >= Mnemonic.NEG) _neg();
else if (opcode >= Mnemonic.ABS) _abs();
else if (opcode >= Mnemonic.MUL) _mul();
else if (opcode >= Mnemonic.DIV) _div();
else if (opcode >= Mnemonic.SUB) _sub();
else if (opcode >= Mnemonic.ADD) _add();
else if (opcode >= Mnemonic.SDS) _sds();
else if (opcode >= Mnemonic.SDB) _sdb();
else if (opcode >= Mnemonic.DELTAP1) _deltap1();
else if (opcode >= Mnemonic.NOT) _not();
else if (opcode >= Mnemonic.OR) _or();
else if (opcode >= Mnemonic.AND) _and();
else if (opcode >= Mnemonic.EIF); // EIF
else if (opcode >= Mnemonic.IF) ip = _if(ip);
else if (opcode >= Mnemonic.EVEN) _even();
else if (opcode >= Mnemonic.ODD) _odd();
else if (opcode >= Mnemonic.NEQ) _neq();
else if (opcode >= Mnemonic.EQ) _eq();
else if (opcode >= Mnemonic.GTEQ) _gteq();
else if (opcode >= Mnemonic.GT) _gt();
else if (opcode >= Mnemonic.LTEQ) _lteq();
else if (opcode >= Mnemonic.LT) _lt();
else if (opcode >= Mnemonic.DEBUG) _debug();
else if (opcode >= Mnemonic.FLIPOFF) _flipoff();
else if (opcode >= Mnemonic.FLIPON) _flipon();
else if (opcode >= Mnemonic.MPS) _mps();
else if (opcode >= Mnemonic.MPPEM) _mppem();
else if (opcode >= Mnemonic.MD) _md((short)(opcode & 1));
else if (opcode >= Mnemonic.SCFS) _scfs();
else if (opcode >= Mnemonic.GC) _gc((short)(opcode & 1));
else if (opcode >= Mnemonic.RCVT) _rcvt();
else if (opcode >= Mnemonic.WCVTP) _wcvtp();
else if (opcode >= Mnemonic.RS) _rs();
else if (opcode >= Mnemonic.WS) _ws();
else if (opcode >= Mnemonic.NPUSHW) _push(parser.getPushData(ip));
else if (opcode >= Mnemonic.NPUSHB) _push(parser.getPushData(ip));
else if (opcode >= Mnemonic.MIAP) _miap((short)(opcode & 1));
else if (opcode >= Mnemonic.RTDG) _rtdg();
else if (opcode >= Mnemonic.ALIGNRP) _alignrp();
else if (opcode >= Mnemonic.IP) _ip();
else if (opcode >= Mnemonic.MSIRP) _msirp((short)(opcode & 1));
else if (opcode >= Mnemonic.SHPIX) _shpix();
else if (opcode >= Mnemonic.SHZ) _shz((short)(opcode & 1));
else if (opcode >= Mnemonic.SHC) _shc((short)(opcode & 1));
else if (opcode >= Mnemonic.SHP) _shp((short)(opcode & 1));
else if (opcode >= Mnemonic.IUP) _iup((short)(opcode & 1));
else if (opcode >= Mnemonic.MDAP) _mdap((short)(opcode & 1));
else if (opcode >= Mnemonic.ENDF) return;
else if (opcode >= Mnemonic.FDEF) _fdef(ip + 1);
else if (opcode >= Mnemonic.CALL) _call();
else if (opcode >= Mnemonic.LOOPCALL) _loopcall();
else if (opcode >= Mnemonic.UTP) _utp();
else if (opcode >= Mnemonic.ALIGNPTS) _alignpts();
else if (opcode >= Mnemonic.MINDEX) _mindex();
else if (opcode >= Mnemonic.CINDEX) _cindex();
else if (opcode >= Mnemonic.DEPTH) _depth();
else if (opcode >= Mnemonic.SWAP) _swap();
else if (opcode >= Mnemonic.CLEAR) _clear();
else if (opcode >= Mnemonic.POP) pop();
else if (opcode >= Mnemonic.DUP) _dup();
else if (opcode >= Mnemonic.SSW) _ssw();
else if (opcode >= Mnemonic.SSWCI) _sswci();
else if (opcode >= Mnemonic.SCVTCI) _scvtci();
else if (opcode >= Mnemonic.JMPR) ip = _jmpr(ip);
else if (opcode >= Mnemonic.ELSE) ip = _else(ip);
else if (opcode >= Mnemonic.SMD) _smd();
else if (opcode >= Mnemonic.RTHG) _rthg();
else if (opcode >= Mnemonic.RTG) _rtg();
else if (opcode >= Mnemonic.SLOOP) _sloop();
else if (opcode >= Mnemonic.SZPS) _szps();
else if (opcode >= Mnemonic.SZP2) _szp2();
else if (opcode >= Mnemonic.SZP1) _szp1();
else if (opcode >= Mnemonic.SZP0) _szp0();
else if (opcode >= Mnemonic.SRP2) _srp2();
else if (opcode >= Mnemonic.SRP1) _srp1();
else if (opcode >= Mnemonic.SRP0) _srp0();
else if (opcode >= Mnemonic.ISECT) _isect();
else if (opcode >= Mnemonic.SFVTPV) _sfvtpv();
else if (opcode >= Mnemonic.GFV) _gfv();
else if (opcode >= Mnemonic.GPV) _gpv();
else if (opcode >= Mnemonic.SFVFS) _sfvfs();
else if (opcode >= Mnemonic.SPVFS) _spvfs();
else if (opcode >= Mnemonic.SFVTL) _sfvtl((short)(opcode & 1));
else if (opcode >= Mnemonic.SPVTL) _spvtl((short)(opcode & 1));
else if (opcode >= Mnemonic.SFVTCA) _sfvtca((short)(opcode & 1));
else if (opcode >= Mnemonic.SPVTCA) _spvtca((short)(opcode & 1));
else if (opcode >= Mnemonic.SVTCA) _svtca((short)(opcode & 1));
ip = parser.advanceIP(ip);
}
}
public Point[][] getZones() {
return zone;
}
private int pop() {
return stack[--stackIndex];
}
private void push(final int i) {
stack[stackIndex++] = i;
}
public void runCvtProgram() {
execute(0x00010000);
}
public void runFontProgram() {
execute(0);
}
public void runGlyphProgram() {
// instruction_control can be set to stop glyphs grid-fitting
if ((gs.instruction_control & 1) == 0) {
execute(0x00020000);
}
}
public void setParser(final Parser p) {
parser = p;
}
}