aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schweinsberg <[email protected]>2015-12-29 23:29:26 -0800
committerDavid Schweinsberg <[email protected]>2015-12-29 23:29:26 -0800
commit0c64891ea399a9c5fd95753c549c604e46a7bc23 (patch)
tree94697d9142f2446ad0cfe9a43bf987b3e792bcbf
parentb2d29d276feb057409d7b2abb30f218d4061b7c5 (diff)
Moved CffTable inner classes out into CFF-specific package.
-rw-r--r--src/net/java/dev/typecast/app/editor/GlyphPanel.java2
-rw-r--r--src/net/java/dev/typecast/app/editor/Main.java2
-rw-r--r--src/net/java/dev/typecast/app/editor/TableTreeBuilder.java5
-rw-r--r--src/net/java/dev/typecast/ot/Glyph.java9
-rw-r--r--src/net/java/dev/typecast/ot/table/CffTable.java506
-rw-r--r--src/net/java/dev/typecast/t2/CffFont.java64
-rw-r--r--src/net/java/dev/typecast/t2/CffStandardStrings.java (renamed from src/net/java/dev/typecast/ot/table/CffStandardStrings.java)2
-rw-r--r--src/net/java/dev/typecast/t2/Charset.java33
-rw-r--r--src/net/java/dev/typecast/t2/CharsetFormat0.java51
-rw-r--r--src/net/java/dev/typecast/t2/CharsetFormat1.java63
-rw-r--r--src/net/java/dev/typecast/t2/CharsetFormat2.java63
-rw-r--r--src/net/java/dev/typecast/t2/CharsetRange.java48
-rw-r--r--src/net/java/dev/typecast/t2/CharsetRange1.java34
-rw-r--r--src/net/java/dev/typecast/t2/CharsetRange2.java34
-rw-r--r--src/net/java/dev/typecast/t2/Charstring.java (renamed from src/net/java/dev/typecast/ot/table/Charstring.java)2
-rw-r--r--src/net/java/dev/typecast/t2/CharstringType2.java (renamed from src/net/java/dev/typecast/ot/table/CharstringType2.java)4
-rw-r--r--src/net/java/dev/typecast/t2/Dict.java169
-rw-r--r--src/net/java/dev/typecast/t2/Index.java89
-rw-r--r--src/net/java/dev/typecast/t2/NameIndex.java57
-rw-r--r--src/net/java/dev/typecast/t2/StringIndex.java62
-rw-r--r--src/net/java/dev/typecast/t2/T2Interpreter.java8
-rw-r--r--src/net/java/dev/typecast/t2/TopDictIndex.java48
22 files changed, 844 insertions, 511 deletions
diff --git a/src/net/java/dev/typecast/app/editor/GlyphPanel.java b/src/net/java/dev/typecast/app/editor/GlyphPanel.java
index 977d351..a992261 100644
--- a/src/net/java/dev/typecast/app/editor/GlyphPanel.java
+++ b/src/net/java/dev/typecast/app/editor/GlyphPanel.java
@@ -26,7 +26,7 @@ import net.java.dev.typecast.app.framework.EditorView;
import net.java.dev.typecast.edit.GlyphEdit;
import net.java.dev.typecast.ot.Glyph;
import net.java.dev.typecast.ot.OTFont;
-import net.java.dev.typecast.ot.table.Charstring;
+import net.java.dev.typecast.t2.Charstring;
import net.java.dev.typecast.ot.table.GlyphDescription;
/**
diff --git a/src/net/java/dev/typecast/app/editor/Main.java b/src/net/java/dev/typecast/app/editor/Main.java
index a427e3b..034b191 100644
--- a/src/net/java/dev/typecast/app/editor/Main.java
+++ b/src/net/java/dev/typecast/app/editor/Main.java
@@ -388,7 +388,7 @@ public class Main {
// Then add the panes we're interested in
if (obj instanceof GlyphDescription
- || obj instanceof net.java.dev.typecast.ot.table.Charstring) {
+ || obj instanceof net.java.dev.typecast.t2.Charstring) {
_glyphPane = new GlyphPanel(_appPrefs);
_glyphPane.setModel(font, obj);
_tabbedPane.add(_glyphPane);
diff --git a/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java b/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java
index eacd719..39ad633 100644
--- a/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java
+++ b/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java
@@ -37,12 +37,13 @@ import net.java.dev.typecast.ot.table.GlyfCompositeDescript;
import net.java.dev.typecast.ot.table.GlyfDescript;
import net.java.dev.typecast.ot.table.GlyfTable;
import net.java.dev.typecast.ot.table.CffTable;
-import net.java.dev.typecast.ot.table.Charstring;
+import net.java.dev.typecast.t2.Charstring;
import net.java.dev.typecast.ot.table.GsubTable;
import net.java.dev.typecast.ot.table.ID;
import net.java.dev.typecast.ot.table.LangSys;
import net.java.dev.typecast.ot.table.Lookup;
import net.java.dev.typecast.ot.table.LookupSubtable;
+import net.java.dev.typecast.t2.NameIndex;
import net.java.dev.typecast.ot.table.NameRecord;
import net.java.dev.typecast.ot.table.NameTable;
import net.java.dev.typecast.ot.table.PostTable;
@@ -241,7 +242,7 @@ public class TableTreeBuilder {
}
private static void addCffTable(OTFont font, TableTreeNode parent, CffTable ct) {
- CffTable.NameIndex ni = ct.getNameIndex();
+ NameIndex ni = ct.getNameIndex();
for (int i = 0; i < ni.getCount(); ++i) {
TableTreeNode n = new TableTreeNode(
ni.getName(i),
diff --git a/src/net/java/dev/typecast/ot/Glyph.java b/src/net/java/dev/typecast/ot/Glyph.java
index 2cd36bd..8dfa015 100644
--- a/src/net/java/dev/typecast/ot/Glyph.java
+++ b/src/net/java/dev/typecast/ot/Glyph.java
@@ -53,8 +53,9 @@ package net.java.dev.typecast.ot;
import net.java.dev.typecast.ot.table.CffTable;
import net.java.dev.typecast.ot.table.GlyphDescription;
import net.java.dev.typecast.ot.table.GlyfDescript;
-import net.java.dev.typecast.ot.table.Charstring;
-import net.java.dev.typecast.ot.table.CharstringType2;
+import net.java.dev.typecast.t2.Charstring;
+import net.java.dev.typecast.t2.CharstringType2;
+import net.java.dev.typecast.t2.Index;
import net.java.dev.typecast.t2.T2Interpreter;
@@ -93,8 +94,8 @@ public class Glyph {
Charstring cs,
short lsb,
int advance,
- CffTable.Index localSubrIndex,
- CffTable.Index globalSubrIndex) {
+ Index localSubrIndex,
+ Index globalSubrIndex) {
_leftSideBearing = lsb;
_advanceWidth = advance;
if (cs instanceof CharstringType2) {
diff --git a/src/net/java/dev/typecast/ot/table/CffTable.java b/src/net/java/dev/typecast/ot/table/CffTable.java
index 2ed84e2..4136c7c 100644
--- a/src/net/java/dev/typecast/ot/table/CffTable.java
+++ b/src/net/java/dev/typecast/ot/table/CffTable.java
@@ -22,11 +22,19 @@ import java.io.ByteArrayInputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
+import net.java.dev.typecast.t2.CffFont;
+import net.java.dev.typecast.t2.Charset;
+import net.java.dev.typecast.t2.CharsetFormat0;
+import net.java.dev.typecast.t2.CharsetFormat1;
+import net.java.dev.typecast.t2.CharsetFormat2;
+import net.java.dev.typecast.t2.Charstring;
+import net.java.dev.typecast.t2.CharstringType2;
+import net.java.dev.typecast.t2.Dict;
+import net.java.dev.typecast.t2.Index;
+import net.java.dev.typecast.t2.NameIndex;
+import net.java.dev.typecast.t2.StringIndex;
+import net.java.dev.typecast.t2.TopDictIndex;
/**
* Compact Font Format Table
@@ -34,496 +42,6 @@ import java.util.Map;
*/
public class CffTable implements Table {
- public static class Dict {
-
- private final Map<Integer, Object> _entries = new HashMap<>();
- private final int[] _data;
- private int _index;
-
- protected Dict(int[] data, int offset, int length) {
- _data = data;
- _index = offset;
- while (_index < offset + length) {
- addKeyAndValueEntry();
- }
- }
-
- protected Dict(DataInput di, int length) throws IOException {
- _data = new int[length];
- for (int i = 0; i < length; ++i) {
- _data[i] = di.readUnsignedByte();
- }
- _index = 0;
- while (_index < length) {
- addKeyAndValueEntry();
- }
- }
-
- public Object getValue(int key) {
- return _entries.get(key);
- }
-
- private boolean addKeyAndValueEntry() {
- ArrayList<Object> operands = new ArrayList<>();
- Object operand = null;
- while (isOperandAtIndex()) {
- operand = nextOperand();
- operands.add(operand);
- }
- int operator = _data[_index++];
- if (operator == 12) {
- operator <<= 8;
- operator |= _data[_index++];
- }
- if (operands.size() == 1) {
- _entries.put(operator, operand);
- } else {
- _entries.put(operator, operands);
- }
- return true;
- }
-
- private boolean isOperandAtIndex() {
- int b0 = _data[_index];
- return (32 <= b0 && b0 <= 254)
- || b0 == 28
- || b0 == 29
- || b0 == 30;
- }
-
-// private boolean isOperatorAtIndex() {
-// int b0 = _data[_index];
-// return 0 <= b0 && b0 <= 21;
-// }
-
- private Object nextOperand() {
- int b0 = _data[_index];
- if (32 <= b0 && b0 <= 246) {
-
- // 1 byte integer
- ++_index;
- return b0 - 139;
- } else if (247 <= b0 && b0 <= 250) {
-
- // 2 byte integer
- int b1 = _data[_index + 1];
- _index += 2;
- return (b0 - 247) * 256 + b1 + 108;
- } else if (251 <= b0 && b0 <= 254) {
-
- // 2 byte integer
- int b1 = _data[_index + 1];
- _index += 2;
- return -(b0 - 251) * 256 - b1 - 108;
- } else if (b0 == 28) {
-
- // 3 byte integer
- int b1 = _data[_index + 1];
- int b2 = _data[_index + 2];
- _index += 3;
- return b1 << 8 | b2;
- } else if (b0 == 29) {
-
- // 5 byte integer
- int b1 = _data[_index + 1];
- int b2 = _data[_index + 2];
- int b3 = _data[_index + 3];
- int b4 = _data[_index + 4];
- _index += 5;
- return b1 << 24 | b2 << 16 | b3 << 8 | b4;
- } else if (b0 == 30) {
-
- // Real number
- StringBuilder fString = new StringBuilder();
- int nibble1 = 0;
- int nibble2 = 0;
- ++_index;
- while ((nibble1 != 0xf) && (nibble2 != 0xf)) {
- nibble1 = _data[_index] >> 4;
- nibble2 = _data[_index] & 0xf;
- ++_index;
- fString.append(decodeRealNibble(nibble1));
- fString.append(decodeRealNibble(nibble2));
- }
- return Float.valueOf(fString.toString());
- } else {
- return null;
- }
- }
-
- private String decodeRealNibble(int nibble) {
- if (nibble < 0xa) {
- return Integer.toString(nibble);
- } else if (nibble == 0xa) {
- return ".";
- } else if (nibble == 0xb) {
- return "E";
- } else if (nibble == 0xc) {
- return "E-";
- } else if (nibble == 0xe) {
- return "-";
- }
- return "";
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- Iterator<Integer> keys = _entries.keySet().iterator();
- while (keys.hasNext()) {
- Integer key = keys.next();
- if ((key & 0xc00) == 0xc00) {
- sb.append("12 ").append(key & 0xff).append(": ");
- } else {
- sb.append(key.toString()).append(": ");
- }
- sb.append(_entries.get(key).toString()).append("\n");
- }
- return sb.toString();
- }
- }
-
- public class Index {
-
- private final int _count;
- private final int _offSize;
- private final int[] _offset;
- private final int[] _data;
-
- protected Index(DataInput di) throws IOException {
- _count = di.readUnsignedShort();
- _offset = new int[_count + 1];
- _offSize = di.readUnsignedByte();
- for (int i = 0; i < _count + 1; ++i) {
- int thisOffset = 0;
- for (int j = 0; j < _offSize; ++j) {
- thisOffset |= di.readUnsignedByte() << ((_offSize - j - 1) * 8);
- }
- _offset[i] = thisOffset;
- }
- _data = new int[getDataLength()];
- for (int i = 0; i < getDataLength(); ++i) {
- _data[i] = di.readUnsignedByte();
- }
- }
-
- public final int getCount() {
- return _count;
- }
-
- public final int getOffset(int index) {
- return _offset[index];
- }
-
- public final int getDataLength() {
- return _offset[_offset.length - 1] - 1;
- }
-
- public final int[] getData() {
- return _data;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("DICT\n");
- sb.append("count: ").append(_count).append("\n");
- sb.append("offSize: ").append(_offSize).append("\n");
- for (int i = 0; i < _count + 1; ++i) {
- sb.append("offset[").append(i).append("]: ").append(_offset[i]).append("\n");
- }
- sb.append("data:");
- for (int i = 0; i < _data.length; ++i) {
- if (i % 8 == 0) {
- sb.append("\n");
- } else {
- sb.append(" ");
- }
- sb.append(_data[i]);
- }
- sb.append("\n");
- return sb.toString();
- }
- }
-
- public class TopDictIndex extends Index {
-
- protected TopDictIndex(DataInput di) throws IOException {
- super(di);
- }
-
- public Dict getTopDict(int index) {
- int offset = getOffset(index) - 1;
- int len = getOffset(index + 1) - offset - 1;
- return new Dict(getData(), offset, len);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < getCount(); ++i) {
- sb.append(getTopDict(i).toString()).append("\n");
- }
- return sb.toString();
- }
- }
-
- public class NameIndex extends Index {
-
- protected NameIndex(DataInput di) throws IOException {
- super(di);
- }
-
- public String getName(int index) {
- String name = null;
- int offset = getOffset(index) - 1;
- int len = getOffset(index + 1) - offset - 1;
-
- // Ensure the name hasn't been deleted
- if (getData()[offset] != 0) {
- StringBuilder sb = new StringBuilder();
- for (int i = offset; i < offset + len; ++i) {
- sb.append((char) getData()[i]);
- }
- name = sb.toString();
- } else {
- name = "DELETED NAME";
- }
- return name;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < getCount(); ++i) {
- sb.append(getName(i)).append("\n");
- }
- return sb.toString();
- }
- }
-
- public class StringIndex extends Index {
-
- protected StringIndex(DataInput di) throws IOException {
- super(di);
- }
-
- public String getString(int index) {
- if (index < CffStandardStrings.standardStrings.length) {
- return CffStandardStrings.standardStrings[index];
- } else {
- index -= CffStandardStrings.standardStrings.length;
- if (index >= getCount()) {
- return null;
- }
- int offset = getOffset(index) - 1;
- int len = getOffset(index + 1) - offset - 1;
-
- StringBuilder sb = new StringBuilder();
- for (int i = offset; i < offset + len; ++i) {
- sb.append((char) getData()[i]);
- }
- return sb.toString();
- }
- }
-
- @Override
- public String toString() {
- int nonStandardBase = CffStandardStrings.standardStrings.length;
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < getCount(); ++i) {
- sb.append(nonStandardBase + i).append(": ");
- sb.append(getString(nonStandardBase + i)).append("\n");
- }
- return sb.toString();
- }
- }
-
- private class CharsetRange {
-
- private int _first;
- private int _left;
-
- public final int getFirst() {
- return _first;
- }
-
- protected final void setFirst(int first) {
- _first = first;
- }
-
- public final int getLeft() {
- return _left;
- }
-
- protected final void setLeft(int left) {
- _left = left;
- }
- }
-
- private class CharsetRange1 extends CharsetRange {
-
- protected CharsetRange1(DataInput di) throws IOException {
- setFirst(di.readUnsignedShort());
- setLeft(di.readUnsignedByte());
- }
- }
-
- private class CharsetRange2 extends CharsetRange {
-
- protected CharsetRange2(DataInput di) throws IOException {
- setFirst(di.readUnsignedShort());
- setLeft(di.readUnsignedShort());
- }
- }
-
- private abstract class Charset {
-
- public abstract int getFormat();
-
- public abstract int getSID(int gid);
- }
-
- private class CharsetFormat0 extends Charset {
-
- private final int[] _glyph;
-
- protected CharsetFormat0(DataInput di, int glyphCount) throws IOException {
- _glyph = new int[glyphCount - 1]; // minus 1 because .notdef is omitted
- for (int i = 0; i < glyphCount - 1; ++i) {
- _glyph[i] = di.readUnsignedShort();
- }
- }
-
- @Override
- public int getFormat() {
- return 0;
- }
-
- @Override
- public int getSID(int gid) {
- if (gid == 0) {
- return 0;
- }
- return _glyph[gid - 1];
- }
- }
-
- private class CharsetFormat1 extends Charset {
-
- private final ArrayList<CharsetRange> _charsetRanges = new ArrayList<>();
-
- protected CharsetFormat1(DataInput di, int glyphCount) throws IOException {
- int glyphsCovered = glyphCount - 1; // minus 1 because .notdef is omitted
- while (glyphsCovered > 0) {
- CharsetRange range = new CharsetRange1(di);
- _charsetRanges.add(range);
- glyphsCovered -= range.getLeft() + 1;
- }
- }
-
- @Override
- public int getFormat() {
- return 1;
- }
-
- @Override
- public int getSID(int gid) {
- if (gid == 0) {
- return 0;
- }
-
- // Count through the ranges to find the one of interest
- int count = 1;
- for (CharsetRange range : _charsetRanges) {
- if (gid <= range.getLeft() + count) {
- int sid = gid - count + range.getFirst();
- return sid;
- }
- count += range.getLeft() + 1;
- }
- return 0;
- }
- }
-
- private class CharsetFormat2 extends Charset {
-
- private final ArrayList<CharsetRange> _charsetRanges = new ArrayList<>();
-
- protected CharsetFormat2(DataInput di, int glyphCount) throws IOException {
- int glyphsCovered = glyphCount - 1; // minus 1 because .notdef is omitted
- while (glyphsCovered > 0) {
- CharsetRange range = new CharsetRange2(di);
- _charsetRanges.add(range);
- glyphsCovered -= range.getLeft() + 1;
- }
- }
-
- @Override
- public int getFormat() {
- return 2;
- }
-
- @Override
- public int getSID(int gid) {
- if (gid == 0) {
- return 0;
- }
-
- // Count through the ranges to find the one of interest
- int count = 1;
- for (CharsetRange range : _charsetRanges) {
- if (gid <= range.getLeft() + count) {
- int sid = gid - count + range.getFirst();
- return sid;
- }
- count += range.getLeft() + 1;
- }
- return 0;
- }
- }
-
- public class CffFont {
- private Index _charStringsIndex;
- private Dict _privateDict;
- private Index _localSubrsIndex;
- private Charset _charset;
- private Charstring[] _charstrings;
-
- public CffFont(
- Index charStringsIndex,
- Dict privateDict,
- Index localSubrsIndex,
- Charset charset,
- Charstring[] charstrings) {
- _charStringsIndex = charStringsIndex;
- _privateDict = privateDict;
- _localSubrsIndex = localSubrsIndex;
- _charset = charset;
- _charstrings = charstrings;
- }
-
- public Index getCharStringsIndex() {
- return _charStringsIndex;
- }
-
- public Dict getPrivateDict() {
- return _privateDict;
- }
-
- public Index getLocalSubrsIndex() {
- return _localSubrsIndex;
- }
-
- public Charset getCharset() {
- return _charset;
- }
-
- public Charstring[] getCharstrings() {
- return _charstrings;
- }
- }
-
private DirectoryEntry _de;
private int _major;
private int _minor;
diff --git a/src/net/java/dev/typecast/t2/CffFont.java b/src/net/java/dev/typecast/t2/CffFont.java
new file mode 100644
index 0000000..68d8bda
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CffFont.java
@@ -0,0 +1,64 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CffFont {
+
+ private final Index _charStringsIndex;
+ private final Dict _privateDict;
+ private final Index _localSubrsIndex;
+ private final Charset _charset;
+ private final Charstring[] _charstrings;
+
+ public CffFont(
+ Index charStringsIndex,
+ Dict privateDict,
+ Index localSubrsIndex,
+ Charset charset,
+ Charstring[] charstrings) {
+ _charStringsIndex = charStringsIndex;
+ _privateDict = privateDict;
+ _localSubrsIndex = localSubrsIndex;
+ _charset = charset;
+ _charstrings = charstrings;
+ }
+
+ public Index getCharStringsIndex() {
+ return _charStringsIndex;
+ }
+
+ public Dict getPrivateDict() {
+ return _privateDict;
+ }
+
+ public Index getLocalSubrsIndex() {
+ return _localSubrsIndex;
+ }
+
+ public Charset getCharset() {
+ return _charset;
+ }
+
+ public Charstring[] getCharstrings() {
+ return _charstrings;
+ }
+}
diff --git a/src/net/java/dev/typecast/ot/table/CffStandardStrings.java b/src/net/java/dev/typecast/t2/CffStandardStrings.java
index 326f115..a2f8cca 100644
--- a/src/net/java/dev/typecast/ot/table/CffStandardStrings.java
+++ b/src/net/java/dev/typecast/t2/CffStandardStrings.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package net.java.dev.typecast.ot.table;
+package net.java.dev.typecast.t2;
/**
* Compact Font Format Standard Strings. As per Appendix A of the Adobe
diff --git a/src/net/java/dev/typecast/t2/Charset.java b/src/net/java/dev/typecast/t2/Charset.java
new file mode 100644
index 0000000..e221828
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/Charset.java
@@ -0,0 +1,33 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public abstract class Charset {
+
+ Charset() {
+ }
+
+ public abstract int getFormat();
+
+ public abstract int getSID(int gid);
+
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetFormat0.java b/src/net/java/dev/typecast/t2/CharsetFormat0.java
new file mode 100644
index 0000000..dfca79b
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetFormat0.java
@@ -0,0 +1,51 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetFormat0 extends Charset {
+
+ private final int[] _glyph;
+
+ public CharsetFormat0(DataInput di, int glyphCount) throws IOException {
+ _glyph = new int[glyphCount - 1]; // minus 1 because .notdef is omitted
+ for (int i = 0; i < glyphCount - 1; ++i) {
+ _glyph[i] = di.readUnsignedShort();
+ }
+ } // minus 1 because .notdef is omitted
+
+ @Override
+ public int getFormat() {
+ return 0;
+ }
+
+ @Override
+ public int getSID(int gid) {
+ if (gid == 0) {
+ return 0;
+ }
+ return _glyph[gid - 1];
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetFormat1.java b/src/net/java/dev/typecast/t2/CharsetFormat1.java
new file mode 100644
index 0000000..1a0a64f
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetFormat1.java
@@ -0,0 +1,63 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetFormat1 extends Charset {
+
+ private final ArrayList<CharsetRange> _charsetRanges = new ArrayList<>();
+
+ public CharsetFormat1(DataInput di, int glyphCount) throws IOException {
+ int glyphsCovered = glyphCount - 1; // minus 1 because .notdef is omitted
+ while (glyphsCovered > 0) {
+ CharsetRange range = new CharsetRange1(di);
+ _charsetRanges.add(range);
+ glyphsCovered -= range.getLeft() + 1;
+ }
+ }
+
+ @Override
+ public int getFormat() {
+ return 1;
+ }
+
+ @Override
+ public int getSID(int gid) {
+ if (gid == 0) {
+ return 0;
+ }
+
+ // Count through the ranges to find the one of interest
+ int count = 1;
+ for (CharsetRange range : _charsetRanges) {
+ if (gid <= range.getLeft() + count) {
+ int sid = gid - count + range.getFirst();
+ return sid;
+ }
+ count += range.getLeft() + 1;
+ }
+ return 0;
+ }
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetFormat2.java b/src/net/java/dev/typecast/t2/CharsetFormat2.java
new file mode 100644
index 0000000..6ccdd86
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetFormat2.java
@@ -0,0 +1,63 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetFormat2 extends Charset {
+
+ private final ArrayList<CharsetRange> _charsetRanges = new ArrayList<>();
+
+ public CharsetFormat2(DataInput di, int glyphCount) throws IOException {
+ int glyphsCovered = glyphCount - 1; // minus 1 because .notdef is omitted
+ while (glyphsCovered > 0) {
+ CharsetRange range = new CharsetRange2(di);
+ _charsetRanges.add(range);
+ glyphsCovered -= range.getLeft() + 1;
+ }
+ }
+
+ @Override
+ public int getFormat() {
+ return 2;
+ }
+
+ @Override
+ public int getSID(int gid) {
+ if (gid == 0) {
+ return 0;
+ }
+
+ // Count through the ranges to find the one of interest
+ int count = 1;
+ for (CharsetRange range : _charsetRanges) {
+ if (gid <= range.getLeft() + count) {
+ int sid = gid - count + range.getFirst();
+ return sid;
+ }
+ count += range.getLeft() + 1;
+ }
+ return 0;
+ }
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetRange.java b/src/net/java/dev/typecast/t2/CharsetRange.java
new file mode 100644
index 0000000..452adc3
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetRange.java
@@ -0,0 +1,48 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetRange {
+
+ private int _first;
+ private int _left;
+
+ CharsetRange() {
+ }
+
+ public final int getFirst() {
+ return _first;
+ }
+
+ protected final void setFirst(int first) {
+ _first = first;
+ }
+
+ public final int getLeft() {
+ return _left;
+ }
+
+ protected final void setLeft(int left) {
+ _left = left;
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetRange1.java b/src/net/java/dev/typecast/t2/CharsetRange1.java
new file mode 100644
index 0000000..dff99d8
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetRange1.java
@@ -0,0 +1,34 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetRange1 extends CharsetRange {
+
+ protected CharsetRange1(DataInput di) throws IOException {
+ setFirst(di.readUnsignedShort());
+ setLeft(di.readUnsignedByte());
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/CharsetRange2.java b/src/net/java/dev/typecast/t2/CharsetRange2.java
new file mode 100644
index 0000000..18b2baf
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/CharsetRange2.java
@@ -0,0 +1,34 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class CharsetRange2 extends CharsetRange {
+
+ protected CharsetRange2(DataInput di) throws IOException {
+ setFirst(di.readUnsignedShort());
+ setLeft(di.readUnsignedShort());
+ }
+
+}
diff --git a/src/net/java/dev/typecast/ot/table/Charstring.java b/src/net/java/dev/typecast/t2/Charstring.java
index 65fcdef..36b8f77 100644
--- a/src/net/java/dev/typecast/ot/table/Charstring.java
+++ b/src/net/java/dev/typecast/t2/Charstring.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package net.java.dev.typecast.ot.table;
+package net.java.dev.typecast.t2;
/**
* CFF Charstring
diff --git a/src/net/java/dev/typecast/ot/table/CharstringType2.java b/src/net/java/dev/typecast/t2/CharstringType2.java
index 31d0d61..eb8bc69 100644
--- a/src/net/java/dev/typecast/ot/table/CharstringType2.java
+++ b/src/net/java/dev/typecast/t2/CharstringType2.java
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-package net.java.dev.typecast.ot.table;
+package net.java.dev.typecast.t2;
/**
* CFF Type 2 Charstring
@@ -114,7 +114,7 @@ public class CharstringType2 extends Charstring {
* @param data
* @param offset
* @param length */
- protected CharstringType2(
+ public CharstringType2(
int index,
String name,
int[] data,
diff --git a/src/net/java/dev/typecast/t2/Dict.java b/src/net/java/dev/typecast/t2/Dict.java
new file mode 100644
index 0000000..d4c6d79
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/Dict.java
@@ -0,0 +1,169 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class Dict {
+
+ private final Map<Integer, Object> _entries = new HashMap<>();
+ private final int[] _data;
+ private int _index;
+
+ public Dict(int[] data, int offset, int length) {
+ _data = data;
+ _index = offset;
+ while (_index < offset + length) {
+ addKeyAndValueEntry();
+ }
+ }
+
+ public Dict(DataInput di, int length) throws IOException {
+ _data = new int[length];
+ for (int i = 0; i < length; ++i) {
+ _data[i] = di.readUnsignedByte();
+ }
+ _index = 0;
+ while (_index < length) {
+ addKeyAndValueEntry();
+ }
+ }
+
+ public Object getValue(int key) {
+ return _entries.get(key);
+ }
+
+ private boolean addKeyAndValueEntry() {
+ ArrayList<Object> operands = new ArrayList<>();
+ Object operand = null;
+ while (isOperandAtIndex()) {
+ operand = nextOperand();
+ operands.add(operand);
+ }
+ int operator = _data[_index++];
+ if (operator == 12) {
+ operator <<= 8;
+ operator |= _data[_index++];
+ }
+ if (operands.size() == 1) {
+ _entries.put(operator, operand);
+ } else {
+ _entries.put(operator, operands);
+ }
+ return true;
+ }
+
+ private boolean isOperandAtIndex() {
+ int b0 = _data[_index];
+ return (32 <= b0 && b0 <= 254) || b0 == 28 || b0 == 29 || b0 == 30;
+ }
+
+ // private boolean isOperatorAtIndex() {
+ // int b0 = _data[_index];
+ // return 0 <= b0 && b0 <= 21;
+ // }
+ private Object nextOperand() {
+ int b0 = _data[_index];
+ if (32 <= b0 && b0 <= 246) {
+ // 1 byte integer
+ ++_index;
+ return b0 - 139;
+ } else if (247 <= b0 && b0 <= 250) {
+ // 2 byte integer
+ int b1 = _data[_index + 1];
+ _index += 2;
+ return (b0 - 247) * 256 + b1 + 108;
+ } else if (251 <= b0 && b0 <= 254) {
+ // 2 byte integer
+ int b1 = _data[_index + 1];
+ _index += 2;
+ return -(b0 - 251) * 256 - b1 - 108;
+ } else if (b0 == 28) {
+ // 3 byte integer
+ int b1 = _data[_index + 1];
+ int b2 = _data[_index + 2];
+ _index += 3;
+ return b1 << 8 | b2;
+ } else if (b0 == 29) {
+ // 5 byte integer
+ int b1 = _data[_index + 1];
+ int b2 = _data[_index + 2];
+ int b3 = _data[_index + 3];
+ int b4 = _data[_index + 4];
+ _index += 5;
+ return b1 << 24 | b2 << 16 | b3 << 8 | b4;
+ } else if (b0 == 30) {
+ // Real number
+ StringBuilder fString = new StringBuilder();
+ int nibble1 = 0;
+ int nibble2 = 0;
+ ++_index;
+ while ((nibble1 != 0xf) && (nibble2 != 0xf)) {
+ nibble1 = _data[_index] >> 4;
+ nibble2 = _data[_index] & 0xf;
+ ++_index;
+ fString.append(decodeRealNibble(nibble1));
+ fString.append(decodeRealNibble(nibble2));
+ }
+ return Float.valueOf(fString.toString());
+ } else {
+ return null;
+ }
+ }
+
+ private String decodeRealNibble(int nibble) {
+ if (nibble < 0xa) {
+ return Integer.toString(nibble);
+ } else if (nibble == 0xa) {
+ return ".";
+ } else if (nibble == 0xb) {
+ return "E";
+ } else if (nibble == 0xc) {
+ return "E-";
+ } else if (nibble == 0xe) {
+ return "-";
+ }
+ return "";
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ Iterator<Integer> keys = _entries.keySet().iterator();
+ while (keys.hasNext()) {
+ Integer key = keys.next();
+ if ((key & 0xc00) == 0xc00) {
+ sb.append("12 ").append(key & 0xff).append(": ");
+ } else {
+ sb.append(key.toString()).append(": ");
+ }
+ sb.append(_entries.get(key).toString()).append("\n");
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/Index.java b/src/net/java/dev/typecast/t2/Index.java
new file mode 100644
index 0000000..dcad83b
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/Index.java
@@ -0,0 +1,89 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class Index {
+
+ private final int _count;
+ private final int _offSize;
+ private final int[] _offset;
+ private final int[] _data;
+
+ public Index(DataInput di) throws IOException {
+ _count = di.readUnsignedShort();
+ _offset = new int[_count + 1];
+ _offSize = di.readUnsignedByte();
+ for (int i = 0; i < _count + 1; ++i) {
+ int thisOffset = 0;
+ for (int j = 0; j < _offSize; ++j) {
+ thisOffset |= di.readUnsignedByte() << ((_offSize - j - 1) * 8);
+ }
+ _offset[i] = thisOffset;
+ }
+ _data = new int[getDataLength()];
+ for (int i = 0; i < getDataLength(); ++i) {
+ _data[i] = di.readUnsignedByte();
+ }
+ }
+
+ public final int getCount() {
+ return _count;
+ }
+
+ public final int getOffset(int index) {
+ return _offset[index];
+ }
+
+ public final int getDataLength() {
+ return _offset[_offset.length - 1] - 1;
+ }
+
+ public final int[] getData() {
+ return _data;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("DICT\n");
+ sb.append("count: ").append(_count).append("\n");
+ sb.append("offSize: ").append(_offSize).append("\n");
+ for (int i = 0; i < _count + 1; ++i) {
+ sb.append("offset[").append(i).append("]: ").append(_offset[i]).append("\n");
+ }
+ sb.append("data:");
+ for (int i = 0; i < _data.length; ++i) {
+ if (i % 8 == 0) {
+ sb.append("\n");
+ } else {
+ sb.append(" ");
+ }
+ sb.append(_data[i]);
+ }
+ sb.append("\n");
+ return sb.toString();
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/NameIndex.java b/src/net/java/dev/typecast/t2/NameIndex.java
new file mode 100644
index 0000000..3831070
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/NameIndex.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 dschweinsberg.
+ *
+ * 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class NameIndex extends Index {
+
+ public NameIndex(DataInput di) throws IOException {
+ super(di);
+ }
+
+ public String getName(int index) {
+ String name = null;
+ int offset = getOffset(index) - 1;
+ int len = getOffset(index + 1) - offset - 1;
+ // Ensure the name hasn't been deleted
+ if (getData()[offset] != 0) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = offset; i < offset + len; ++i) {
+ sb.append((char) getData()[i]);
+ }
+ name = sb.toString();
+ } else {
+ name = "DELETED NAME";
+ }
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < getCount(); ++i) {
+ sb.append(getName(i)).append("\n");
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/StringIndex.java b/src/net/java/dev/typecast/t2/StringIndex.java
new file mode 100644
index 0000000..ece39ab
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/StringIndex.java
@@ -0,0 +1,62 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class StringIndex extends Index {
+
+ public StringIndex(DataInput di) throws IOException {
+ super(di);
+ }
+
+ public String getString(int index) {
+ if (index < CffStandardStrings.standardStrings.length) {
+ return CffStandardStrings.standardStrings[index];
+ } else {
+ index -= CffStandardStrings.standardStrings.length;
+ if (index >= getCount()) {
+ return null;
+ }
+ int offset = getOffset(index) - 1;
+ int len = getOffset(index + 1) - offset - 1;
+ StringBuilder sb = new StringBuilder();
+ for (int i = offset; i < offset + len; ++i) {
+ sb.append((char) getData()[i]);
+ }
+ return sb.toString();
+ }
+ }
+
+ @Override
+ public String toString() {
+ int nonStandardBase = CffStandardStrings.standardStrings.length;
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < getCount(); ++i) {
+ sb.append(nonStandardBase + i).append(": ");
+ sb.append(getString(nonStandardBase + i)).append("\n");
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/src/net/java/dev/typecast/t2/T2Interpreter.java b/src/net/java/dev/typecast/t2/T2Interpreter.java
index c3d05ae..f15856d 100644
--- a/src/net/java/dev/typecast/t2/T2Interpreter.java
+++ b/src/net/java/dev/typecast/t2/T2Interpreter.java
@@ -20,8 +20,6 @@ package net.java.dev.typecast.t2;
import java.util.ArrayList;
import net.java.dev.typecast.ot.Point;
-import net.java.dev.typecast.ot.table.CffTable;
-import net.java.dev.typecast.ot.table.CharstringType2;
/**
* Type 2 Charstring Interpreter. Operator descriptions are quoted from
@@ -43,11 +41,11 @@ public class T2Interpreter {
private int _stemCount = 0;
private ArrayList<Point> _points;
- private final CffTable.Index _localSubrIndex;
- private final CffTable.Index _globalSubrIndex;
+ private final Index _localSubrIndex;
+ private final Index _globalSubrIndex;
/** Creates a new instance of T2Interpreter */
- public T2Interpreter(CffTable.Index localSubrIndex, CffTable.Index globalSubrIndex) {
+ public T2Interpreter(Index localSubrIndex, Index globalSubrIndex) {
_localSubrIndex = localSubrIndex;
_globalSubrIndex = globalSubrIndex;
}
diff --git a/src/net/java/dev/typecast/t2/TopDictIndex.java b/src/net/java/dev/typecast/t2/TopDictIndex.java
new file mode 100644
index 0000000..cd22466
--- /dev/null
+++ b/src/net/java/dev/typecast/t2/TopDictIndex.java
@@ -0,0 +1,48 @@
+/*
+ * Typecast - The Font Development Environment
+ *
+ * Copyright (c) 2004-2015 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.io.DataInput;
+import java.io.IOException;
+
+/**
+ *
+ * @author dschweinsberg
+ */
+public class TopDictIndex extends Index {
+
+ public TopDictIndex(DataInput di) throws IOException {
+ super(di);
+ }
+
+ public Dict getTopDict(int index) {
+ int offset = getOffset(index) - 1;
+ int len = getOffset(index + 1) - offset - 1;
+ return new Dict(getData(), offset, len);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < getCount(); ++i) {
+ sb.append(getTopDict(i).toString()).append("\n");
+ }
+ return sb.toString();
+ }
+
+}