aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Schweinsberg <[email protected]>2015-12-27 14:51:46 -0700
committerDavid Schweinsberg <[email protected]>2015-12-27 14:51:46 -0700
commitb2d29d276feb057409d7b2abb30f218d4061b7c5 (patch)
treeb493e092c0d2906e821bebc4445faff6602f1a57 /src
parentcebb5365de45b22f18284079056a8b78b8941093 (diff)
New CffFont class encapulates an individual font within a CFF table. T2Interpreter references local and global subrs.
Diffstat (limited to 'src')
-rw-r--r--src/net/java/dev/typecast/app/editor/GlyphPanel.java28
-rw-r--r--src/net/java/dev/typecast/ot/Glyph.java13
-rw-r--r--src/net/java/dev/typecast/ot/OTFont.java31
-rw-r--r--src/net/java/dev/typecast/ot/table/CffTable.java117
-rw-r--r--src/net/java/dev/typecast/ot/table/CharstringType2.java18
-rw-r--r--src/net/java/dev/typecast/ot/table/Table.java1
-rw-r--r--src/net/java/dev/typecast/t2/T2Interpreter.java45
7 files changed, 162 insertions, 91 deletions
diff --git a/src/net/java/dev/typecast/app/editor/GlyphPanel.java b/src/net/java/dev/typecast/app/editor/GlyphPanel.java
index fcdb99c..977d351 100644
--- a/src/net/java/dev/typecast/app/editor/GlyphPanel.java
+++ b/src/net/java/dev/typecast/app/editor/GlyphPanel.java
@@ -1,9 +1,7 @@
/*
- * $Id: GlyphPanel.java,v 1.4 2007-02-21 12:22:55 davidsch Exp $
- *
* Typecast - The Font Development Environment
*
- * Copyright (c) 2004-2007 David Schweinsberg
+ * 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.
@@ -22,38 +20,27 @@ package net.java.dev.typecast.app.editor;
import java.awt.BorderLayout;
import java.awt.Color;
-
-import java.util.Properties;
-
import javax.swing.JPanel;
import javax.swing.JScrollPane;
-
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.ot.table.GlyphDescription;
-import net.java.dev.typecast.app.editor.GlyphPanelToolBar;
-import net.java.dev.typecast.app.editor.GlyphPanelStatusBar;
-
/**
*
* @author <a href="mailto:[email protected]">David Schweinsberg</a>
- * @version $Id: GlyphPanel.java,v 1.4 2007-02-21 12:22:55 davidsch Exp $
*/
public class GlyphPanel extends JPanel implements EditorView {
private static final long serialVersionUID = 1L;
- private EditorPrefs _prefs;
- private GlyphEdit _glyphEdit = new GlyphEdit();
- private GlyphPanelToolBar _toolBar = new GlyphPanelToolBar();
- private GlyphPanelStatusBar _glyphPanelStatusBar =
+ private final EditorPrefs _prefs;
+ private final GlyphEdit _glyphEdit = new GlyphEdit();
+ private final GlyphPanelToolBar _toolBar = new GlyphPanelToolBar();
+ private final GlyphPanelStatusBar _glyphPanelStatusBar =
new GlyphPanelStatusBar();
/** Creates new GlyphPanel */
@@ -83,6 +70,7 @@ public class GlyphPanel extends JPanel implements EditorView {
* The GlyphPanel deals with GlyphDescriptions, so the Object parameter must
* implement the GlyphDescription interface.
*/
+ @Override
public void setModel(OTFont font, Object obj) {
if (obj instanceof GlyphDescription) {
_glyphEdit.setFont(font);
@@ -98,7 +86,9 @@ public class GlyphPanel extends JPanel implements EditorView {
_glyphEdit.setGlyph(new Glyph(
cs,
font.getHmtxTable().getLeftSideBearing(cs.getIndex()),
- font.getHmtxTable().getAdvanceWidth(cs.getIndex())));
+ font.getHmtxTable().getAdvanceWidth(cs.getIndex()),
+ font.getCffTable().getFont(cs.getIndex()).getLocalSubrsIndex(),
+ font.getCffTable().getGlobalSubrIndex()));
}
}
diff --git a/src/net/java/dev/typecast/ot/Glyph.java b/src/net/java/dev/typecast/ot/Glyph.java
index 9a7e3f9..2cd36bd 100644
--- a/src/net/java/dev/typecast/ot/Glyph.java
+++ b/src/net/java/dev/typecast/ot/Glyph.java
@@ -50,6 +50,7 @@
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;
@@ -59,7 +60,6 @@ import net.java.dev.typecast.t2.T2Interpreter;
/**
* An individual glyph within a font.
- * @version $Id: Glyph.java,v 1.3 2007-02-21 12:23:54 davidsch Exp $
* @author <a href="mailto:[email protected]">David Schweinsberg</a>
*/
public class Glyph {
@@ -86,12 +86,19 @@ public class Glyph {
* @param cs The Charstring describing the glyph.
* @param lsb The Left Side Bearing.
* @param advance The advance width.
+ * @param localSubrIndex
+ * @param globalSubrIndex
*/
- public Glyph(Charstring cs, short lsb, int advance) {
+ public Glyph(
+ Charstring cs,
+ short lsb,
+ int advance,
+ CffTable.Index localSubrIndex,
+ CffTable.Index globalSubrIndex) {
_leftSideBearing = lsb;
_advanceWidth = advance;
if (cs instanceof CharstringType2) {
- T2Interpreter t2i = new T2Interpreter();
+ T2Interpreter t2i = new T2Interpreter(localSubrIndex, globalSubrIndex);
_points = t2i.execute((CharstringType2) cs);
} else {
//throw unsupported charstring type
diff --git a/src/net/java/dev/typecast/ot/OTFont.java b/src/net/java/dev/typecast/ot/OTFont.java
index b0752e7..90980be 100644
--- a/src/net/java/dev/typecast/ot/OTFont.java
+++ b/src/net/java/dev/typecast/ot/OTFont.java
@@ -52,13 +52,9 @@ package net.java.dev.typecast.ot;
import java.io.DataInputStream;
import java.io.IOException;
-
-import net.java.dev.typecast.ot.table.DirectoryEntry;
-import net.java.dev.typecast.ot.table.TTCHeader;
-import net.java.dev.typecast.ot.table.TableDirectory;
-import net.java.dev.typecast.ot.table.Table;
-import net.java.dev.typecast.ot.table.Os2Table;
+import net.java.dev.typecast.ot.table.CffTable;
import net.java.dev.typecast.ot.table.CmapTable;
+import net.java.dev.typecast.ot.table.DirectoryEntry;
import net.java.dev.typecast.ot.table.GlyfTable;
import net.java.dev.typecast.ot.table.HeadTable;
import net.java.dev.typecast.ot.table.HheaTable;
@@ -66,21 +62,24 @@ import net.java.dev.typecast.ot.table.HmtxTable;
import net.java.dev.typecast.ot.table.LocaTable;
import net.java.dev.typecast.ot.table.MaxpTable;
import net.java.dev.typecast.ot.table.NameTable;
+import net.java.dev.typecast.ot.table.Os2Table;
import net.java.dev.typecast.ot.table.PostTable;
-import net.java.dev.typecast.ot.table.VheaTable;
+import net.java.dev.typecast.ot.table.Table;
+import net.java.dev.typecast.ot.table.TableDirectory;
import net.java.dev.typecast.ot.table.TableFactory;
+import net.java.dev.typecast.ot.table.VheaTable;
/**
* The TrueType font.
- * @version $Id: OTFont.java,v 1.6 2007-01-31 01:49:18 davidsch Exp $
* @author <a href="mailto:[email protected]">David Schweinsberg</a>
*/
public class OTFont {
- private OTFontCollection _fc;
+ private final OTFontCollection _fc;
private TableDirectory _tableDirectory = null;
private Table[] _tables;
private Os2Table _os2;
+ private CffTable _cff;
private CmapTable _cmap;
private GlyfTable _glyf;
private HeadTable _head;
@@ -100,9 +99,9 @@ public class OTFont {
}
public Table getTable(int tableType) {
- for (int i = 0; i < _tables.length; i++) {
- if ((_tables[i] != null) && (_tables[i].getType() == tableType)) {
- return _tables[i];
+ for (Table _table : _tables) {
+ if ((_table != null) && (_table.getType() == tableType)) {
+ return _table;
}
}
return null;
@@ -112,6 +111,10 @@ public class OTFont {
return _os2;
}
+ public CffTable getCffTable() {
+ return _cff;
+ }
+
public CmapTable getCmapTable() {
return _cmap;
}
@@ -194,8 +197,9 @@ public class OTFont {
* offset is retrieved from the resource headers.
* @param tablesOrigin The point the table offsets are calculated from.
* Once again, in a regular TTF file, this will be zero. In a TTC is is
- * also zero, but within a Mac resource, it is the beggining of the
+ * also zero, but within a Mac resource, it is the beginning of the
* individual font resource data.
+ * @throws java.io.IOException
*/
protected void read(
DataInputStream dis,
@@ -244,6 +248,7 @@ public class OTFont {
// Get references to commonly used tables (these happen to be all the
// required tables)
+ _cff = (CffTable) getTable(Table.CFF);
_cmap = (CmapTable) getTable(Table.cmap);
_hmtx = (HmtxTable) getTable(Table.hmtx);
_name = (NameTable) getTable(Table.name);
diff --git a/src/net/java/dev/typecast/ot/table/CffTable.java b/src/net/java/dev/typecast/ot/table/CffTable.java
index 0eb56e0..2ed84e2 100644
--- a/src/net/java/dev/typecast/ot/table/CffTable.java
+++ b/src/net/java/dev/typecast/ot/table/CffTable.java
@@ -483,6 +483,47 @@ public class CffTable implements Table {
}
}
+ 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;
@@ -492,11 +533,7 @@ public class CffTable implements Table {
private TopDictIndex _topDictIndex;
private StringIndex _stringIndex;
private Index _globalSubrIndex;
- private Index _charStringsIndexArray[];
- private Charset[] _charsets;
- private Charstring[][] _charstringsArray;
- private Dict _privateDictArray[];
- private Index _localSubrsIndexArray[];
+ private CffFont[] _fonts;
private byte[] _buf;
@@ -531,17 +568,21 @@ public class CffTable implements Table {
// Global Subr INDEX
_globalSubrIndex = new Index(di2);
+ // TESTING
+ Charstring gscs = new CharstringType2(
+ 0,
+ "Global subrs",
+ _globalSubrIndex.getData(),
+ _globalSubrIndex.getOffset(0) - 1,
+ _globalSubrIndex.getDataLength());
+ System.out.println(gscs.toString());
+
// Encodings go here -- but since this is an OpenType font will this
// not always be a CIDFont? In which case there are no encodings
// within the CFF data.
// Load each of the fonts
- // TODO Bundle the following into an individual font class
- _charStringsIndexArray = new Index[_topDictIndex.getCount()];
- _charsets = new Charset[_topDictIndex.getCount()];
- _charstringsArray = new Charstring[_topDictIndex.getCount()][];
- _privateDictArray = new Dict[_topDictIndex.getCount()];
- _localSubrsIndexArray = new Index[_topDictIndex.getCount()];
+ _fonts = new CffFont[_topDictIndex.getCount()];
for (int i = 0; i < _topDictIndex.getCount(); ++i) {
// Charstrings INDEX
@@ -549,51 +590,53 @@ public class CffTable implements Table {
// of glyphs
Integer charStringsOffset = (Integer) _topDictIndex.getTopDict(i).getValue(17);
di2 = getDataInputForOffset(charStringsOffset);
- _charStringsIndexArray[i] = new Index(di2);
- int glyphCount = _charStringsIndexArray[i].getCount();
+ Index charStringsIndex = new Index(di2);
+ int glyphCount = charStringsIndex.getCount();
// Private DICT
List<Integer> privateSizeAndOffset = (List<Integer>) _topDictIndex.getTopDict(i).getValue(18);
di2 = getDataInputForOffset(privateSizeAndOffset.get(1));
- _privateDictArray[i] = new Dict(di2, privateSizeAndOffset.get(0));
+ Dict privateDict = new Dict(di2, privateSizeAndOffset.get(0));
// Local Subrs INDEX
- Integer localSubrsOffset = (Integer) _privateDictArray[i].getValue(19);
+ Index localSubrsIndex = null;
+ Integer localSubrsOffset = (Integer) privateDict.getValue(19);
if (localSubrsOffset != null) {
di2 = getDataInputForOffset(privateSizeAndOffset.get(1) + localSubrsOffset);
- _localSubrsIndexArray[i] = new Index(di2);
+ localSubrsIndex = new Index(di2);
}
// Charsets
+ Charset charset = null;
Integer charsetOffset = (Integer) _topDictIndex.getTopDict(i).getValue(15);
di2 = getDataInputForOffset(charsetOffset);
int format = di2.readUnsignedByte();
switch (format) {
case 0:
- _charsets[i] = new CharsetFormat0(di2, glyphCount);
+ charset = new CharsetFormat0(di2, glyphCount);
break;
case 1:
- _charsets[i] = new CharsetFormat1(di2, glyphCount);
+ charset = new CharsetFormat1(di2, glyphCount);
break;
case 2:
- _charsets[i] = new CharsetFormat2(di2, glyphCount);
+ charset = new CharsetFormat2(di2, glyphCount);
break;
}
// Create the charstrings
- _charstringsArray[i] = new Charstring[glyphCount];
+ Charstring[] charstrings = new Charstring[glyphCount];
for (int j = 0; j < glyphCount; ++j) {
- int offset = _charStringsIndexArray[i].getOffset(j) - 1;
- int len = _charStringsIndexArray[i].getOffset(j + 1) - offset - 1;
- _charstringsArray[i][j] = new CharstringType2(
+ int offset = charStringsIndex.getOffset(j) - 1;
+ int len = charStringsIndex.getOffset(j + 1) - offset - 1;
+ charstrings[j] = new CharstringType2(
i,
- _stringIndex.getString(_charsets[i].getSID(j)),
- _charStringsIndexArray[i].getData(),
+ _stringIndex.getString(charset.getSID(j)),
+ charStringsIndex.getData(),
offset,
- len,
- null,
- null);
+ len);
}
+
+ _fonts[i] = new CffFont(charStringsIndex, privateDict, localSubrsIndex, charset, charstrings);
}
}
@@ -607,18 +650,26 @@ public class CffTable implements Table {
return _nameIndex;
}
+ public Index getGlobalSubrIndex() {
+ return _globalSubrIndex;
+ }
+
+ public CffFont getFont(int fontIndex) {
+ return _fonts[fontIndex];
+ }
+
// public Charset getCharset(int fontIndex) {
// return _charsets[fontIndex];
// }
public Charstring getCharstring(int fontIndex, int gid) {
- return _charstringsArray[fontIndex][gid];
+ return _fonts[fontIndex].getCharstrings()[gid];
}
public int getCharstringCount(int fontIndex) {
- return _charstringsArray[fontIndex].length;
+ return _fonts[fontIndex].getCharstrings().length;
}
-
+
@Override
public int getType() {
return CFF;
@@ -636,9 +687,9 @@ public class CffTable implements Table {
sb.append(_stringIndex.toString());
sb.append("\nGlobal Subr INDEX\n");
sb.append(_globalSubrIndex.toString());
- for (int i = 0; i < _charStringsIndexArray.length; ++i) {
+ for (int i = 0; i < _fonts.length; ++i) {
sb.append("\nCharStrings INDEX ").append(i).append("\n");
- sb.append(_charStringsIndexArray[i].toString());
+ sb.append(_fonts[i].getCharStringsIndex().toString());
}
return sb.toString();
}
diff --git a/src/net/java/dev/typecast/ot/table/CharstringType2.java b/src/net/java/dev/typecast/ot/table/CharstringType2.java
index de9cf01..31d0d61 100644
--- a/src/net/java/dev/typecast/ot/table/CharstringType2.java
+++ b/src/net/java/dev/typecast/ot/table/CharstringType2.java
@@ -106,8 +106,6 @@ public class CharstringType2 extends Charstring {
private final int[] _data;
private final int _offset;
private final int _length;
- private final CffTable.Index _localSubrIndex;
- private final CffTable.Index _globalSubrIndex;
private int _ip;
/** Creates a new instance of CharstringType2
@@ -115,24 +113,18 @@ public class CharstringType2 extends Charstring {
* @param name
* @param data
* @param offset
- * @param length
- * @param localSubrIndex
- * @param globalSubrIndex */
+ * @param length */
protected CharstringType2(
int index,
String name,
int[] data,
int offset,
- int length,
- CffTable.Index localSubrIndex,
- CffTable.Index globalSubrIndex) {
+ int length) {
_index = index;
_name = name;
_data = data;
_offset = offset;
_length = length;
- _localSubrIndex = localSubrIndex;
- _globalSubrIndex = globalSubrIndex;
}
@Override
@@ -145,7 +137,7 @@ public class CharstringType2 extends Charstring {
return _name;
}
- private void disassemble(StringBuffer sb) {
+ private void disassemble(StringBuilder sb) {
while (isOperandAtIndex()) {
Number operand = nextOperand();
sb.append(operand).append(" ");
@@ -222,10 +214,10 @@ public class CharstringType2 extends Charstring {
public boolean moreBytes() {
return _ip < _offset + _length;
}
-
+
@Override
public String toString() {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
resetIP();
while (moreBytes()) {
disassemble(sb);
diff --git a/src/net/java/dev/typecast/ot/table/Table.java b/src/net/java/dev/typecast/ot/table/Table.java
index 97b60aa..1fcb352 100644
--- a/src/net/java/dev/typecast/ot/table/Table.java
+++ b/src/net/java/dev/typecast/ot/table/Table.java
@@ -9,7 +9,6 @@
package net.java.dev.typecast.ot.table;
/**
- * @version $Id: Table.java,v 1.1.1.1 2004-12-05 23:14:59 davidsch Exp $
* @author <a href="mailto:[email protected]">David Schweinsberg</a>
*/
public interface Table {
diff --git a/src/net/java/dev/typecast/t2/T2Interpreter.java b/src/net/java/dev/typecast/t2/T2Interpreter.java
index 7282c9c..c3d05ae 100644
--- a/src/net/java/dev/typecast/t2/T2Interpreter.java
+++ b/src/net/java/dev/typecast/t2/T2Interpreter.java
@@ -20,6 +20,7 @@ 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;
/**
@@ -42,9 +43,13 @@ public class T2Interpreter {
private int _stemCount = 0;
private ArrayList<Point> _points;
+ private final CffTable.Index _localSubrIndex;
+ private final CffTable.Index _globalSubrIndex;
/** Creates a new instance of T2Interpreter */
- public T2Interpreter() {
+ public T2Interpreter(CffTable.Index localSubrIndex, CffTable.Index globalSubrIndex) {
+ _localSubrIndex = localSubrIndex;
+ _globalSubrIndex = globalSubrIndex;
}
/**
@@ -780,15 +785,37 @@ 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() {
-
+ private void _callsubr(CharstringType2 cs) {
+ int bias;
+ int subrsCount = _localSubrIndex.getCount();
+ if (subrsCount < 1240) {
+ bias = 107;
+ } else if (subrsCount < 33900) {
+ bias = 1131;
+ } else {
+ bias = 32768;
+ }
+ int i = popArg().intValue();
+ int offset = _localSubrIndex.getOffset(i + bias);
+ int offset2 = _localSubrIndex.getOffset(i + bias + 1);
}
/**
* Operates in the same manner as callsubr except that it calls a
* global subroutine.
*/
- private void _callgsubr() {
+ private void _callgsubr(CharstringType2 cs) {
+ int bias;
+ int subrsCount = _localSubrIndex.getCount();
+ if (subrsCount < 1240) {
+ bias = 107;
+ } else if (subrsCount < 33900) {
+ bias = 1131;
+ } else {
+ bias = 32768;
+ }
+ int i = popArg().intValue();
+ int offset = _localSubrIndex.getOffset(i + bias);
}
@@ -796,8 +823,8 @@ public class T2Interpreter {
* Returns from either a local or global charstring subroutine, and
* continues execution after the corresponding call(g)subr.
*/
- private void _return() {
-
+ private void _return(CharstringType2 cs) {
+ //_ip = popSubr();
}
public Point[] execute(CharstringType2 cs) {
@@ -915,10 +942,10 @@ public class T2Interpreter {
_rrcurveto();
break;
case T2Mnemonic.CALLSUBR:
- _callsubr();
+ _callsubr(cs);
break;
case T2Mnemonic.RETURN:
- _return();
+ _return(cs);
break;
case T2Mnemonic.ENDCHAR:
_endchar();
@@ -954,7 +981,7 @@ public class T2Interpreter {
_hhcurveto();
break;
case T2Mnemonic.CALLGSUBR:
- _callgsubr();
+ _callgsubr(cs);
break;
case T2Mnemonic.VHCURVETO:
_vhcurveto();