aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Schweinsberg <[email protected]>2015-12-31 14:17:46 -0800
committerDavid Schweinsberg <[email protected]>2015-12-31 14:17:46 -0800
commitf9171741a060e1445a030c5e68c0b04920b8497d (patch)
tree17a50073dbc37f80511793ea5f9858b01c75bda2 /src
parent52e8dce11e6456ff08f4c46e59ac619b67df603f (diff)
Implemented subrs in Type 2 Charstring interpreter
Diffstat (limited to 'src')
-rw-r--r--src/net/java/dev/typecast/cff/CffFont.java2
-rw-r--r--src/net/java/dev/typecast/cff/CharstringType2.java2
-rw-r--r--src/net/java/dev/typecast/cff/T2Interpreter.java97
3 files changed, 77 insertions, 24 deletions
diff --git a/src/net/java/dev/typecast/cff/CffFont.java b/src/net/java/dev/typecast/cff/CffFont.java
index 3599178..cbb197f 100644
--- a/src/net/java/dev/typecast/cff/CffFont.java
+++ b/src/net/java/dev/typecast/cff/CffFont.java
@@ -24,7 +24,7 @@ import net.java.dev.typecast.ot.table.CffTable;
/**
*
- * @author dschweinsberg
+ * @author <a href="mailto:[email protected]">David Schweinsberg</a>
*/
public class CffFont {
diff --git a/src/net/java/dev/typecast/cff/CharstringType2.java b/src/net/java/dev/typecast/cff/CharstringType2.java
index 34ae551..578bab1 100644
--- a/src/net/java/dev/typecast/cff/CharstringType2.java
+++ b/src/net/java/dev/typecast/cff/CharstringType2.java
@@ -250,6 +250,8 @@ public class CharstringType2 extends Charstring {
StringBuilder sb = new StringBuilder();
int ip = getFirstIndex();
while (moreBytes(ip)) {
+ sb.append(ip);
+ sb.append(": ");
ip = disassemble(ip, sb);
sb.append("\n");
}
diff --git a/src/net/java/dev/typecast/cff/T2Interpreter.java b/src/net/java/dev/typecast/cff/T2Interpreter.java
index ad23141..930b578 100644
--- a/src/net/java/dev/typecast/cff/T2Interpreter.java
+++ b/src/net/java/dev/typecast/cff/T2Interpreter.java
@@ -28,13 +28,22 @@ import net.java.dev.typecast.ot.Point;
*/
public class T2Interpreter {
+ private class SubrPair {
+ final CharstringType2 cs;
+ final int ip;
+ SubrPair(CharstringType2 cs, int ip) {
+ this.cs = cs;
+ this.ip = ip;
+ }
+ }
+
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 final Number[] _argStack = new Number[ARGUMENT_STACK_LIMIT];
private int _argStackIndex = 0;
- private final int[] _subrStack = new int[SUBR_STACK_LIMIT];
+ private final SubrPair[] _subrStack = new SubrPair[SUBR_STACK_LIMIT];
private int _subrStackIndex = 0;
private final Number[] _transientArray = new Number[TRANSIENT_ARRAY_ELEMENT_COUNT];
@@ -43,6 +52,9 @@ public class T2Interpreter {
private ArrayList<Point> _points;
private Index _localSubrIndex;
private Index _globalSubrIndex;
+ private CharstringType2 _localSubrs;
+ private CharstringType2 _globalSubrs;
+ private CharstringType2 _cs;
private int _ip;
/** Creates a new instance of T2Interpreter */
@@ -527,6 +539,11 @@ public class T2Interpreter {
private void _endchar() {
endContour();
clearArg();
+ while (_subrStackIndex > 0) {
+ SubrPair sp = popSubr();
+ _cs = sp.cs;
+ _ip = sp.ip;
+ }
}
private void _hstem() {
@@ -776,7 +793,7 @@ public class T2Interpreter {
* act according to the manner in which the subroutine is coded.
* Calling an undefined subr (gsubr) has undefined results.
*/
- private void _callsubr(CharstringType2 cs) {
+ private void _callsubr() {
int bias;
int subrsCount = _localSubrIndex.getCount();
if (subrsCount < 1240) {
@@ -787,17 +804,19 @@ public class T2Interpreter {
bias = 32768;
}
int i = popArg().intValue();
- int offset = _localSubrIndex.getOffset(i + bias);
- int offset2 = _localSubrIndex.getOffset(i + bias + 1);
+ int offset = _localSubrIndex.getOffset(i + bias) - 1;
+ pushSubr(new SubrPair(_cs, _ip));
+ _cs = _localSubrs;
+ _ip = offset;
}
/**
* Operates in the same manner as callsubr except that it calls a
* global subroutine.
*/
- private void _callgsubr(CharstringType2 cs) {
+ private void _callgsubr() {
int bias;
- int subrsCount = _localSubrIndex.getCount();
+ int subrsCount = _globalSubrIndex.getCount();
if (subrsCount < 1240) {
bias = 107;
} else if (subrsCount < 33900) {
@@ -806,31 +825,52 @@ public class T2Interpreter {
bias = 32768;
}
int i = popArg().intValue();
- int offset = _localSubrIndex.getOffset(i + bias);
-
+ int offset = _globalSubrIndex.getOffset(i + bias) - 1;
+ pushSubr(new SubrPair(_cs, _ip));
+ _cs = _globalSubrs;
+ _ip = offset;
}
/**
* Returns from either a local or global charstring subroutine, and
* continues execution after the corresponding call(g)subr.
*/
- private void _return(CharstringType2 cs) {
- //_ip = popSubr();
+ private void _return() {
+ SubrPair sp = popSubr();
+ _cs = sp.cs;
+ _ip = sp.ip;
}
public Point[] execute(CharstringType2 cs) {
_localSubrIndex = cs.getFont().getLocalSubrIndex();
_globalSubrIndex = cs.getFont().getTable().getGlobalSubrIndex();
+ _localSubrs = new CharstringType2(
+ null,
+ 0,
+ "Local subrs",
+ _localSubrIndex.getData(),
+ _localSubrIndex.getOffset(0) - 1,
+ _localSubrIndex.getDataLength());
+ _globalSubrs = new CharstringType2(
+ null,
+ 0,
+ "Global subrs",
+ _globalSubrIndex.getData(),
+ _globalSubrIndex.getOffset(0) - 1,
+ _globalSubrIndex.getDataLength());
+ _cs = cs;
+ System.out.println(_localSubrs.toString());
+
_points = new ArrayList<>();
- _ip = cs.getFirstIndex();
- while (cs.moreBytes(_ip)) {
- while (cs.isOperandAtIndex(_ip)) {
- pushArg(cs.operandAtIndex(_ip));
- _ip = cs.nextOperandIndex(_ip);
+ _ip = _cs.getFirstIndex();
+ while (_cs.moreBytes(_ip)) {
+ while (_cs.isOperandAtIndex(_ip)) {
+ pushArg(_cs.operandAtIndex(_ip));
+ _ip = _cs.nextOperandIndex(_ip);
}
- int operator = cs.byteAtIndex(_ip++);
+ int operator = _cs.byteAtIndex(_ip++);
if (operator == 12) {
- operator = cs.byteAtIndex(_ip++);
+ operator = _cs.byteAtIndex(_ip++);
// Two-byte operators
switch (operator) {
@@ -936,10 +976,10 @@ public class T2Interpreter {
_rrcurveto();
break;
case T2Mnemonic.CALLSUBR:
- _callsubr(cs);
+ _callsubr();
break;
case T2Mnemonic.RETURN:
- _return(cs);
+ _return();
break;
case T2Mnemonic.ENDCHAR:
_endchar();
@@ -975,7 +1015,7 @@ public class T2Interpreter {
_hhcurveto();
break;
case T2Mnemonic.CALLGSUBR:
- _callgsubr(cs);
+ _callgsubr();
break;
case T2Mnemonic.VHCURVETO:
_vhcurveto();
@@ -1005,6 +1045,11 @@ public class T2Interpreter {
* Pop a value off the argument stack
*/
private Number popArg() {
+// System.out.print("popArg: " + _argStack[_argStackIndex - 1] + " (");
+// for (int i = 0; i < _argStackIndex - 1; ++i) {
+// System.out.print(" " + _argStack[i]);
+// }
+// System.out.println(")");
return _argStack[--_argStackIndex];
}
@@ -1013,20 +1058,26 @@ public class T2Interpreter {
*/
private void pushArg(Number n) {
_argStack[_argStackIndex++] = n;
+// System.out.print("pushArg: " + n + " (");
+// for (int i = 0; i < _argStackIndex - 1; ++i) {
+// System.out.print(" " + _argStack[i]);
+// }
+// System.out.println(")");
}
/**
* Pop a value off the subroutine stack
*/
- private int popSubr() {
+ private SubrPair popSubr() {
return _subrStack[--_subrStackIndex];
}
/**
* Push a value on to the subroutine stack
*/
- private void pushSubr(int n) {
- _subrStack[_subrStackIndex++] = n;
+ private void pushSubr(SubrPair sp) {
+ _subrStack[_subrStackIndex] = sp;
+ _subrStackIndex++;
}
/**