aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schweinsberg <[email protected]>2007-02-21 12:30:48 +0000
committerDavid Schweinsberg <[email protected]>2007-02-21 12:30:48 +0000
commit9e5f45a7d84a8dd5536d4057b6135219c065d506 (patch)
tree62b97379f1cc318aa9fb2e42c1c7e48fd0ea7de0
parent5d1e7fbd4580baf175e9fe86da5878e198effe14 (diff)
New Type 2 Charstring handling classes.
-rw-r--r--src/net/java/dev/typecast/t2/T2Interpreter.java835
-rw-r--r--src/net/java/dev/typecast/t2/T2Mnemonic.java86
2 files changed, 921 insertions, 0 deletions
diff --git a/src/net/java/dev/typecast/t2/T2Interpreter.java b/src/net/java/dev/typecast/t2/T2Interpreter.java
new file mode 100644
index 0000000..9b4ce50
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/T2Interpreter.java
@@ -0,0 +1,835 @@
+/*
+ * $Id: T2Interpreter.java,v 1.1 2007-02-21 12:30:48 davidsch Exp $
+ *
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2007 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 net.java.dev.typecast.t2;
+
+import java.util.ArrayList;
+
+import net.java.dev.typecast.ot.Point;
+
+import net.java.dev.typecast.ot.table.CharstringType2;
+
+/**
+ * Type 2 Charstring Interpreter. Operator descriptions are quoted from
+ * Adobe's Type 2 Charstring Format document -- 5117.Type2.pdf.
+ * @author <a href="mailto:[email protected]">David Schweinsberg</a>
+ * @version $Id: T2Interpreter.java,v 1.1 2007-02-21 12:30:48 davidsch Exp $
+ */
+public class T2Interpreter {
+
+ private static final int ARGUMENT_STACK_LIMIT = 48;
+ private static final int SUBR_STACK_LIMIT = 10;
+ private static final int TRANSIENT_ARRAY_ELEMENT_COUNT = 32;
+
+ private Number[] _argStack = new Number[ARGUMENT_STACK_LIMIT];
+ private int _argStackIndex = 0;
+ private int[] _subrStack = new int[SUBR_STACK_LIMIT];
+ private int _subrStackIndex = 0;
+ private Number[] _transientArray = new Number[TRANSIENT_ARRAY_ELEMENT_COUNT];
+
+ private ArrayList<Point> _points;
+
+ /** Creates a new instance of T2Interpreter */
+ public T2Interpreter() {
+ }
+
+ /**
+ * Moves the current point to a position at the relative coordinates
+ * (dx1, dy1).
+ */
+ private void _rmoveto() {
+ int dy1 = popArg().intValue();
+ int dx1 = popArg().intValue();
+ clearArg();
+ Point lastPoint = getLastPoint();
+ moveTo(lastPoint.x + dx1, lastPoint.y + dy1);
+ }
+
+ /**
+ * Moves the current point dx1 units in the horizontal direction.
+ */
+ private void _hmoveto() {
+ int dx1 = popArg().intValue();
+ clearArg();
+ Point lastPoint = getLastPoint();
+ moveTo(lastPoint.x + dx1, lastPoint.y);
+ }
+
+ /**
+ * Moves the current point dy1 units in the vertical direction.
+ */
+ private void _vmoveto() {
+ int dy1 = popArg().intValue();
+ clearArg();
+ Point lastPoint = getLastPoint();
+ moveTo(lastPoint.x, lastPoint.y + dy1);
+ }
+
+ /**
+ * Appends a line from the current point to a position at the
+ * relative coordinates dxa, dya. Additional rlineto operations are
+ * performed for all subsequent argument pairs. The number of
+ * lines is determined from the number of arguments on the stack.
+ */
+ private void _rlineto() {
+ int count = getArgCount() / 2;
+ for (int i = 0; i < count; ++i) {
+ int dy = popArg().intValue();
+ int dx = popArg().intValue();
+ Point lastPoint = getLastPoint();
+ lineTo(lastPoint.x + dx, lastPoint.y + dy);
+ }
+ clearArg();
+ }
+
+ /**
+ * Appends a horizontal line of length dx1 to the current point.
+ * With an odd number of arguments, subsequent argument pairs
+ * are interpreted as alternating values of dy and dx, for which
+ * additional lineto operators draw alternating vertical and
+ * horizontal lines. With an even number of arguments, the
+ * arguments are interpreted as alternating horizontal and
+ * vertical lines. The number of lines is determined from the
+ * number of arguments on the stack.
+ */
+ private void _hlineto() {
+ boolean oddCount = getArgCount() % 2 == 1;
+ int count = getArgCount() / 2;
+ if (oddCount) {
+ for (int i = 0; i < count; ++i) {
+ double dxb = popArg().doubleValue();
+ double dya = popArg().doubleValue();
+ }
+ double dx1 = popArg().doubleValue();
+ } else {
+ for (int i = 0; i < count; ++i) {
+ double dyb = popArg().doubleValue();
+ double dxa = popArg().doubleValue();
+ }
+ }
+ clearArg();
+ }
+
+ /**
+ * Appends a vertical line of length dy1 to the current point. With
+ * an odd number of arguments, subsequent argument pairs are
+ * interpreted as alternating values of dx and dy, for which
+ * additional lineto operators draw alternating horizontal and
+ * vertical lines. With an even number of arguments, the
+ * arguments are interpreted as alternating vertical and
+ * horizontal lines. The number of lines is determined from the
+ * number of arguments on the stack.
+ */
+ private void _vlineto() {
+ int count = getArgCount();
+ Number[] nums = new Number[count];
+ for (int i = 0; i < count; ++i) {
+ nums[count - i - 1] = popArg();
+ }
+ for (int i = 0; i < count; ++i) {
+ Point lastPoint = getLastPoint();
+ if (i % 2 == 0) {
+ lineTo(lastPoint.x, lastPoint.y + nums[i].intValue());
+ } else {
+ lineTo(lastPoint.x + nums[i].intValue(), lastPoint.y);
+ }
+ }
+
+// boolean oddCount = getArgCount() % 2 == 1;
+// int count = getArgCount() / 2;
+// if (oddCount) {
+// for (int i = 0; i < count; ++i) {
+// double dyb = popArg().doubleValue();
+// double dxa = popArg().doubleValue();
+// }
+// double dy1 = popArg().doubleValue();
+// } else {
+// for (int i = 0; i < count; ++i) {
+// double dxb = popArg().doubleValue();
+// double dya = popArg().doubleValue();
+// }
+// }
+ clearArg();
+ }
+
+ /**
+ * Appends a B�zier curve, defined by dxa...dyc, to the current
+ * point. For each subsequent set of six arguments, an additional
+ * curve is appended to the current point. The number of curve
+ * segments is determined from the number of arguments on the
+ * number stack and is limited only by the size of the number
+ * stack.
+ */
+ private void _rrcurveto() {
+ int count = getArgCount() / 6;
+ for (int i = 0; i < count; ++i) {
+ double dyc = popArg().doubleValue();
+ double dxc = popArg().doubleValue();
+ double dyb = popArg().doubleValue();
+ double dxb = popArg().doubleValue();
+ double dya = popArg().doubleValue();
+ double dxa = popArg().doubleValue();
+ }
+ clearArg();
+ }
+
+ /**
+ * Appends one or more B�zier curves, as described by the
+ * dxa...dxc set of arguments, to the current point. For each curve,
+ * if there are 4 arguments, the curve starts and ends horizontal.
+ * The first curve need not start horizontal (the odd argument
+ * case). Note the argument order for the odd argument case.
+ */
+ private void _hhcurveto() {
+
+ clearArg();
+ }
+
+ /**
+ * Appends one or more B�zier curves to the current point. The
+ * tangent for the first B�zier must be horizontal, and the second
+ * must be vertical (except as noted below).
+ * If there is a multiple of four arguments, the curve starts
+ * horizontal and ends vertical. Note that the curves alternate
+ * between start horizontal, end vertical, and start vertical, and
+ * end horizontal. The last curve (the odd argument case) need not
+ * end horizontal/vertical.
+ */
+ private void _hvcurveto() {
+
+ clearArg();
+ }
+
+ /**
+ * Is equivalent to one rrcurveto for each set of six arguments
+ * dxa...dyc, followed by exactly one rlineto using the dxd, dyd
+ * arguments. The number of curves is determined from the count
+ * on the argument stack.
+ */
+ private void _rcurveline() {
+
+ clearArg();
+ }
+
+ /**
+ * Is equivalent to one rlineto for each pair of arguments beyond
+ * the six arguments dxb...dyd needed for the one rrcurveto
+ * command. The number of lines is determined from the count of
+ * items on the argument stack.
+ */
+ private void _rlinecurve() {
+
+ clearArg();
+ }
+
+ /**
+ * Appends one or more B�zier curves to the current point, where
+ * the first tangent is vertical and the second tangent is horizontal.
+ * This command is the complement of hvcurveto; see the
+ * description of hvcurveto for more information.
+ */
+ private void _vhcurveto() {
+
+ clearArg();
+ }
+
+ /**
+ * Appends one or more curves to the current point. If the argument
+ * count is a multiple of four, the curve starts and ends vertical. If
+ * the argument count is odd, the first curve does not begin with a
+ * vertical tangent.
+ */
+ private void _vvcurveto() {
+
+ clearArg();
+ }
+
+ /**
+ * Causes two B�zier curves, as described by the arguments (as
+ * shown in Figure 2 below), to be rendered as a straight line when
+ * the flex depth is less than fd /100 device pixels, and as curved lines
+ * when the flex depth is greater than or equal to fd/100 device
+ * pixels.
+ */
+ private void _flex() {
+
+ clearArg();
+ }
+
+ /**
+ * Causes the two curves described by the arguments dx1...dx6 to
+ * be rendered as a straight line when the flex depth is less than
+ * 0.5 (that is, fd is 50) device pixels, and as curved lines when the
+ * flex depth is greater than or equal to 0.5 device pixels.
+ */
+ private void _hflex() {
+
+ clearArg();
+ }
+
+ /**
+ * Causes the two curves described by the arguments to be
+ * rendered as a straight line when the flex depth is less than 0.5
+ * device pixels, and as curved lines when the flex depth is greater
+ * than or equal to 0.5 device pixels.
+ */
+ private void _hflex1() {
+
+ clearArg();
+ }
+
+ /**
+ * Causes the two curves described by the arguments to be
+ * rendered as a straight line when the flex depth is less than 0.5
+ * device pixels, and as curved lines when the flex depth is greater
+ * than or equal to 0.5 device pixels.
+ */
+ private void _flex1() {
+
+ clearArg();
+ }
+
+ /**
+ * Finishes a charstring outline definition, and must be the
+ * last operator in a character�s outline.
+ */
+ private void _endchar() {
+ endContour();
+ clearArg();
+ }
+
+ private void _hstem() {
+
+ clearArg();
+ }
+
+ private void _vstem() {
+
+ clearArg();
+ }
+
+ private void _hstemhm() {
+
+ clearArg();
+ }
+
+ private void _vstemhm() {
+
+ clearArg();
+ }
+
+ private void _hintmask() {
+
+ clearArg();
+ }
+
+ private void _cntrmask() {
+
+ clearArg();
+ }
+
+ /**
+ * Returns the absolute value of num.
+ */
+ private void _abs() {
+ double num = popArg().doubleValue();
+ pushArg(Math.abs(num));
+ }
+
+ /**
+ * Returns the sum of the two numbers num1 and num2.
+ */
+ private void _add() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg(num1 + num2);
+ }
+
+ /**
+ * Returns the result of subtracting num2 from num1.
+ */
+ private void _sub() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg(num1 - num2);
+ }
+
+ /**
+ * Returns the quotient of num1 divided by num2. The result is
+ * undefined if overflow occurs and is zero for underflow.
+ */
+ private void _div() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg(num1 / num2);
+ }
+
+ /**
+ * Returns the negative of num.
+ */
+ private void _neg() {
+ double num = popArg().doubleValue();
+ pushArg(-num);
+ }
+
+ /**
+ * Returns a pseudo random number num2 in the range (0,1], that
+ * is, greater than zero and less than or equal to one.
+ */
+ private void _random() {
+ pushArg(1.0 - Math.random());
+ }
+
+ /**
+ * Returns the product of num1 and num2. If overflow occurs, the
+ * result is undefined, and zero is returned for underflow.
+ */
+ private void _mul() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg(num1 * num2);
+ }
+
+ /**
+ * Returns the square root of num. If num is negative, the result is
+ * undefined.
+ */
+ private void _sqrt() {
+ double num = popArg().doubleValue();
+ pushArg(Math.sqrt(num));
+ }
+
+ /**
+ * Removes the top element num from the Type 2 argument stack.
+ */
+ private void _drop() {
+ popArg();
+ }
+
+ /**
+ * Exchanges the top two elements on the argument stack.
+ */
+ private void _exch() {
+ Number num2 = popArg();
+ Number num1 = popArg();
+ pushArg(num2);
+ pushArg(num1);
+ }
+
+ /**
+ * Retrieves the element i from the top of the argument stack and
+ * pushes a copy of that element onto that stack. If i is negative,
+ * the top element is copied. If i is greater than X, the operation is
+ * undefined.
+ */
+ private void _index() {
+ int i = popArg().intValue();
+ Number[] nums = new Number[i];
+ for (int j = 0; j < i; ++j) {
+ nums[j] = popArg();
+ }
+ for (int j = i - 1; j >= 0; --j) {
+ pushArg(nums[j]);
+ }
+ pushArg(nums[i]);
+ }
+
+ /**
+ * Performs a circular shift of the elements num(N�1) ... num0 on
+ * the argument stack by the amount J. Positive J indicates upward
+ * motion of the stack; negative J indicates downward motion.
+ * The value N must be a non-negative integer, otherwise the
+ * operation is undefined.
+ */
+ private void _roll() {
+ int j = popArg().intValue();
+ int n = popArg().intValue();
+ Number[] nums = new Number[n];
+ for (int i = 0; i < n; ++i) {
+ nums[i] = popArg();
+ }
+ for (int i = n - 1; i >= 0; --i) {
+ pushArg(nums[(n + i + j) % n]);
+ }
+ }
+
+ /**
+ * Duplicates the top element on the argument stack.
+ */
+ private void _dup() {
+ Number any = popArg();
+ pushArg(any);
+ pushArg(any);
+ }
+
+ /**
+ * Stores val into the transient array at the location given by i.
+ */
+ private void _put() {
+ int i = popArg().intValue();
+ Number val = popArg();
+ _transientArray[i] = val;
+ }
+
+ /**
+ * Retrieves the value stored in the transient array at the location
+ * given by i and pushes the value onto the argument stack. If get
+ * is executed prior to put for i during execution of the current
+ * charstring, the value returned is undefined.
+ */
+ private void _get() {
+ int i = popArg().intValue();
+ pushArg(_transientArray[i]);
+ }
+
+ /**
+ * Puts a 1 on the stack if num1 and num2 are both non-zero, and
+ * puts a 0 on the stack if either argument is zero.
+ */
+ private void _and() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg((num1!=0.0) && (num2!=0.0) ? 1 : 0);
+ }
+
+ /**
+ * Puts a 1 on the stack if either num1 or num2 are non-zero, and
+ * puts a 0 on the stack if both arguments are zero.
+ */
+ private void _or() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg((num1!=0.0) || (num2!=0.0) ? 1 : 0);
+ }
+
+ /**
+ * Returns a 0 if num1 is non-zero; returns a 1 if num1 is zero.
+ */
+ private void _not() {
+ double num1 = popArg().doubleValue();
+ pushArg((num1!=0.0) ? 0 : 1);
+ }
+
+ /**
+ * Puts a 1 on the stack if num1 equals num2, otherwise a 0 (zero)
+ * is put on the stack.
+ */
+ private void _eq() {
+ double num2 = popArg().doubleValue();
+ double num1 = popArg().doubleValue();
+ pushArg(num1 == num2 ? 1 : 0);
+ }
+
+ /**
+ * Leaves the value s1 on the stack if v1 ? v2, or leaves s2 on the
+ * stack if v1 > v2. The value of s1 and s2 is usually the biased
+ * number of a subroutine.
+ */
+ private void _ifelse() {
+ double v2 = popArg().doubleValue();
+ double v1 = popArg().doubleValue();
+ Number s2 = popArg();
+ Number s1 = popArg();
+ pushArg(v1 <= v2 ? s1 : s2);
+ }
+
+ /**
+ * Calls a charstring subroutine with index subr# (actually the subr
+ * number plus the subroutine bias number, as described in section
+ * 2.3) in the Subrs array. Each element of the Subrs array is a
+ * charstring encoded like any other charstring. Arguments
+ * pushed on the Type 2 argument stack prior to calling the
+ * subroutine, and results pushed on this stack by the subroutine,
+ * act according to the manner in which the subroutine is coded.
+ * Calling an undefined subr (gsubr) has undefined results.
+ */
+ private void _callsubr() {
+
+ }
+
+ /**
+ * Operates in the same manner as callsubr except that it calls a
+ * global subroutine.
+ */
+ private void _callgsubr() {
+
+ }
+
+ /**
+ * Returns from either a local or global charstring subroutine, and
+ * continues execution after the corresponding call(g)subr.
+ */
+ private void _return() {
+
+ }
+
+ public Point[] execute(CharstringType2 cs) {
+ _points = new ArrayList<Point>();
+ cs.resetIP();
+ while (cs.moreBytes()) {
+ while (cs.isOperandAtIndex()) {
+ pushArg(cs.nextOperand());
+ }
+ int operator = cs.nextByte();
+ if (operator == 12) {
+ operator = cs.nextByte();
+
+ // Two-byte operators
+ switch (operator) {
+ case T2Mnemonic.AND:
+ _and();
+ break;
+ case T2Mnemonic.OR:
+ _or();
+ break;
+ case T2Mnemonic.NOT:
+ _not();
+ break;
+ case T2Mnemonic.ABS:
+ _abs();
+ break;
+ case T2Mnemonic.ADD:
+ _add();
+ break;
+ case T2Mnemonic.SUB:
+ _sub();
+ break;
+ case T2Mnemonic.DIV:
+ _div();
+ break;
+ case T2Mnemonic.NEG:
+ _neg();
+ break;
+ case T2Mnemonic.EQ:
+ _eq();
+ break;
+ case T2Mnemonic.DROP:
+ _drop();
+ break;
+ case T2Mnemonic.PUT:
+ _put();
+ break;
+ case T2Mnemonic.GET:
+ _get();
+ break;
+ case T2Mnemonic.IFELSE:
+ _ifelse();
+ break;
+ case T2Mnemonic.RANDOM:
+ _random();
+ break;
+ case T2Mnemonic.MUL:
+ _mul();
+ break;
+ case T2Mnemonic.SQRT:
+ _sqrt();
+ break;
+ case T2Mnemonic.DUP:
+ _dup();
+ break;
+ case T2Mnemonic.EXCH:
+ _exch();
+ break;
+ case T2Mnemonic.INDEX:
+ _index();
+ break;
+ case T2Mnemonic.ROLL:
+ _roll();
+ break;
+ case T2Mnemonic.HFLEX:
+ _hflex();
+ break;
+ case T2Mnemonic.FLEX:
+ _flex();
+ break;
+ case T2Mnemonic.HFLEX1:
+ _hflex1();
+ break;
+ case T2Mnemonic.FLEX1:
+ _flex1();
+ break;
+ default:
+ //throw new Exception();
+ return null;
+ }
+ } else {
+
+ // One-byte operators
+ switch (operator) {
+ case T2Mnemonic.HSTEM:
+ _hstem();
+ break;
+ case T2Mnemonic.VSTEM:
+ _vstem();
+ break;
+ case T2Mnemonic.VMOVETO:
+ _vmoveto();
+ break;
+ case T2Mnemonic.RLINETO:
+ _rlineto();
+ break;
+ case T2Mnemonic.HLINETO:
+ _hlineto();
+ break;
+ case T2Mnemonic.VLINETO:
+ _vlineto();
+ break;
+ case T2Mnemonic.RRCURVETO:
+ _rrcurveto();
+ break;
+ case T2Mnemonic.CALLSUBR:
+ _callsubr();
+ break;
+ case T2Mnemonic.RETURN:
+ _return();
+ break;
+ case T2Mnemonic.ENDCHAR:
+ _endchar();
+ break;
+ case T2Mnemonic.HSTEMHM:
+ _hstemhm();
+ break;
+ case T2Mnemonic.HINTMASK:
+ _hintmask();
+ break;
+ case T2Mnemonic.CNTRMASK:
+ _cntrmask();
+ break;
+ case T2Mnemonic.RMOVETO:
+ _rmoveto();
+ break;
+ case T2Mnemonic.HMOVETO:
+ _hmoveto();
+ break;
+ case T2Mnemonic.VSTEMHM:
+ _vstemhm();
+ break;
+ case T2Mnemonic.RCURVELINE:
+ _rcurveline();
+ break;
+ case T2Mnemonic.RLINECURVE:
+ _rlinecurve();
+ break;
+ case T2Mnemonic.VVCURVETO:
+ _vvcurveto();
+ break;
+ case T2Mnemonic.HHCURVETO:
+ _hhcurveto();
+ break;
+ case T2Mnemonic.CALLGSUBR:
+ _callgsubr();
+ break;
+ case T2Mnemonic.VHCURVETO:
+ _vhcurveto();
+ break;
+ case T2Mnemonic.HVCURVETO:
+ _hvcurveto();
+ break;
+ default:
+ //throw new Exception();
+ return null;
+ }
+ }
+ }
+ Point[] pointArray = new Point[_points.size()];
+ _points.toArray(pointArray);
+ return pointArray;
+ }
+
+ /**
+ * The number of arguments on the argument stack
+ */
+ private int getArgCount() {
+ return _argStackIndex;
+ }
+
+ /**
+ * Pop a value off the argument stack
+ */
+ private Number popArg() {
+ return _argStack[--_argStackIndex];
+ }
+
+ /**
+ * Push a value on to the argument stack
+ */
+ private void pushArg(Number n) {
+ _argStack[_argStackIndex++] = n;
+ }
+
+ /**
+ * Pop a value off the subroutine stack
+ */
+ private int popSubr() {
+ return _subrStack[--_subrStackIndex];
+ }
+
+ /**
+ * Push a value on to the subroutine stack
+ */
+ private void pushSubr(int n) {
+ _subrStack[_subrStackIndex++] = n;
+ }
+
+ /**
+ * Clear the argument stack
+ */
+ private void clearArg() {
+ _argStackIndex = 0;
+ }
+
+ private Point getLastPoint() {
+ int size = _points.size();
+ if (size > 0) {
+ return _points.get(size - 1);
+ } else {
+ return new Point(0, 0, true, false);
+ }
+ }
+
+ private void moveTo(int x, int y) {
+ endContour();
+ _points.add(new Point(x, y, true, false));
+ }
+
+ private void lineTo(int x, int y) {
+ _points.add(new Point(x, y, true, false));
+ }
+
+ private void curveTo(int dcx1, int dcy1, int dcx2, int dcy2, int dx, int dy) {
+ Point lastPoint = getLastPoint();
+ int x = lastPoint.x + dcx1;
+ int y = lastPoint.y + dcy1;
+ _points.add(new Point(x, y, false, false));
+ x += dcx2;
+ y += dcy2;
+ _points.add(new Point(x, y, false, false));
+ x += dx;
+ y += dy;
+ _points.add(new Point(x, y, true, false));
+ }
+
+ private void endContour() {
+ Point lastPoint = getLastPoint();
+ if (lastPoint != null) {
+ lastPoint.endOfContour = true;
+ }
+ }
+}
diff --git a/src/net/java/dev/typecast/t2/T2Mnemonic.java b/src/net/java/dev/typecast/t2/T2Mnemonic.java
new file mode 100644
index 0000000..810aea1
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/T2Mnemonic.java
@@ -0,0 +1,86 @@
+/*
+ * $Id: T2Mnemonic.java,v 1.1 2007-02-21 12:30:48 davidsch Exp $
+ *
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2007 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 net.java.dev.typecast.t2;
+
+/**
+ * The Mnemonic representations of the Type 2 charstring instruction set.
+ * @author <a href="mailto:[email protected]">David Schweinsberg</a>
+ * @version $Id: T2Mnemonic.java,v 1.1 2007-02-21 12:30:48 davidsch Exp $
+ */
+public class T2Mnemonic {
+
+ /**
+ * One byte operators
+ */
+ public static final short HSTEM = 0x01;
+ public static final short VSTEM = 0x03;
+ public static final short VMOVETO = 0x04;
+ public static final short RLINETO = 0x05;
+ public static final short HLINETO = 0x06;
+ public static final short VLINETO = 0x07;
+ public static final short RRCURVETO = 0x08;
+ public static final short CALLSUBR = 0x0a;
+ public static final short RETURN = 0x0b;
+ public static final short ESCAPE = 0x0c;
+ public static final short ENDCHAR = 0x0e;
+ public static final short HSTEMHM = 0x12;
+ public static final short HINTMASK = 0x13;
+ public static final short CNTRMASK = 0x14;
+ public static final short RMOVETO = 0x15;
+ public static final short HMOVETO = 0x16;
+ public static final short VSTEMHM = 0x17;
+ public static final short RCURVELINE = 0x18;
+ public static final short RLINECURVE = 0x19;
+ public static final short VVCURVETO = 0x1a;
+ public static final short HHCURVETO = 0x1b;
+ public static final short CALLGSUBR = 0x1d;
+ public static final short VHCURVETO = 0x1e;
+ public static final short HVCURVETO = 0x1f;
+
+ /**
+ * Two byte operators
+ */
+ public static final short DOTSECTION = 0x00;
+ public static final short AND = 0x03;
+ public static final short OR = 0x04;
+ public static final short NOT = 0x05;
+ public static final short ABS = 0x09;
+ public static final short ADD = 0x0a;
+ public static final short SUB = 0x0b;
+ public static final short DIV = 0x0c;
+ public static final short NEG = 0x0e;
+ public static final short EQ = 0x0f;
+ public static final short DROP = 0x12;
+ public static final short PUT = 0x14;
+ public static final short GET = 0x15;
+ public static final short IFELSE = 0x16;
+ public static final short RANDOM = 0x17;
+ public static final short MUL = 0x18;
+ public static final short SQRT = 0x1a;
+ public static final short DUP = 0x1b;
+ public static final short EXCH = 0x1c;
+ public static final short INDEX = 0x1d;
+ public static final short ROLL = 0x1e;
+ public static final short HFLEX = 0x22;
+ public static final short FLEX = 0x23;
+ public static final short HFLEX1 = 0x24;
+ public static final short FLEX1 = 0x25;
+}