diff options
author | David Schweinsberg <[email protected]> | 2015-12-27 14:51:46 -0700 |
---|---|---|
committer | David Schweinsberg <[email protected]> | 2015-12-27 14:51:46 -0700 |
commit | b2d29d276feb057409d7b2abb30f218d4061b7c5 (patch) | |
tree | b493e092c0d2906e821bebc4445faff6602f1a57 | |
parent | cebb5365de45b22f18284079056a8b78b8941093 (diff) |
New CffFont class encapulates an individual font within a CFF table. T2Interpreter references local and global subrs.
-rw-r--r-- | src/net/java/dev/typecast/app/editor/GlyphPanel.java | 28 | ||||
-rw-r--r-- | src/net/java/dev/typecast/ot/Glyph.java | 13 | ||||
-rw-r--r-- | src/net/java/dev/typecast/ot/OTFont.java | 31 | ||||
-rw-r--r-- | src/net/java/dev/typecast/ot/table/CffTable.java | 117 | ||||
-rw-r--r-- | src/net/java/dev/typecast/ot/table/CharstringType2.java | 18 | ||||
-rw-r--r-- | src/net/java/dev/typecast/ot/table/Table.java | 1 | ||||
-rw-r--r-- | src/net/java/dev/typecast/t2/T2Interpreter.java | 45 |
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(); |