aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/fonts
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache/fop/fonts')
-rw-r--r--src/org/apache/fop/fonts/FontFileReader.java227
-rw-r--r--src/org/apache/fop/fonts/Glyphs.java1692
-rw-r--r--src/org/apache/fop/fonts/PFMFile.java59
-rw-r--r--src/org/apache/fop/fonts/TTFCmapEntry.java60
-rw-r--r--src/org/apache/fop/fonts/TTFDirTabEntry.java85
-rw-r--r--src/org/apache/fop/fonts/TTFFile.java528
-rw-r--r--src/org/apache/fop/fonts/TTFMtxEntry.java77
-rw-r--r--src/org/apache/fop/fonts/TTFSegEntry.java61
-rw-r--r--src/org/apache/fop/fonts/apps/PFMReader.java232
-rw-r--r--src/org/apache/fop/fonts/apps/TTFReader.java504
10 files changed, 3470 insertions, 55 deletions
diff --git a/src/org/apache/fop/fonts/FontFileReader.java b/src/org/apache/fop/fonts/FontFileReader.java
new file mode 100644
index 000000000..f6bc3cff9
--- /dev/null
+++ b/src/org/apache/fop/fonts/FontFileReader.java
@@ -0,0 +1,227 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.File;
+import java.io.IOException;
+
+/** Reads a file into an array and
+ provides file like functions for array access.
+*/
+public class FontFileReader {
+ private int fsize; // file size
+ private int current; // current position in file
+ private byte[] file;
+ /**
+ * Initialisez class and reads stream. Init does not close stream
+ * @param stream InputStream to read from
+ * @param start initial size av array to read to
+ * @param inc if initial size isn't enough, create
+ new array with size + inc
+ */
+ private void init(InputStream stream, int start, int inc)
+ throws java.io.IOException {
+ fsize=0;
+ current=0;
+
+ file=new byte[start];
+
+ int l=stream.read(file, 0, start);
+ fsize+=l;
+
+ if (l==start) {
+ // More to read - needs to extend
+ byte[] tmpbuf;
+
+ while (l>0) {
+ tmpbuf=new byte[file.length + inc];
+ System.arraycopy(file, 0, tmpbuf, 0, file.length);
+ l=stream.read(tmpbuf, file.length, inc);
+ fsize+=l;
+ file=tmpbuf;
+
+ if (l<inc) // whole file read. No need to loop again
+ l=0;
+ }
+ }
+ }
+
+ /**
+ * Constructor
+ * @param fileName filename to read
+ */
+ public FontFileReader(String fileName)
+ throws java.io.IOException {
+
+ // Get estimates for file size and increment
+ File f=new File(fileName);
+ FileInputStream ins = new FileInputStream(fileName);
+ init(ins, (int)(f.length()+1), (int)(f.length()/10));
+ ins.close();
+ }
+
+
+ /** Set current file position to offset */
+ public void seek_set(long offset) throws IOException {
+ if (offset > fsize || offset < 0)
+ throw new java.io.EOFException("Reached EOF, file size="+fsize+
+ " offset="+offset);
+ current=(int)offset;
+ }
+
+ /** Set current file position to offset */
+ public void seek_add(long add) throws IOException {
+ seek_set(current+add);
+ }
+
+ public void skip(long add) throws IOException {
+ seek_add(add);
+ }
+
+ /** return current file position */
+ public int getCurrentPos() {
+ return current;
+ }
+
+ public int getFileSize() {
+ return fsize;
+ }
+
+
+ /** Read 1 byte, throws EOFException on end of file */
+ public byte read() throws IOException {
+ if (current>fsize)
+ throw new java.io.EOFException("Reached EOF, file size="+fsize);
+
+ byte ret=file[current++];
+ return ret;
+ }
+
+
+
+ /** Read 1 signed byte from InputStream */
+ public final byte readTTFByte() throws IOException {
+ return read();
+ }
+
+ /** Read 1 unsigned byte from InputStream */
+ public final int readTTFUByte() throws IOException {
+ byte buf=read();
+
+ if (buf < 0)
+ return (int)(256+buf);
+ else
+ return (int)buf;
+ }
+
+ /** Read 2 bytes signed from InputStream */
+ public final short readTTFShort() throws IOException {
+ int ret=(readTTFUByte() << 8) +
+ readTTFUByte();
+ short sret=(short)ret;
+
+ return sret;
+ }
+
+ /** Read 2 bytes unsigned from InputStream */
+ public final int readTTFUShort() throws IOException {
+ int ret=(readTTFUByte() << 8) +
+ readTTFUByte();
+
+ return (int)ret;
+ }
+
+ /** Read 4 bytes from InputStream */
+ public final int readTTFLong() throws IOException {
+ long ret=readTTFUByte();// << 8;
+ ret=(ret << 8) + readTTFUByte();
+ ret=(ret << 8) + readTTFUByte();
+ ret=(ret << 8) + readTTFUByte();
+
+ return (int)ret;
+ }
+
+ /** Read 4 bytes from InputStream */
+ public final long readTTFULong() throws IOException {
+ long ret=readTTFUByte();
+ ret=(ret << 8) + readTTFUByte();
+ ret=(ret << 8) + readTTFUByte();
+ ret=(ret << 8) + readTTFUByte();
+
+ return ret;
+ }
+
+ /** Read a 0 terminatet ISO-8859-1 string */
+ public final String readTTFString() throws IOException {
+ int i=current;
+ while (file[i++]!=0) {
+ if (i > fsize)
+ throw new java.io.EOFException("Reached EOF, file size="+fsize);
+ }
+
+ byte[] tmp=new byte[i-current];
+ System.arraycopy(file, current, tmp, 0, i-current);
+ return new String(tmp, "ISO-8859-1");
+ }
+
+
+ /** Read an ISO-8859-1 string of len bytes*/
+ public final String readTTFString(int len) throws IOException {
+ if ((len+current) > fsize)
+ throw new java.io.EOFException("Reached EOF, file size="+fsize);
+
+ byte[] tmp=new byte[len];
+ System.arraycopy(file, current, tmp, 0, len);
+ current+=len;
+ return new String(tmp, "ISO-8859-1");
+ }
+}
diff --git a/src/org/apache/fop/fonts/Glyphs.java b/src/org/apache/fop/fonts/Glyphs.java
new file mode 100644
index 000000000..cba61bcdb
--- /dev/null
+++ b/src/org/apache/fop/fonts/Glyphs.java
@@ -0,0 +1,1692 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+
+public class Glyphs {
+ static String notdef = ".notdef";
+
+ static String mac_glyph_names[] = {
+/* 0x00 */
+ notdef,
+ ".null",
+ "CR",
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quotesingle",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+/* 0x10 */
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+/* 0x20 */
+ "equal",
+ "greater",
+ "question",
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+/* 0x30 */
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+/* 0x40 */
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ "grave",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+/* 0x50 */
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+/* 0x60 */
+ "braceright",
+ "asciitilde",
+ "Adieresis",
+ "Aring",
+ "Ccedilla",
+ "Eacute",
+ "Ntilde",
+ "Odieresis",
+ "Udieresis",
+ "aacute",
+ "agrave",
+ "acircumflex",
+ "adieresis",
+ "atilde",
+ "aring",
+ "ccedilla",
+/* 0x70 */
+ "eacute",
+ "egrave",
+ "ecircumflex",
+ "edieresis",
+ "iacute",
+ "igrave",
+ "icircumflex",
+ "idieresis",
+ "ntilde",
+ "oacute",
+ "ograve",
+ "ocircumflex",
+ "odieresis",
+ "otilde",
+ "uacute",
+ "ugrave",
+/* 0x80 */
+ "ucircumflex",
+ "udieresis",
+ "dagger",
+ "degree",
+ "cent",
+ "sterling",
+ "section",
+ "bullet",
+ "paragraph",
+ "germandbls",
+ "registered",
+ "copyright",
+ "trademark",
+ "acute",
+ "dieresis",
+ "notequal",
+/* 0x90 */
+ "AE",
+ "Oslash",
+ "infinity",
+ "plusminus",
+ "lessequal",
+ "greaterequal",
+ "yen",
+ "mu",
+ "partialdiff",
+ "Sigma",
+ "Pi",
+ "pi",
+ "integral",
+ "ordfeminine",
+ "ordmasculine",
+ "Omega",
+/* 0xa0 */
+ "ae",
+ "oslash",
+ "questiondown",
+ "exclamdown",
+ "logicalnot",
+ "radical",
+ "florin",
+ "approxequal",
+ "Delta",
+ "guillemotleft",
+ "guillemotright",
+ "ellipsis",
+ "nbspace",
+ "Agrave",
+ "Atilde",
+ "Otilde",
+/* 0xb0 */
+ "OE",
+ "oe",
+ "endash",
+ "emdash",
+ "quotedblleft",
+ "quotedblright",
+ "quoteleft",
+ "quoteright",
+ "divide",
+ "lozenge",
+ "ydieresis",
+ "Ydieresis",
+ "fraction",
+ "currency",
+ "guilsinglleft",
+ "guilsinglright",
+/* 0xc0 */
+ "fi",
+ "fl",
+ "daggerdbl",
+ "periodcentered",
+ "quotesinglbase",
+ "quotedblbase",
+ "perthousand",
+ "Acircumflex",
+ "Ecircumflex",
+ "Aacute",
+ "Edieresis",
+ "Egrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ "Igrave",
+/* 0xd0 */
+ "Oacute",
+ "Ocircumflex",
+ "applelogo",
+ "Ograve",
+ "Uacute",
+ "Ucircumflex",
+ "Ugrave",
+ "dotlessi",
+ "circumflex",
+ "tilde",
+ "macron",
+ "breve",
+ "dotaccent",
+ "ring",
+ "cedilla",
+ "hungarumlaut",
+/* 0xe0 */
+ "ogonek",
+ "caron",
+ "Lslash",
+ "lslash",
+ "Scaron",
+ "scaron",
+ "Zcaron",
+ "zcaron",
+ "brokenbar",
+ "Eth",
+ "eth",
+ "Yacute",
+ "yacute",
+ "Thorn",
+ "thorn",
+ "minus",
+/* 0xf0 */
+ "multiply",
+ "onesuperior",
+ "twosuperior",
+ "threesuperior",
+ "onehalf",
+ "onequarter",
+ "threequarters",
+ "franc",
+ "Gbreve",
+ "gbreve",
+ "Idot",
+ "Scedilla",
+ "scedilla",
+ "Cacute",
+ "cacute",
+ "Ccaron",
+/* 0x100 */
+ "ccaron",
+ "dmacron"
+ };
+
+ static String[] tex8r = {
+ // 0x00
+ ".notdef",
+ "dotaccent",
+ "fi",
+ "fl",
+ "fraction",
+ "hungarumlaut",
+ "Lslash",
+ "lslash",
+ "ogonek",
+ "ring",
+ ".notdef",
+ "breve",
+ "minus",
+ ".notdef",
+ "Zcaron",
+ "zcaron",
+ // 0x10
+ "caron",
+ "dotlessi",
+ "dotlessj",
+ "ff",
+ "ffi",
+ "ffl",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ "grave",
+ "quotesingle",
+ // 0x20
+ "space",
+ "exclam",
+ "quotedbl",
+ "numbersign",
+ "dollar",
+ "percent",
+ "ampersand",
+ "quoteright",
+ "parenleft",
+ "parenright",
+ "asterisk",
+ "plus",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ // 0x30
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less",
+ "equal",
+ "greater",
+ "question",
+ // 0x40
+ "at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ // 0x50
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "bracketleft",
+ "backslash",
+ "bracketright",
+ "asciicircum",
+ "underscore",
+ // 0x60
+ "quoteleft",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ // 0x70
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "braceleft",
+ "bar",
+ "braceright",
+ "asciitilde",
+ ".notdef",
+ // 0x80
+ "Euro",
+ ".notdef",
+ "quotesinglbase",
+ "florin",
+ "quotedblbase",
+ "ellipsis",
+ "dagger",
+ "daggerdbl",
+ "circumflex",
+ "perthousand",
+ "Scaron",
+ "guilsinglleft",
+ "OE",
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ // 0x90
+ ".notdef",
+ ".notdef",
+ ".notdef",
+ "quotedblleft",
+ "quotedblright",
+ "bullet",
+ "endash",
+ "emdash",
+ "tilde",
+ "trademark",
+ "scaron",
+ "guilsinglright",
+ "oe",
+ ".notdef",
+ ".notdef",
+ "Ydieresis",
+ // 0xA0
+ ".notdef",
+ "exclamdown",
+ "cent",
+ "sterling",
+ "currency",
+ "yen",
+ "brokenbar",
+ "section",
+ "dieresis",
+ "copyright",
+ "ordfeminine",
+ "guillemotleft",
+ "logicalnot",
+ "hyphen",
+ "registered",
+ "macron",
+ // 0xB0
+ "degree",
+ "plusminus",
+ "twosuperior",
+ "threesuperior",
+ "acute",
+ "mu",
+ "paragraph",
+ "periodcentered",
+ "cedilla",
+ "onesuperior",
+ "ordmasculine",
+ "guillemotright",
+ "onequarter",
+ "onehalf",
+ "threequarters",
+ "questiondown",
+ // 0xC0
+ "Agrave",
+ "Aacute",
+ "Acircumflex",
+ "Atilde",
+ "Adieresis",
+ "Aring",
+ "AE",
+ "Ccedilla",
+ "Egrave",
+ "Eacute",
+ "Ecircumflex",
+ "Edieresis",
+ "Igrave",
+ "Iacute",
+ "Icircumflex",
+ "Idieresis",
+ // 0xD0
+ "Eth",
+ "Ntilde",
+ "Ograve",
+ "Oacute",
+ "Ocircumflex",
+ "Otilde",
+ "Odieresis",
+ "multiply",
+ "Oslash",
+ "Ugrave",
+ "Uacute",
+ "Ucircumflex",
+ "Udieresis",
+ "Yacute",
+ "Thorn",
+ "germandbls",
+ // 0xE0
+ "agrave",
+ "aacute",
+ "acircumflex",
+ "atilde",
+ "adieresis",
+ "aring",
+ "ae",
+ "ccedilla",
+ "egrave",
+ "eacute",
+ "ecircumflex",
+ "edieresis",
+ "igrave",
+ "iacute",
+ "icircumflex",
+ "idieresis",
+ // 0xF0
+ "eth",
+ "ntilde",
+ "ograve",
+ "oacute",
+ "ocircumflex",
+ "otilde",
+ "odieresis",
+ "divide",
+ "oslash",
+ "ugrave",
+ "uacute",
+ "ucircumflex",
+ "udieresis",
+ "yacute",
+ "thorn",
+ "ydieresis"};
+
+ static String[] unicode_glyphs={
+ "\u0041", "A",
+ "\u00C6", "AE",
+ "\u01FC", "AEacute",
+ "\uF7E6", "AEsmall",
+ "\u00C1", "Aacute",
+ "\uF7E1", "Aacutesmall",
+ "\u0102", "Abreve",
+ "\u00C2", "Acircumflex",
+ "\uF7E2", "Acircumflexsmall",
+ "\uF6C9", "Acute",
+ "\uF7B4", "Acutesmall",
+ "\u00C4", "Adieresis",
+ "\uF7E4", "Adieresissmall",
+ "\u00C0", "Agrave",
+ "\uF7E0", "Agravesmall",
+ "\u0391", "Alpha",
+ "\u0386", "Alphatonos",
+ "\u0100", "Amacron",
+ "\u0104", "Aogonek",
+ "\u00C5", "Aring",
+ "\u01FA", "Aringacute",
+ "\uF7E5", "Aringsmall",
+ "\uF761", "Asmall",
+ "\u00C3", "Atilde",
+ "\uF7E3", "Atildesmall",
+ "\u0042", "B",
+ "\u0392", "Beta",
+ "\uF6F4", "Brevesmall",
+ "\uF762", "Bsmall",
+ "\u0043", "C",
+ "\u0106", "Cacute",
+ "\uF6CA", "Caron",
+ "\uF6F5", "Caronsmall",
+ "\u010C", "Ccaron",
+ "\u00C7", "Ccedilla",
+ "\uF7E7", "Ccedillasmall",
+ "\u0108", "Ccircumflex",
+ "\u010A", "Cdotaccent",
+ "\uF7B8", "Cedillasmall",
+ "\u03A7", "Chi",
+ "\uF6F6", "Circumflexsmall",
+ "\uF763", "Csmall",
+ "\u0044", "D",
+ "\u010E", "Dcaron",
+ "\u0110", "Dcroat",
+ "\u2206", "Delta",
+ "\u0394", "Delta",
+ "\uF6CB", "Dieresis",
+ "\uF6CC", "DieresisAcute",
+ "\uF6CD", "DieresisGrave",
+ "\uF7A8", "Dieresissmall",
+ "\uF6F7", "Dotaccentsmall",
+ "\uF764", "Dsmall",
+ "\u0045", "E",
+ "\u00C9", "Eacute",
+ "\uF7E9", "Eacutesmall",
+ "\u0114", "Ebreve",
+ "\u011A", "Ecaron",
+ "\u00CA", "Ecircumflex",
+ "\uF7EA", "Ecircumflexsmall",
+ "\u00CB", "Edieresis",
+ "\uF7EB", "Edieresissmall",
+ "\u0116", "Edotaccent",
+ "\u00C8", "Egrave",
+ "\uF7E8", "Egravesmall",
+ "\u0112", "Emacron",
+ "\u014A", "Eng",
+ "\u0118", "Eogonek",
+ "\u0395", "Epsilon",
+ "\u0388", "Epsilontonos",
+ "\uF765", "Esmall",
+ "\u0397", "Eta",
+ "\u0389", "Etatonos",
+ "\u00D0", "Eth",
+ "\uF7F0", "Ethsmall",
+ "\u20AC", "Euro",
+ "\u0046", "F",
+ "\uF766", "Fsmall",
+ "\u0047", "G",
+ "\u0393", "Gamma",
+ "\u011E", "Gbreve",
+ "\u01E6", "Gcaron",
+ "\u011C", "Gcircumflex",
+ "\u0122", "Gcommaaccent",
+ "\u0120", "Gdotaccent",
+ "\uF6CE", "Grave",
+ "\uF760", "Gravesmall",
+ "\uF767", "Gsmall",
+ "\u0048", "H",
+ "\u25CF", "H18533",
+ "\u25AA", "H18543",
+ "\u25AB", "H18551",
+ "\u25A1", "H22073",
+ "\u0126", "Hbar",
+ "\u0124", "Hcircumflex",
+ "\uF768", "Hsmall",
+ "\uF6CF", "Hungarumlaut",
+ "\uF6F8", "Hungarumlautsmall",
+ "\u0049", "I",
+ "\u0132", "IJ",
+ "\u00CD", "Iacute",
+ "\uF7ED", "Iacutesmall",
+ "\u012C", "Ibreve",
+ "\u00CE", "Icircumflex",
+ "\uF7EE", "Icircumflexsmall",
+ "\u00CF", "Idieresis",
+ "\uF7EF", "Idieresissmall",
+ "\u0130", "Idotaccent",
+ "\u2111", "Ifraktur",
+ "\u00CC", "Igrave",
+ "\uF7EC", "Igravesmall",
+ "\u012A", "Imacron",
+ "\u012E", "Iogonek",
+ "\u0399", "Iota",
+ "\u03AA", "Iotadieresis",
+ "\u038A", "Iotatonos",
+ "\uF769", "Ismall",
+ "\u0128", "Itilde",
+ "\u004A", "J",
+ "\u0134", "Jcircumflex",
+ "\uF76A", "Jsmall",
+ "\u004B", "K",
+ "\u039A", "Kappa",
+ "\u0136", "Kcommaaccent",
+ "\uF76B", "Ksmall",
+ "\u004C", "L",
+ "\uF6BF", "LL",
+ "\u0139", "Lacute",
+ "\u039B", "Lambda",
+ "\u013D", "Lcaron",
+ "\u013B", "Lcommaaccent",
+ "\u013F", "Ldot",
+ "\u0141", "Lslash",
+ "\uF6F9", "Lslashsmall",
+ "\uF76C", "Lsmall",
+ "\u004D", "M",
+ "\uF6D0", "Macron",
+ "\uF7AF", "Macronsmall",
+ "\uF76D", "Msmall",
+ "\u039C", "Mu",
+ "\u004E", "N",
+ "\u0143", "Nacute",
+ "\u0147", "Ncaron",
+ "\u0145", "Ncommaaccent",
+ "\uF76E", "Nsmall",
+ "\u00D1", "Ntilde",
+ "\uF7F1", "Ntildesmall",
+ "\u039D", "Nu",
+ "\u004F", "O",
+ "\u0152", "OE",
+ "\uF6FA", "OEsmall",
+ "\u00D3", "Oacute",
+ "\uF7F3", "Oacutesmall",
+ "\u014E", "Obreve",
+ "\u00D4", "Ocircumflex",
+ "\uF7F4", "Ocircumflexsmall",
+ "\u00D6", "Odieresis",
+ "\uF7F6", "Odieresissmall",
+ "\uF6FB", "Ogoneksmall",
+ "\u00D2", "Ograve",
+ "\uF7F2", "Ogravesmall",
+ "\u01A0", "Ohorn",
+ "\u0150", "Ohungarumlaut",
+ "\u014C", "Omacron",
+ "\u2126", "Omega",
+ "\u03A9", "Omega",
+ "\u038F", "Omegatonos",
+ "\u039F", "Omicron",
+ "\u038C", "Omicrontonos",
+ "\u00D8", "Oslash",
+ "\u01FE", "Oslashacute",
+ "\uF7F8", "Oslashsmall",
+ "\uF76F", "Osmall",
+ "\u00D5", "Otilde",
+ "\uF7F5", "Otildesmall",
+ "\u0050", "P",
+ "\u03A6", "Phi",
+ "\u03A0", "Pi",
+ "\u03A8", "Psi",
+ "\uF770", "Psmall",
+ "\u0051", "Q",
+ "\uF771", "Qsmall",
+ "\u0052", "R",
+ "\u0154", "Racute",
+ "\u0158", "Rcaron",
+ "\u0156", "Rcommaaccent",
+ "\u211C", "Rfraktur",
+ "\u03A1", "Rho",
+ "\uF6FC", "Ringsmall",
+ "\uF772", "Rsmall",
+ "\u0053", "S",
+ "\u250C", "SF010000",
+ "\u2514", "SF020000",
+ "\u2510", "SF030000",
+ "\u2518", "SF040000",
+ "\u253C", "SF050000",
+ "\u252C", "SF060000",
+ "\u2534", "SF070000",
+ "\u251C", "SF080000",
+ "\u2524", "SF090000",
+ "\u2500", "SF100000",
+ "\u2502", "SF110000",
+ "\u2561", "SF190000",
+ "\u2562", "SF200000",
+ "\u2556", "SF210000",
+ "\u2555", "SF220000",
+ "\u2563", "SF230000",
+ "\u2551", "SF240000",
+ "\u2557", "SF250000",
+ "\u255D", "SF260000",
+ "\u255C", "SF270000",
+ "\u255B", "SF280000",
+ "\u255E", "SF360000",
+ "\u255F", "SF370000",
+ "\u255A", "SF380000",
+ "\u2554", "SF390000",
+ "\u2569", "SF400000",
+ "\u2566", "SF410000",
+ "\u2560", "SF420000",
+ "\u2550", "SF430000",
+ "\u256C", "SF440000",
+ "\u2567", "SF450000",
+ "\u2568", "SF460000",
+ "\u2564", "SF470000",
+ "\u2565", "SF480000",
+ "\u2559", "SF490000",
+ "\u2558", "SF500000",
+ "\u2552", "SF510000",
+ "\u2553", "SF520000",
+ "\u256B", "SF530000",
+ "\u256A", "SF540000",
+ "\u015A", "Sacute",
+ "\u0160", "Scaron",
+ "\uF6FD", "Scaronsmall",
+ "\u015E", "Scedilla",
+ "\uF6C1", "Scedilla",
+ "\u015C", "Scircumflex",
+ "\u0218", "Scommaaccent",
+ "\u03A3", "Sigma",
+ "\uF773", "Ssmall",
+ "\u0054", "T",
+ "\u03A4", "Tau",
+ "\u0166", "Tbar",
+ "\u0164", "Tcaron",
+ "\u0162", "Tcommaaccent",
+ "\u021A", "Tcommaaccent",
+ "\u0398", "Theta",
+ "\u00DE", "Thorn",
+ "\uF7FE", "Thornsmall",
+ "\uF6FE", "Tildesmall",
+ "\uF774", "Tsmall",
+ "\u0055", "U",
+ "\u00DA", "Uacute",
+ "\uF7FA", "Uacutesmall",
+ "\u016C", "Ubreve",
+ "\u00DB", "Ucircumflex",
+ "\uF7FB", "Ucircumflexsmall",
+ "\u00DC", "Udieresis",
+ "\uF7FC", "Udieresissmall",
+ "\u00D9", "Ugrave",
+ "\uF7F9", "Ugravesmall",
+ "\u01AF", "Uhorn",
+ "\u0170", "Uhungarumlaut",
+ "\u016A", "Umacron",
+ "\u0172", "Uogonek",
+ "\u03A5", "Upsilon",
+ "\u03D2", "Upsilon1",
+ "\u03AB", "Upsilondieresis",
+ "\u038E", "Upsilontonos",
+ "\u016E", "Uring",
+ "\uF775", "Usmall",
+ "\u0168", "Utilde",
+ "\u0056", "V",
+ "\uF776", "Vsmall",
+ "\u0057", "W",
+ "\u1E82", "Wacute",
+ "\u0174", "Wcircumflex",
+ "\u1E84", "Wdieresis",
+ "\u1E80", "Wgrave",
+ "\uF777", "Wsmall",
+ "\u0058", "X",
+ "\u039E", "Xi",
+ "\uF778", "Xsmall",
+ "\u0059", "Y",
+ "\u00DD", "Yacute",
+ "\uF7FD", "Yacutesmall",
+ "\u0176", "Ycircumflex",
+ "\u0178", "Ydieresis",
+ "\uF7FF", "Ydieresissmall",
+ "\u1EF2", "Ygrave",
+ "\uF779", "Ysmall",
+ "\u005A", "Z",
+ "\u0179", "Zacute",
+ "\u017D", "Zcaron",
+ "\uF6FF", "Zcaronsmall",
+ "\u017B", "Zdotaccent",
+ "\u0396", "Zeta",
+ "\uF77A", "Zsmall",
+ "\u0061", "a",
+ "\u00E1", "aacute",
+ "\u0103", "abreve",
+ "\u00E2", "acircumflex",
+ "\u00B4", "acute",
+ "\u0301", "acutecomb",
+ "\u00E4", "adieresis",
+ "\u00E6", "ae",
+ "\u01FD", "aeacute",
+ "\u2015", "afii00208",
+ "\u0410", "afii10017",
+ "\u0411", "afii10018",
+ "\u0412", "afii10019",
+ "\u0413", "afii10020",
+ "\u0414", "afii10021",
+ "\u0415", "afii10022",
+ "\u0401", "afii10023",
+ "\u0416", "afii10024",
+ "\u0417", "afii10025",
+ "\u0418", "afii10026",
+ "\u0419", "afii10027",
+ "\u041A", "afii10028",
+ "\u041B", "afii10029",
+ "\u041C", "afii10030",
+ "\u041D", "afii10031",
+ "\u041E", "afii10032",
+ "\u041F", "afii10033",
+ "\u0420", "afii10034",
+ "\u0421", "afii10035",
+ "\u0422", "afii10036",
+ "\u0423", "afii10037",
+ "\u0424", "afii10038",
+ "\u0425", "afii10039",
+ "\u0426", "afii10040",
+ "\u0427", "afii10041",
+ "\u0428", "afii10042",
+ "\u0429", "afii10043",
+ "\u042A", "afii10044",
+ "\u042B", "afii10045",
+ "\u042C", "afii10046",
+ "\u042D", "afii10047",
+ "\u042E", "afii10048",
+ "\u042F", "afii10049",
+ "\u0490", "afii10050",
+ "\u0402", "afii10051",
+ "\u0403", "afii10052",
+ "\u0404", "afii10053",
+ "\u0405", "afii10054",
+ "\u0406", "afii10055",
+ "\u0407", "afii10056",
+ "\u0408", "afii10057",
+ "\u0409", "afii10058",
+ "\u040A", "afii10059",
+ "\u040B", "afii10060",
+ "\u040C", "afii10061",
+ "\u040E", "afii10062",
+ "\uF6C4", "afii10063",
+ "\uF6C5", "afii10064",
+ "\u0430", "afii10065",
+ "\u0431", "afii10066",
+ "\u0432", "afii10067",
+ "\u0433", "afii10068",
+ "\u0434", "afii10069",
+ "\u0435", "afii10070",
+ "\u0451", "afii10071",
+ "\u0436", "afii10072",
+ "\u0437", "afii10073",
+ "\u0438", "afii10074",
+ "\u0439", "afii10075",
+ "\u043A", "afii10076",
+ "\u043B", "afii10077",
+ "\u043C", "afii10078",
+ "\u043D", "afii10079",
+ "\u043E", "afii10080",
+ "\u043F", "afii10081",
+ "\u0440", "afii10082",
+ "\u0441", "afii10083",
+ "\u0442", "afii10084",
+ "\u0443", "afii10085",
+ "\u0444", "afii10086",
+ "\u0445", "afii10087",
+ "\u0446", "afii10088",
+ "\u0447", "afii10089",
+ "\u0448", "afii10090",
+ "\u0449", "afii10091",
+ "\u044A", "afii10092",
+ "\u044B", "afii10093",
+ "\u044C", "afii10094",
+ "\u044D", "afii10095",
+ "\u044E", "afii10096",
+ "\u044F", "afii10097",
+ "\u0491", "afii10098",
+ "\u0452", "afii10099",
+ "\u0453", "afii10100",
+ "\u0454", "afii10101",
+ "\u0455", "afii10102",
+ "\u0456", "afii10103",
+ "\u0457", "afii10104",
+ "\u0458", "afii10105",
+ "\u0459", "afii10106",
+ "\u045A", "afii10107",
+ "\u045B", "afii10108",
+ "\u045C", "afii10109",
+ "\u045E", "afii10110",
+ "\u040F", "afii10145",
+ "\u0462", "afii10146",
+ "\u0472", "afii10147",
+ "\u0474", "afii10148",
+ "\uF6C6", "afii10192",
+ "\u045F", "afii10193",
+ "\u0463", "afii10194",
+ "\u0473", "afii10195",
+ "\u0475", "afii10196",
+ "\uF6C7", "afii10831",
+ "\uF6C8", "afii10832",
+ "\u04D9", "afii10846",
+ "\u200E", "afii299",
+ "\u200F", "afii300",
+ "\u200D", "afii301",
+ "\u066A", "afii57381",
+ "\u060C", "afii57388",
+ "\u0660", "afii57392",
+ "\u0661", "afii57393",
+ "\u0662", "afii57394",
+ "\u0663", "afii57395",
+ "\u0664", "afii57396",
+ "\u0665", "afii57397",
+ "\u0666", "afii57398",
+ "\u0667", "afii57399",
+ "\u0668", "afii57400",
+ "\u0669", "afii57401",
+ "\u061B", "afii57403",
+ "\u061F", "afii57407",
+ "\u0621", "afii57409",
+ "\u0622", "afii57410",
+ "\u0623", "afii57411",
+ "\u0624", "afii57412",
+ "\u0625", "afii57413",
+ "\u0626", "afii57414",
+ "\u0627", "afii57415",
+ "\u0628", "afii57416",
+ "\u0629", "afii57417",
+ "\u062A", "afii57418",
+ "\u062B", "afii57419",
+ "\u062C", "afii57420",
+ "\u062D", "afii57421",
+ "\u062E", "afii57422",
+ "\u062F", "afii57423",
+ "\u0630", "afii57424",
+ "\u0631", "afii57425",
+ "\u0632", "afii57426",
+ "\u0633", "afii57427",
+ "\u0634", "afii57428",
+ "\u0635", "afii57429",
+ "\u0636", "afii57430",
+ "\u0637", "afii57431",
+ "\u0638", "afii57432",
+ "\u0639", "afii57433",
+ "\u063A", "afii57434",
+ "\u0640", "afii57440",
+ "\u0641", "afii57441",
+ "\u0642", "afii57442",
+ "\u0643", "afii57443",
+ "\u0644", "afii57444",
+ "\u0645", "afii57445",
+ "\u0646", "afii57446",
+ "\u0648", "afii57448",
+ "\u0649", "afii57449",
+ "\u064A", "afii57450",
+ "\u064B", "afii57451",
+ "\u064C", "afii57452",
+ "\u064D", "afii57453",
+ "\u064E", "afii57454",
+ "\u064F", "afii57455",
+ "\u0650", "afii57456",
+ "\u0651", "afii57457",
+ "\u0652", "afii57458",
+ "\u0647", "afii57470",
+ "\u06A4", "afii57505",
+ "\u067E", "afii57506",
+ "\u0686", "afii57507",
+ "\u0698", "afii57508",
+ "\u06AF", "afii57509",
+ "\u0679", "afii57511",
+ "\u0688", "afii57512",
+ "\u0691", "afii57513",
+ "\u06BA", "afii57514",
+ "\u06D2", "afii57519",
+ "\u06D5", "afii57534",
+ "\u20AA", "afii57636",
+ "\u05BE", "afii57645",
+ "\u05C3", "afii57658",
+ "\u05D0", "afii57664",
+ "\u05D1", "afii57665",
+ "\u05D2", "afii57666",
+ "\u05D3", "afii57667",
+ "\u05D4", "afii57668",
+ "\u05D5", "afii57669",
+ "\u05D6", "afii57670",
+ "\u05D7", "afii57671",
+ "\u05D8", "afii57672",
+ "\u05D9", "afii57673",
+ "\u05DA", "afii57674",
+ "\u05DB", "afii57675",
+ "\u05DC", "afii57676",
+ "\u05DD", "afii57677",
+ "\u05DE", "afii57678",
+ "\u05DF", "afii57679",
+ "\u05E0", "afii57680",
+ "\u05E1", "afii57681",
+ "\u05E2", "afii57682",
+ "\u05E3", "afii57683",
+ "\u05E4", "afii57684",
+ "\u05E5", "afii57685",
+ "\u05E6", "afii57686",
+ "\u05E7", "afii57687",
+ "\u05E8", "afii57688",
+ "\u05E9", "afii57689",
+ "\u05EA", "afii57690",
+ "\uFB2A", "afii57694",
+ "\uFB2B", "afii57695",
+ "\uFB4B", "afii57700",
+ "\uFB1F", "afii57705",
+ "\u05F0", "afii57716",
+ "\u05F1", "afii57717",
+ "\u05F2", "afii57718",
+ "\uFB35", "afii57723",
+ "\u05B4", "afii57793",
+ "\u05B5", "afii57794",
+ "\u05B6", "afii57795",
+ "\u05BB", "afii57796",
+ "\u05B8", "afii57797",
+ "\u05B7", "afii57798",
+ "\u05B0", "afii57799",
+ "\u05B2", "afii57800",
+ "\u05B1", "afii57801",
+ "\u05B3", "afii57802",
+ "\u05C2", "afii57803",
+ "\u05C1", "afii57804",
+ "\u05B9", "afii57806",
+ "\u05BC", "afii57807",
+ "\u05BD", "afii57839",
+ "\u05BF", "afii57841",
+ "\u05C0", "afii57842",
+ "\u02BC", "afii57929",
+ "\u2105", "afii61248",
+ "\u2113", "afii61289",
+ "\u2116", "afii61352",
+ "\u202C", "afii61573",
+ "\u202D", "afii61574",
+ "\u202E", "afii61575",
+ "\u200C", "afii61664",
+ "\u066D", "afii63167",
+ "\u02BD", "afii64937",
+ "\u00E0", "agrave",
+ "\u2135", "aleph",
+ "\u03B1", "alpha",
+ "\u03AC", "alphatonos",
+ "\u0101", "amacron",
+ "\u0026", "ampersand",
+ "\uF726", "ampersandsmall",
+ "\u2220", "angle",
+ "\u2329", "angleleft",
+ "\u232A", "angleright",
+ "\u0387", "anoteleia",
+ "\u0105", "aogonek",
+ "\u2248", "approxequal",
+ "\u00E5", "aring",
+ "\u01FB", "aringacute",
+ "\u2194", "arrowboth",
+ "\u21D4", "arrowdblboth",
+ "\u21D3", "arrowdbldown",
+ "\u21D0", "arrowdblleft",
+ "\u21D2", "arrowdblright",
+ "\u21D1", "arrowdblup",
+ "\u2193", "arrowdown",
+ "\uF8E7", "arrowhorizex",
+ "\u2190", "arrowleft",
+ "\u2192", "arrowright",
+ "\u2191", "arrowup",
+ "\u2195", "arrowupdn",
+ "\u21A8", "arrowupdnbse",
+ "\uF8E6", "arrowvertex",
+ "\u005E", "asciicircum",
+ "\u007E", "asciitilde",
+ "\u002A", "asterisk",
+ "\u2217", "asteriskmath",
+ "\uF6E9", "asuperior",
+ "\u0040", "at",
+ "\u00E3", "atilde",
+ "\u0062", "b",
+ //"\u005C", "backslash",
+ "\\", "backslash",
+ "\u007C", "bar",
+ "\u03B2", "beta",
+ "\u2588", "block",
+ "\uF8F4", "braceex",
+ "\u007B", "braceleft",
+ "\uF8F3", "braceleftbt",
+ "\uF8F2", "braceleftmid",
+ "\uF8F1", "bracelefttp",
+ "\u007D", "braceright",
+ "\uF8FE", "bracerightbt",
+ "\uF8FD", "bracerightmid",
+ "\uF8FC", "bracerighttp",
+ "\u005B", "bracketleft",
+ "\uF8F0", "bracketleftbt",
+ "\uF8EF", "bracketleftex",
+ "\uF8EE", "bracketlefttp",
+ "\u005D", "bracketright",
+ "\uF8FB", "bracketrightbt",
+ "\uF8FA", "bracketrightex",
+ "\uF8F9", "bracketrighttp",
+ "\u02D8", "breve",
+ "\u00A6", "brokenbar",
+ "\uF6EA", "bsuperior",
+ "\u2022", "bullet",
+ "\u0063", "c",
+ "\u0107", "cacute",
+ "\u02C7", "caron",
+ "\u21B5", "carriagereturn",
+ "\u010D", "ccaron",
+ "\u00E7", "ccedilla",
+ "\u0109", "ccircumflex",
+ "\u010B", "cdotaccent",
+ "\u00B8", "cedilla",
+ "\u00A2", "cent",
+ "\uF6DF", "centinferior",
+ "\uF7A2", "centoldstyle",
+ "\uF6E0", "centsuperior",
+ "\u03C7", "chi",
+ "\u25CB", "circle",
+ "\u2297", "circlemultiply",
+ "\u2295", "circleplus",
+ "\u02C6", "circumflex",
+ "\u2663", "club",
+ "\u003A", "colon",
+ "\u20A1", "colonmonetary",
+ "\u002C", "comma",
+ "\uF6C3", "commaaccent",
+ "\uF6E1", "commainferior",
+ "\uF6E2", "commasuperior",
+ "\u2245", "congruent",
+ "\u00A9", "copyright",
+ "\uF8E9", "copyrightsans",
+ "\uF6D9", "copyrightserif",
+ "\u00A4", "currency",
+ "\uF6D1", "cyrBreve",
+ "\uF6D2", "cyrFlex",
+ "\uF6D4", "cyrbreve",
+ "\uF6D5", "cyrflex",
+ "\u0064", "d",
+ "\u2020", "dagger",
+ "\u2021", "daggerdbl",
+ "\uF6D3", "dblGrave",
+ "\uF6D6", "dblgrave",
+ "\u010F", "dcaron",
+ "\u0111", "dcroat",
+ "\u00B0", "degree",
+ "\u03B4", "delta",
+ "\u2666", "diamond",
+ "\u00A8", "dieresis",
+ "\uF6D7", "dieresisacute",
+ "\uF6D8", "dieresisgrave",
+ "\u0385", "dieresistonos",
+ "\u00F7", "divide",
+ "\u2593", "dkshade",
+ "\u2584", "dnblock",
+ "\u0024", "dollar",
+ "\uF6E3", "dollarinferior",
+ "\uF724", "dollaroldstyle",
+ "\uF6E4", "dollarsuperior",
+ "\u20AB", "dong",
+ "\u02D9", "dotaccent",
+ "\u0323", "dotbelowcomb",
+ "\u0131", "dotlessi",
+ "\uF6BE", "dotlessj",
+ "\u22C5", "dotmath",
+ "\uF6EB", "dsuperior",
+ "\u0065", "e",
+ "\u00E9", "eacute",
+ "\u0115", "ebreve",
+ "\u011B", "ecaron",
+ "\u00EA", "ecircumflex",
+ "\u00EB", "edieresis",
+ "\u0117", "edotaccent",
+ "\u00E8", "egrave",
+ "\u0038", "eight",
+ "\u2088", "eightinferior",
+ "\uF738", "eightoldstyle",
+ "\u2078", "eightsuperior",
+ "\u2208", "element",
+ "\u2026", "ellipsis",
+ "\u0113", "emacron",
+ "\u2014", "emdash",
+ "\u2205", "emptyset",
+ "\u2013", "endash",
+ "\u014B", "eng",
+ "\u0119", "eogonek",
+ "\u03B5", "epsilon",
+ "\u03AD", "epsilontonos",
+ "\u003D", "equal",
+ "\u2261", "equivalence",
+ "\u212E", "estimated",
+ "\uF6EC", "esuperior",
+ "\u03B7", "eta",
+ "\u03AE", "etatonos",
+ "\u00F0", "eth",
+ "\u0021", "exclam",
+ "\u203C", "exclamdbl",
+ "\u00A1", "exclamdown",
+ "\uF7A1", "exclamdownsmall",
+ "\uF721", "exclamsmall",
+ "\u2203", "existential",
+ "\u0066", "f",
+ "\u2640", "female",
+ "\uFB00", "ff",
+ "\uFB03", "ffi",
+ "\uFB04", "ffl",
+ "\uFB01", "fi",
+ "\u2012", "figuredash",
+ "\u25A0", "filledbox",
+ "\u25AC", "filledrect",
+ "\u0035", "five",
+ "\u215D", "fiveeighths",
+ "\u2085", "fiveinferior",
+ "\uF735", "fiveoldstyle",
+ "\u2075", "fivesuperior",
+ "\uFB02", "fl",
+ "\u0192", "florin",
+ "\u0034", "four",
+ "\u2084", "fourinferior",
+ "\uF734", "fouroldstyle",
+ "\u2074", "foursuperior",
+ "\u2044", "fraction",
+ "\u2215", "fraction",
+ "\u20A3", "franc",
+ "\u0067", "g",
+ "\u03B3", "gamma",
+ "\u011F", "gbreve",
+ "\u01E7", "gcaron",
+ "\u011D", "gcircumflex",
+ "\u0123", "gcommaaccent",
+ "\u0121", "gdotaccent",
+ "\u00DF", "germandbls",
+ "\u2207", "gradient",
+ "\u0060", "grave",
+ "\u0300", "gravecomb",
+ "\u003E", "greater",
+ "\u2265", "greaterequal",
+ "\u00AB", "guillemotleft",
+ "\u00BB", "guillemotright",
+ "\u2039", "guilsinglleft",
+ "\u203A", "guilsinglright",
+ "\u0068", "h",
+ "\u0127", "hbar",
+ "\u0125", "hcircumflex",
+ "\u2665", "heart",
+ "\u0309", "hookabovecomb",
+ "\u2302", "house",
+ "\u02DD", "hungarumlaut",
+ "\u002D", "hyphen",
+ "\u00AD", "hyphen",
+ "\uF6E5", "hypheninferior",
+ "\uF6E6", "hyphensuperior",
+ "\u0069", "i",
+ "\u00ED", "iacute",
+ "\u012D", "ibreve",
+ "\u00EE", "icircumflex",
+ "\u00EF", "idieresis",
+ "\u00EC", "igrave",
+ "\u0133", "ij",
+ "\u012B", "imacron",
+ "\u221E", "infinity",
+ "\u222B", "integral",
+ "\u2321", "integralbt",
+ "\uF8F5", "integralex",
+ "\u2320", "integraltp",
+ "\u2229", "intersection",
+ "\u25D8", "invbullet",
+ "\u25D9", "invcircle",
+ "\u263B", "invsmileface",
+ "\u012F", "iogonek",
+ "\u03B9", "iota",
+ "\u03CA", "iotadieresis",
+ "\u0390", "iotadieresistonos",
+ "\u03AF", "iotatonos",
+ "\uF6ED", "isuperior",
+ "\u0129", "itilde",
+ "\u006A", "j",
+ "\u0135", "jcircumflex",
+ "\u006B", "k",
+ "\u03BA", "kappa",
+ "\u0137", "kcommaaccent",
+ "\u0138", "kgreenlandic",
+ "\u006C", "l",
+ "\u013A", "lacute",
+ "\u03BB", "lambda",
+ "\u013E", "lcaron",
+ "\u013C", "lcommaaccent",
+ "\u0140", "ldot",
+ "\u003C", "less",
+ "\u2264", "lessequal",
+ "\u258C", "lfblock",
+ "\u20A4", "lira",
+ "\uF6C0", "ll",
+ "\u2227", "logicaland",
+ "\u00AC", "logicalnot",
+ "\u2228", "logicalor",
+ "\u017F", "longs",
+ "\u25CA", "lozenge",
+ "\u0142", "lslash",
+ "\uF6EE", "lsuperior",
+ "\u2591", "ltshade",
+ "\u006D", "m",
+ "\u00AF", "macron",
+ "\u02C9", "macron",
+ "\u2642", "male",
+ "\u2212", "minus",
+ "\u2032", "minute",
+ "\uF6EF", "msuperior",
+ "\u00B5", "mu",
+ "\u03BC", "mu",
+ "\u00D7", "multiply",
+ "\u266A", "musicalnote",
+ "\u266B", "musicalnotedbl",
+ "\u006E", "n",
+ "\u0144", "nacute",
+ "\u0149", "napostrophe",
+ "\u0148", "ncaron",
+ "\u0146", "ncommaaccent",
+ "\u0039", "nine",
+ "\u2089", "nineinferior",
+ "\uF739", "nineoldstyle",
+ "\u2079", "ninesuperior",
+ "\u2209", "notelement",
+ "\u2260", "notequal",
+ "\u2284", "notsubset",
+ "\u207F", "nsuperior",
+ "\u00F1", "ntilde",
+ "\u03BD", "nu",
+ "\u0023", "numbersign",
+ "\u006F", "o",
+ "\u00F3", "oacute",
+ "\u014F", "obreve",
+ "\u00F4", "ocircumflex",
+ "\u00F6", "odieresis",
+ "\u0153", "oe",
+ "\u02DB", "ogonek",
+ "\u00F2", "ograve",
+ "\u01A1", "ohorn",
+ "\u0151", "ohungarumlaut",
+ "\u014D", "omacron",
+ "\u03C9", "omega",
+ "\u03D6", "omega1",
+ "\u03CE", "omegatonos",
+ "\u03BF", "omicron",
+ "\u03CC", "omicrontonos",
+ "\u0031", "one",
+ "\u2024", "onedotenleader",
+ "\u215B", "oneeighth",
+ "\uF6DC", "onefitted",
+ "\u00BD", "onehalf",
+ "\u2081", "oneinferior",
+ "\uF731", "oneoldstyle",
+ "\u00BC", "onequarter",
+ "\u00B9", "onesuperior",
+ "\u2153", "onethird",
+ "\u25E6", "openbullet",
+ "\u00AA", "ordfeminine",
+ "\u00BA", "ordmasculine",
+ "\u221F", "orthogonal",
+ "\u00F8", "oslash",
+ "\u01FF", "oslashacute",
+ "\uF6F0", "osuperior",
+ "\u00F5", "otilde",
+ "\u0070", "p",
+ "\u00B6", "paragraph",
+ "\u0028", "parenleft",
+ "\uF8ED", "parenleftbt",
+ "\uF8EC", "parenleftex",
+ "\u208D", "parenleftinferior",
+ "\u207D", "parenleftsuperior",
+ "\uF8EB", "parenlefttp",
+ "\u0029", "parenright",
+ "\uF8F8", "parenrightbt",
+ "\uF8F7", "parenrightex",
+ "\u208E", "parenrightinferior",
+ "\u207E", "parenrightsuperior",
+ "\uF8F6", "parenrighttp",
+ "\u2202", "partialdiff",
+ "\u0025", "percent",
+ "\u002E", "period",
+ "\u00B7", "periodcentered",
+ "\u2219", "periodcentered",
+ "\uF6E7", "periodinferior",
+ "\uF6E8", "periodsuperior",
+ "\u22A5", "perpendicular",
+ "\u2030", "perthousand",
+ "\u20A7", "peseta",
+ "\u03C6", "phi",
+ "\u03D5", "phi1",
+ "\u03C0", "pi",
+ "\u002B", "plus",
+ "\u00B1", "plusminus",
+ "\u211E", "prescription",
+ "\u220F", "product",
+ "\u2282", "propersubset",
+ "\u2283", "propersuperset",
+ "\u221D", "proportional",
+ "\u03C8", "psi",
+ "\u0071", "q",
+ "\u003F", "question",
+ "\u00BF", "questiondown",
+ "\uF7BF", "questiondownsmall",
+ "\uF73F", "questionsmall",
+ "\"", "quotedbl",
+// "\u0022", "quotedbl",
+ "\u201E", "quotedblbase",
+ "\u201C", "quotedblleft",
+ "\u201D", "quotedblright",
+ "\u2018", "quoteleft",
+ "\u201B", "quotereversed",
+ "\u2019", "quoteright",
+ "\u201A", "quotesinglbase",
+ "\u0027", "quotesingle",
+ "\u0072", "r",
+ "\u0155", "racute",
+ "\u221A", "radical",
+ "\uF8E5", "radicalex",
+ "\u0159", "rcaron",
+ "\u0157", "rcommaaccent",
+ "\u2286", "reflexsubset",
+ "\u2287", "reflexsuperset",
+ "\u00AE", "registered",
+ "\uF8E8", "registersans",
+ "\uF6DA", "registerserif",
+ "\u2310", "revlogicalnot",
+ "\u03C1", "rho",
+ "\u02DA", "ring",
+ "\uF6F1", "rsuperior",
+ "\u2590", "rtblock",
+ "\uF6DD", "rupiah",
+ "\u0073", "s",
+ "\u015B", "sacute",
+ "\u0161", "scaron",
+ "\u015F", "scedilla",
+ "\uF6C2", "scedilla",
+ "\u015D", "scircumflex",
+ "\u0219", "scommaaccent",
+ "\u2033", "second",
+ "\u00A7", "section",
+ "\u003B", "semicolon",
+ "\u0037", "seven",
+ "\u215E", "seveneighths",
+ "\u2087", "seveninferior",
+ "\uF737", "sevenoldstyle",
+ "\u2077", "sevensuperior",
+ "\u2592", "shade",
+ "\u03C3", "sigma",
+ "\u03C2", "sigma1",
+ "\u223C", "similar",
+ "\u0036", "six",
+ "\u2086", "sixinferior",
+ "\uF736", "sixoldstyle",
+ "\u2076", "sixsuperior",
+ "\u002F", "slash",
+ "\u263A", "smileface",
+ "\u0020", "space",
+ "\u00A0", "space",
+ "\u2660", "spade",
+ "\uF6F2", "ssuperior",
+ "\u00A3", "sterling",
+ "\u220B", "suchthat",
+ "\u2211", "summation",
+ "\u263C", "sun",
+ "\u0074", "t",
+ "\u03C4", "tau",
+ "\u0167", "tbar",
+ "\u0165", "tcaron",
+ "\u0163", "tcommaaccent",
+ "\u021B", "tcommaaccent",
+ "\u2234", "therefore",
+ "\u03B8", "theta",
+ "\u03D1", "theta1",
+ "\u00FE", "thorn",
+ "\u0033", "three",
+ "\u215C", "threeeighths",
+ "\u2083", "threeinferior",
+ "\uF733", "threeoldstyle",
+ "\u00BE", "threequarters",
+ "\uF6DE", "threequartersemdash",
+ "\u00B3", "threesuperior",
+ "\u02DC", "tilde",
+ "\u0303", "tildecomb",
+ "\u0384", "tonos",
+ "\u2122", "trademark",
+ "\uF8EA", "trademarksans",
+ "\uF6DB", "trademarkserif",
+ "\u25BC", "triagdn",
+ "\u25C4", "triaglf",
+ "\u25BA", "triagrt",
+ "\u25B2", "triagup",
+ "\uF6F3", "tsuperior",
+ "\u0032", "two",
+ "\u2025", "twodotenleader",
+ "\u2082", "twoinferior",
+ "\uF732", "twooldstyle",
+ "\u00B2", "twosuperior",
+ "\u2154", "twothirds",
+ "\u0075", "u",
+ "\u00FA", "uacute",
+ "\u016D", "ubreve",
+ "\u00FB", "ucircumflex",
+ "\u00FC", "udieresis",
+ "\u00F9", "ugrave",
+ "\u01B0", "uhorn",
+ "\u0171", "uhungarumlaut",
+ "\u016B", "umacron",
+ "\u005F", "underscore",
+ "\u2017", "underscoredbl",
+ "\u222A", "union",
+ "\u2200", "universal",
+ "\u0173", "uogonek",
+ "\u2580", "upblock",
+ "\u03C5", "upsilon",
+ "\u03CB", "upsilondieresis",
+ "\u03B0", "upsilondieresistonos",
+ "\u03CD", "upsilontonos",
+ "\u016F", "uring",
+ "\u0169", "utilde",
+ "\u0076", "v",
+ "\u0077", "w",
+ "\u1E83", "wacute",
+ "\u0175", "wcircumflex",
+ "\u1E85", "wdieresis",
+ "\u2118", "weierstrass",
+ "\u1E81", "wgrave",
+ "\u0078", "x",
+ "\u03BE", "xi",
+ "\u0079", "y",
+ "\u00FD", "yacute",
+ "\u0177", "ycircumflex",
+ "\u00FF", "ydieresis",
+ "\u00A5", "yen",
+ "\u1EF3", "ygrave",
+ "\u007A", "z",
+ "\u017A", "zacute",
+ "\u017E", "zcaron",
+ "\u017C", "zdotaccent",
+ "\u0030", "zero",
+ "\u2080", "zeroinferior",
+ "\uF730", "zerooldstyle",
+ "\u2070", "zerosuperior",
+ "\u03B6", "zeta"};
+
+ /** Return the glyphname from a string,
+ eg, glyphToString("\\") returns "backslash"
+ */
+ public static String glyphToString(String name) {
+ String ret="";
+ int i=unicode_glyphs.length;
+ for (int j=0; j<i; j+=2) {
+ if (unicode_glyphs[j+1].equals(name)) {
+ ret=unicode_glyphs[j];
+ j=i;
+ }
+ }
+ return ret;
+ }
+ /** Return the string representation of a glyphname,
+ eg stringToGlyph("backslash") returns "\\"
+ */
+ public static String stringToGlyph(String name) {
+ String ret="";
+ int i=unicode_glyphs.length;
+ for (int j=0; j<i; j+=2) {
+ if (unicode_glyphs[j].equals(name)) {
+ ret=unicode_glyphs[j+1];
+ j=i;
+ }
+ }
+ return ret;
+ }
+}
+
diff --git a/src/org/apache/fop/fonts/PFMFile.java b/src/org/apache/fop/fonts/PFMFile.java
index 8ab72dee1..5ebb011cc 100644
--- a/src/org/apache/fop/fonts/PFMFile.java
+++ b/src/org/apache/fop/fonts/PFMFile.java
@@ -51,6 +51,7 @@
package org.apache.fop.fonts;
import java.io.*;
+import java.util.Hashtable;
/**
* This class represents a PFM file (or parts of it) as a Java object.
@@ -84,7 +85,9 @@ public class PFMFile {
//Extent table
private int[] extentTable;
+ private Hashtable kerningTab;
public PFMFile() {
+ kerningTab=new Hashtable();
}
/**
@@ -146,8 +149,17 @@ public class PFMFile {
int size = inStream.readShort();
long extMetricsOffset = inStream.readInt();
long extentTableOffset = inStream.readInt();
- inStream.skip(12);
+ inStream.skip(4);
+ long kernPairOffset = inStream.readInt();
+ long kernTrackOffset = inStream.readInt();
long driverInfoOffset = inStream.readInt();
+
+ if (kernPairOffset > 0) {
+ inStream.reset();
+ inStream.skip(kernPairOffset);
+ loadKernPairs(inStream);
+ }
+
inStream.reset();
inStream.skip(driverInfoOffset);
postscriptName = inStream.readString();
@@ -166,6 +178,40 @@ public class PFMFile {
}
/**
+ * Parses the kernPairs part of the pfm file
+ *
+ * @param inStream The stream from which to read the PFM file.
+ */
+ private void loadKernPairs(PFMInputStream inStream) throws IOException {
+ int i = inStream.readShort();
+
+
+ System.out.println(i + " kerning pairs");
+ while (i > 0) {
+ int g1 = (int)inStream.readByte();
+ i--;
+ //System.out.print ("Char no: ("+g1+", ");
+
+ int g2 = (int)inStream.readByte();
+ //System.out.print (g2+") kern");
+
+ int adj = inStream.readShort();
+ if (adj > 0x8000)
+ adj=-(0x10000-adj);
+ //System.out.println (": " + adj);
+
+ String glyph1=Glyphs.tex8r[g1];
+ String glyph2=Glyphs.tex8r[g2];
+
+ Hashtable adjTab=(Hashtable)kerningTab.get(glyph1);
+ if (adjTab==null)
+ adjTab=new Hashtable();
+ adjTab.put(glyph2, new Integer(adj));
+ kerningTab.put(glyph1, adjTab);
+ }
+ }
+
+ /**
* Parses the extended metrics part of the PFM file.
*
* @param inStream The stream from which to read the PFM file.
@@ -204,6 +250,15 @@ public class PFMFile {
return windowsName;
}
+ /**
+ * Return the kerning table. The kerning table is a hastable with
+ * strings with glyphnames as keys, containing hashtables as value.
+ * The value hashtable contain a glyph name string key and an Integer value
+ */
+ public Hashtable getKerning() {
+ return kerningTab;
+ }
+
/**
* Returns the Postscript name of the font.
*
@@ -378,4 +433,4 @@ public class PFMFile {
public int getCharWidth(short which) {
return extentTable[which-dfFirstChar];
}
-} \ No newline at end of file
+}
diff --git a/src/org/apache/fop/fonts/TTFCmapEntry.java b/src/org/apache/fop/fonts/TTFCmapEntry.java
new file mode 100644
index 000000000..af1eb5c00
--- /dev/null
+++ b/src/org/apache/fop/fonts/TTFCmapEntry.java
@@ -0,0 +1,60 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+
+class TTFCmapEntry {
+ int platform_id;
+ int encoding_id;
+ long offset;
+
+ TTFCmapEntry() {
+ }
+}
diff --git a/src/org/apache/fop/fonts/TTFDirTabEntry.java b/src/org/apache/fop/fonts/TTFDirTabEntry.java
new file mode 100644
index 000000000..42fed9f3a
--- /dev/null
+++ b/src/org/apache/fop/fonts/TTFDirTabEntry.java
@@ -0,0 +1,85 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+import java.io.*;
+
+class TTFDirTabEntry {
+ byte[] tag;
+ int checksum;
+ long offset;
+ long length;
+
+ TTFDirTabEntry() {
+ tag = new byte[4];
+ }
+
+ /** Read Dir Tab, return tag name */
+ public String read(FontFileReader in) throws IOException {
+ tag[0]=in.readTTFByte();
+ tag[1]=in.readTTFByte();
+ tag[2]=in.readTTFByte();
+ tag[3]=in.readTTFByte();
+
+ in.skip(4); // Skip checksum
+
+ offset=in.readTTFULong();
+ length=in.readTTFULong();
+
+ System.out.println ("Read dir tab [" + tag[0]+
+ " "+tag[1] +
+ " "+tag[2] +
+ " "+tag[3] +
+ "] offset: " + offset +
+ " length: " + length +
+ " name: " + new String(tag));
+ return new String(tag, "ISO-8859-1");
+ }
+}
diff --git a/src/org/apache/fop/fonts/TTFFile.java b/src/org/apache/fop/fonts/TTFFile.java
new file mode 100644
index 000000000..06987e77a
--- /dev/null
+++ b/src/org/apache/fop/fonts/TTFFile.java
@@ -0,0 +1,528 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+import java.io.*;
+import java.util.Hashtable;
+
+public class TTFFile {
+ static final byte NTABS = 24;
+ static final int NMACGLYPHS = 258;
+ static final int MAX_CHAR_CODE = 255;
+ static final int ENC_BUF_SIZE = 1024;
+
+ boolean is_embeddable=true;
+ boolean hasSerifs=true;
+ Hashtable dirTabs;
+ Hashtable kerningTab;
+
+ /** Position inputstream to position indicated
+ in the dirtab offset + offset */
+ void seek_tab(FontFileReader in, String name, long offset)
+ throws IOException {
+ TTFDirTabEntry dt=(TTFDirTabEntry)dirTabs.get(name);
+ if (dt==null) {
+ System.out.println("Dirtab " + name + " not found.");
+ return;
+ }
+
+ in.seek_set(dt.offset+offset);
+ }
+
+ int get_ttf_funit(int n) {
+ int ret;
+ if (n < 0) {
+ long rest1=n % upem;
+ long storrest=1000*rest1;
+ long ledd2=rest1/storrest;
+ ret = -((-1000*n)/upem - (int)ledd2);
+ } else {
+ ret = (n/upem)*1000 + ((n % upem)*1000)/upem;
+ }
+
+ return ret;
+ }
+
+ int upem;
+ int ntabs;
+ int nhmtx;
+ int post_format;
+ int loca_format;
+ int nglyphs;
+ int nmglyphs;
+ int names_count;
+
+
+
+ TTFDirTabEntry dir_tab;
+ TTFMtxEntry mtx_tab[];
+ int[] mtx_encoded=null;
+ boolean reencoded=false;
+ String enc_names;
+
+ String fontName="";
+ String fullName="";
+ String notice="";
+ String familyName="";
+ String subFamilyName="";
+
+ long italicAngle = 0;
+ long isFixedPitch = 0;
+ int fontBBox1 = 0;
+ int fontBBox2 = 0;
+ int fontBBox3 = 0;
+ int fontBBox4 = 0;
+ int capHeight = 0;
+ int underlinePosition = 0;
+ int underlineThickness = 0;
+ int xHeight = 0;
+ int ascender = 0;
+ int descender = 0;
+
+ public void readFont(FontFileReader in) throws IOException {
+ int i, j, k, l, platform_id, encoding_id, language_id;
+ long n;
+ TTFDirTabEntry[] pd;
+ TTFMtxEntry[] pm;
+ String[] ps_glyphs_buf;
+
+ in.skip(4); // TTF_FIXED_SIZE
+ ntabs=in.readTTFUShort();
+ in.skip(6); // 3xTTF_USHORT_SIZE;
+
+ // Read Dir tabs
+ dirTabs=new Hashtable();
+ pd=new TTFDirTabEntry[ntabs];
+ //System.out.println("Reading " + ntabs + " dir tables");
+ for (i=0; i < ntabs; i++) {
+ pd[i]=new TTFDirTabEntry();
+ dirTabs.put(pd[i].read(in),
+ pd[i]);
+ }
+
+ seek_tab(in, "head", 2*4 + 2*4 + 2);
+ upem=in.readTTFUShort();
+
+ in.skip(16);
+
+ fontBBox1=in.readTTFShort();
+ fontBBox2=in.readTTFShort();
+ fontBBox3=in.readTTFShort();
+ fontBBox4=in.readTTFShort();
+
+ in.skip(2+2+2);
+
+ loca_format=in.readTTFShort();
+
+ seek_tab(in, "maxp", 4);
+ nglyphs=in.readTTFUShort();
+ //System.out.println("nglyphs= " + nglyphs);
+ mtx_tab=new TTFMtxEntry[nglyphs];
+
+ for (i=0; i < nglyphs; i++)
+ mtx_tab[i]=new TTFMtxEntry();
+
+ seek_tab(in, "hhea", 4);
+ ascender=in.readTTFShort(); // Use sTypoAscender in "OS/2" table?
+ descender=in.readTTFShort(); // Use sTypoDescender in "OS/2" table?
+
+ in.skip(2+2+3*2+8*2);
+ nhmtx=in.readTTFUShort();
+ //System.out.println("nhmtx: " + nhmtx);
+ seek_tab(in, "hmtx", 0);
+ for (i=0; i < nhmtx; i++) {
+ mtx_tab[i].wx=in.readTTFUShort();
+ in.skip(2);
+ }
+ // NB: Her skal det settes mer wx.
+
+ seek_tab(in, "post", 0);
+ post_format=in.readTTFLong();
+ italicAngle=in.readTTFULong();
+ //System.out.println("Italic angle: " + italicAngle);
+ underlinePosition=in.readTTFShort();
+ underlineThickness=in.readTTFShort();
+ isFixedPitch=in.readTTFULong();
+
+ in.skip(4*4);
+
+ switch (post_format) {
+ case 0x00010000:
+ //System.out.println("Postscript format 1");
+ for (i=0; i<Glyphs.mac_glyph_names.length; i++) {
+ mtx_tab[i].name=Glyphs.mac_glyph_names[i];
+ }
+ break;
+ case 0x00020000:
+ //System.out.println("Postscript format 2");
+ l = in.readTTFUShort();
+ for (i=0; i < l ; i++) {
+ mtx_tab[i].index=in.readTTFUShort();
+ }
+
+ TTFDirTabEntry dirTab=
+ (TTFDirTabEntry)dirTabs.get("post");
+ if (dirTab==null)
+ System.out.println("Can't find table 'post'");
+
+ n=dirTab.length - (in.getCurrentPos() - dirTab.offset);
+ ps_glyphs_buf=new String[(int)n];
+ int nn=(ps_glyphs_buf.length < nglyphs) ?
+ ps_glyphs_buf.length : nglyphs;
+ //System.out.println("Reading " + n + " glyphnames");
+ for (i=0; i < nn; i++) {
+ ps_glyphs_buf[i]=in.readTTFString(in.readTTFUByte());
+ }
+
+ for (i=0; i < l; i++) {
+ if (mtx_tab[i].index < NMACGLYPHS) {
+ mtx_tab[i].name = Glyphs.mac_glyph_names[mtx_tab[i].index];
+ } else {
+ k = mtx_tab[i].index - NMACGLYPHS ;
+ mtx_tab[i].name=ps_glyphs_buf[k];
+ }
+ }
+
+ break;
+ case 0x00030000:
+ //System.out.println("Postscript format 3 - index");
+ break;
+ default:
+ //System.out.println("Unknown format : " + post_format);
+ }
+
+ // Check if font is embeddable
+ if (dirTabs.get("OS/2") != null) {
+ seek_tab(in, "OS/2", 2*4);
+ int fsType=in.readTTFUShort();
+ if ((fsType & 2) == 0)
+ is_embeddable=false;
+ else
+ is_embeddable=true;
+ } else
+ is_embeddable=true;
+
+
+
+ seek_tab(in, "loca", 0);
+ for (i=0; i < nglyphs ; i++) {
+ mtx_tab[i].offset = (loca_format == 1 ? in.readTTFULong() :
+ (in.readTTFUShort() << 1));
+ }
+
+ TTFDirTabEntry dirTab =
+ (TTFDirTabEntry)dirTabs.get("glyf");
+ for (i=0; i < (nglyphs-1); i++) {
+ if (mtx_tab[i].offset != mtx_tab[i+1].offset) {
+ in.seek_set(dirTab.offset + mtx_tab[i].offset);
+ in.skip(2);
+ mtx_tab[i].bbox[0]=in.readTTFShort();
+ mtx_tab[i].bbox[1]=in.readTTFShort();
+ mtx_tab[i].bbox[2]=in.readTTFShort();
+ mtx_tab[i].bbox[3]=in.readTTFShort();
+ } else {
+ mtx_tab[i].bbox[0]=mtx_tab[0].bbox[0];
+ mtx_tab[i].bbox[1]=mtx_tab[0].bbox[1];
+ mtx_tab[i].bbox[2]=mtx_tab[0].bbox[2];
+ mtx_tab[i].bbox[3]=mtx_tab[0].bbox[3];
+ }
+ }
+
+ //System.out.println("nglyf="+nglyphs+" mtx="+mtx_tab.length);
+
+
+ n=((TTFDirTabEntry)dirTabs.get("glyf")).offset;
+ for (i=0; i < nglyphs; i++) {
+ if ((i+1) >= mtx_tab.length ||
+ mtx_tab[i].offset != mtx_tab[i+1].offset) {
+ in.seek_set(n+mtx_tab[i].offset);
+ in.skip(2);
+ mtx_tab[i].bbox[0]=in.readTTFShort();
+ mtx_tab[i].bbox[1]=in.readTTFShort();
+ mtx_tab[i].bbox[2]=in.readTTFShort();
+ mtx_tab[i].bbox[3]=in.readTTFShort();
+ } else {
+ mtx_tab[i].bbox[0]=mtx_tab[0].bbox[0];
+ mtx_tab[i].bbox[1]=mtx_tab[0].bbox[0];
+ mtx_tab[i].bbox[2]=mtx_tab[0].bbox[0];
+ mtx_tab[i].bbox[3]=mtx_tab[0].bbox[0];
+ }
+ //System.out.println(mtx_tab[i].toString(this));
+ }
+
+ seek_tab(in, "name", 2);
+ i = in.getCurrentPos();
+ n = in.readTTFUShort();
+ j = in.readTTFUShort() + i - 2;
+ i += 2*2;
+
+ while (n-- > 0) {
+ in.seek_set(i);
+ platform_id=in.readTTFUShort();
+ encoding_id=in.readTTFUShort();
+ language_id=in.readTTFUShort();
+ //System.out.println("Platform id: " + language_id);
+ //System.out.println("Encoding id: " + language_id);
+ //System.out.println("Language id: " + language_id);
+ k=in.readTTFUShort();
+ l=in.readTTFUShort();
+
+ if ((platform_id==1 && encoding_id==0) &&
+ (k==1 || k==2 || k==0 || k==4 || k==6)) {
+ in.seek_set(j+in.readTTFUShort());
+ String txt = in.readTTFString(l);
+ switch (k) {
+ case 0: notice=txt; break;
+ case 1: familyName=txt; break;
+ case 2: subFamilyName=txt;break;
+ case 4: fullName=txt; break;
+ case 6: fontName=txt; break;
+ }
+ if (!notice.equals("") && !fullName.equals("") &&
+ !fontName.equals("") && !familyName.equals("") &&
+ !subFamilyName.equals(""))
+ break;
+ }
+ i+=6*2;
+ }
+
+ dirTab=
+ (TTFDirTabEntry)dirTabs.get("PCLT");
+ if (dirTab!=null) {
+ in.seek_set(dirTab.offset + 4 + 4 + 2);
+ xHeight=in.readTTFUShort();
+ in.skip(2*2);
+ capHeight=in.readTTFUShort();
+ in.skip(2+16+8+6+1+1);
+
+ int serifStyle=in.readTTFUByte();
+ serifStyle=serifStyle >> 6;
+ serifStyle=serifStyle & 3;
+ if (serifStyle == 1)
+ hasSerifs=false;
+ else
+ hasSerifs=true;
+
+ } else {
+ // Approximate capHeight from height of "H"
+ for (i=0; i < mtx_tab.length; i++) {
+ if ("H".equals(mtx_tab[i].name))
+ capHeight=mtx_tab[i].bbox[3]-
+ mtx_tab[i].bbox[1];
+ }
+ }
+
+ // Read kerning
+ kerningTab=new Hashtable();
+ dirTab=
+ (TTFDirTabEntry)dirTabs.get("kern");
+ if (dirTab!=null) {
+ seek_tab(in, "kern", 2);
+ for (n=in.readTTFUShort(); n>0 ; n--) {
+ in.skip(2*2);
+ k=in.readTTFUShort();
+ if (!((k & 1)!=0) || (k & 2)!=0 || (k & 4)!=0)
+ return;
+ if ((k >> 8) !=0)
+ continue;
+
+ k=in.readTTFUShort();
+ in.skip(3 * 2);
+ while (k-- > 0) {
+ i=in.readTTFUShort();
+ j=in.readTTFUShort();
+ int kpx=in.readTTFShort();
+ if (kpx != 0) {
+ Hashtable adjTab=(Hashtable)kerningTab.get(mtx_tab[i].name);
+ if (adjTab==null)
+ adjTab=new java.util.Hashtable();
+ adjTab.put(mtx_tab[j].name, new Integer((int)get_ttf_funit(kpx)));
+ kerningTab.put(mtx_tab[i].name, adjTab);
+ }
+ }
+ }
+ //System.out.println(kerningTab.toString());
+ }
+ }
+
+
+ public void printStuff() {
+ System.out.println("Font name: " + fontName);
+ System.out.println("Full name: " + fullName);
+ System.out.println("Family name: " + familyName);
+ System.out.println("Subfamily name: " + subFamilyName);
+ System.out.println("Notice: " + notice);
+ System.out.println("xHeight: " + (int)get_ttf_funit(xHeight));
+ System.out.println("capheight: " + (int)get_ttf_funit(capHeight));
+
+ int italic=(int)(italicAngle>>16);
+ System.out.println("Italic: " + italic);
+ System.out.print("ItalicAngle: " + (short)(italicAngle/0x10000));
+ if ((italicAngle % 0x10000) > 0 )
+ System.out.print("."+(short)((italicAngle % 0x10000)*1000)/0x10000);
+ System.out.println();
+ System.out.println("Ascender: " + get_ttf_funit(ascender));
+ System.out.println("Descender: " + get_ttf_funit(descender));
+ System.out.println("FontBBox: [" + (int)get_ttf_funit(fontBBox1) +
+ " " + (int)get_ttf_funit(fontBBox2) +
+ " " + (int)get_ttf_funit(fontBBox3) +
+ " " + (int)get_ttf_funit(fontBBox4)+"]");
+ }
+
+ public static void main(String[] args) {
+ try {
+ TTFFile ttfFile=new TTFFile();
+ FontFileReader reader=
+ new FontFileReader(args[0]);
+
+ ttfFile.readFont(reader);
+ ttfFile.printStuff();
+
+ } catch (IOException ioe) {
+ System.out.println(ioe.toString());
+ }
+ }
+
+ public String getWindowsName() {
+ return new String(familyName+","+subFamilyName);
+ }
+ public String getPostscriptName() {
+ return fontName;
+ }
+ public String getCharSetName() {
+ return "WinAnsi";
+ }
+ public int getCapHeight() {
+ return (int)get_ttf_funit(capHeight);
+ }
+ public int getXHeight() {
+ return (int)get_ttf_funit(xHeight);
+ }
+ public int getFlags() {
+ int flags=32; // Use Adobe Standard charset
+ if (italicAngle != 0)
+ flags = flags | 64;
+ if (isFixedPitch != 0)
+ flags = flags | 2;
+ if (hasSerifs)
+ flags = flags | 1;
+ return flags;
+ }
+ public String getStemV() {
+ return "0";
+ }
+ public String getItalicAngle() {
+ String ia=Short.toString((short)(italicAngle/0x10000));
+ if ((italicAngle % 0x10000) > 0 )
+ ia=ia+("."+Short.toString((short)((short)((italicAngle % 0x10000)*1000)/0x10000)));
+
+ return ia;
+ }
+ public int[] getFontBBox() {
+ int[] fbb=new int[4];
+ fbb[0]=(int)get_ttf_funit(fontBBox1);
+ fbb[1]=(int)get_ttf_funit(fontBBox2);
+ fbb[2]=(int)get_ttf_funit(fontBBox3);
+ fbb[3]=(int)get_ttf_funit(fontBBox4);
+
+ return fbb;
+ }
+ public int getLowerCaseAscent() {
+ return (int)get_ttf_funit(ascender);
+ }
+ public int getLowerCaseDescent() {
+ return (int)get_ttf_funit(descender);
+ }
+ public short getLastChar() {
+ fixWidth();
+ return (short)(nmglyphs-1);
+ }
+ public short getFirstChar() {
+ return 0;
+ }
+
+ public int getCharWidth(int idx) {
+ fixWidth();
+
+ return (int)get_ttf_funit(mtx_encoded[idx]);
+ }
+
+ public Hashtable getKerning() {
+ return kerningTab;
+ }
+
+ public boolean isEmbeddable() {
+ return is_embeddable;
+ }
+ private void fixWidth() {
+ if (reencoded)
+ return;
+ reencoded=true;
+ //System.out.println("Reencoding widths");
+ nmglyphs=0;
+ mtx_encoded=new int[Glyphs.tex8r.length];
+
+ Hashtable existingGlyphs=new java.util.Hashtable();
+
+ for (int i=0; i < mtx_tab.length; i++)
+ existingGlyphs.put(mtx_tab[i].name, new Integer(mtx_tab[i].wx));
+
+
+ for (int i=0; i < Glyphs.tex8r.length; i++) {
+ nmglyphs++;
+ Integer wx=(Integer)existingGlyphs.get(Glyphs.tex8r[i]);
+ if (wx==null)
+ mtx_encoded[i]=0;
+ else
+ mtx_encoded[i]=wx.intValue();
+ }
+ }
+}
+
diff --git a/src/org/apache/fop/fonts/TTFMtxEntry.java b/src/org/apache/fop/fonts/TTFMtxEntry.java
new file mode 100644
index 000000000..c44c2c965
--- /dev/null
+++ b/src/org/apache/fop/fonts/TTFMtxEntry.java
@@ -0,0 +1,77 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+
+import java.io.*;
+
+class TTFMtxEntry {
+ int wx;
+ String name;
+ int index;
+ int[] bbox;
+ long offset;
+ byte found;
+
+ TTFMtxEntry() {
+ name="";
+ found=0;
+ bbox=new int[4];
+ }
+
+ public String toString(TTFFile t) {
+ return new String("Glyph "+name+ " index: " + index +
+ " bbox [ "+t.get_ttf_funit(bbox[0])+
+ " " + t.get_ttf_funit(bbox[1]) +
+ " " + t.get_ttf_funit(bbox[2]) +
+ " " + t.get_ttf_funit(bbox[3]) + "]" +
+ "wx: "+t.get_ttf_funit(wx));
+ }
+}
diff --git a/src/org/apache/fop/fonts/TTFSegEntry.java b/src/org/apache/fop/fonts/TTFSegEntry.java
new file mode 100644
index 000000000..9c7cbad8c
--- /dev/null
+++ b/src/org/apache/fop/fonts/TTFSegEntry.java
@@ -0,0 +1,61 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts;
+
+class TTFSegEntry {
+ int endCode;
+ int startCode;
+ int idDelta;
+ int idRangeOffset;
+
+ TTFSegEntry() {
+ }
+}
diff --git a/src/org/apache/fop/fonts/apps/PFMReader.java b/src/org/apache/fop/fonts/apps/PFMReader.java
index fc563d4d4..c7c1410f2 100644
--- a/src/org/apache/fop/fonts/apps/PFMReader.java
+++ b/src/org/apache/fop/fonts/apps/PFMReader.java
@@ -56,6 +56,9 @@ import org.apache.xerces.dom.*;
import org.apache.xml.serialize.*;
import org.apache.xalan.xslt.*;
import org.apache.fop.fonts.*;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
/**
* A tool which reads PFM files from Adobe Type 1 fonts and creates
@@ -73,37 +76,120 @@ public class PFMReader {
public PFMReader() {
}
+
+ /**
+ * Parse commandline arguments. put options in the Hashtable and return
+ * arguments in the String array
+ * the arguments: -fn Perpetua,Bold -cn PerpetuaBold per.ttf Perpetua.xml
+ * returns a String[] with the per.ttf and Perpetua.xml. The hash
+ * will have the (key, value) pairs: (-fn, Perpetua) and (-cn, PerpetuaBold)
+ */
+ private static String[] parseArguments(Hashtable options, String[] args) {
+ Vector arguments=new Vector();
+ for (int i=0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ i++;
+ if (i < args.length)
+ options.put(args[i-1], args[i]);
+ else
+ options.put(args[i-1], "");
+ } else {
+ arguments.addElement(args[i]);
+ }
+ }
+
+ String[] argStrings=new String[arguments.size()];
+ arguments.copyInto(argStrings);
+ return argStrings;
+ }
+
+ private final static void displayUsage() {
+ System.out.println(" java org.apache.fop.fonts.apps.PFMReader [options] metricfile.pfm xmlfile.xml\n");
+ System.out.println(" where options can be:\n");
+ System.out.println(" -fn <fontname>\n");
+ System.out.println(" default is to use the fontname in the .pfm file, but you can override\n");
+ System.out.println(" that name to make sure that the embedded font is used instead of installed\n");
+ System.out.println(" fonts when viewing documents with Acrobat Reader.\n");
+ System.out.println(" -cn <classname>\n");
+ System.out.println(" default is to use the fontname\n");
+ System.out.println(" -ef <path to the Type1 .pfb fontfile>\n");
+ System.out.println(" will add the possibility to embed the font. When running fop, fop will look\n");
+ System.out.println(" for this file to embed it\n");
+ System.out.println(" -er <path to Type1 fontfile relative to org/apache/fop/render/pdf/fonts>\n");
+ System.out.println(" you can also include the fontfile in the fop.jar file when building fop.\n");
+ System.out.println(" You can use both -ef and -er. The file specified in -ef will be searched first,\n");
+ System.out.println(" then the -er file.\n");
+ }
+
+
/**
* The main method for the PFM reader tool.
*
- * @param args Command-line arguments: [pfm-file] {[xml-file]}
- * If [xml-file] is not provided, then just a little preview of
- * the PFM ist displayed.
+ * @param args Command-line arguments: [options] metricfile.pfm xmlfile.xml
+ * where options can be:
+ * -fn <fontname>
+ * default is to use the fontname in the .pfm file, but you can override
+ * that name to make sure that the embedded font is used instead of installed
+ * fonts when viewing documents with Acrobat Reader.
+ * -cn <classname>
+ * default is to use the fontname
+ * -ef <path to the Type1 .pfb fontfile>
+ * will add the possibility to embed the font. When running fop, fop will look
+ * for this file to embed it
+ * -er <path to Type1 fontfile relative to org/apache/fop/render/pdf/fonts>
+ * you can also include the fontfile in the fop.jar file when building fop.
+ * You can use both -ef and -er. The file specified in -ef will be searched first,
+ * then the -er file.
*/
public static void main(String[] args) {
- PFMReader app = new PFMReader();
- app.invokedStandalone = true;
-
- System.out.println("PFM Reader v1.0");
- System.out.println();
-
- if (args.length > 0) {
- PFMFile pfm = app.loadPFM(args[0]);
- if (pfm != null) {
- app.preview(pfm);
-
- if (args.length > 1) {
- org.w3c.dom.Document doc = app.constructFontXML(pfm);
- doc = app.postProcessXML(doc);
- if (doc != null) {
- app.writeFontXML(doc, args[1]);
- }
- }
- }
- } else {
- System.out.println("Arguments: <source> [<target>]");
- System.out.println("Example: COM_____.pfm COM_____.xml");
- }
+ String embFile=null;
+ String embResource=null;
+ String className=null;
+ String fontName=null;
+
+ Hashtable options=new Hashtable();
+ String[] arguments=parseArguments(options, args);
+
+ PFMReader app = new PFMReader();
+ app.invokedStandalone = true;
+
+ System.out.println("PFM Reader v1.1");
+ System.out.println();
+
+ if (options.get("-ef") != null)
+ embFile=(String)options.get("-ef");
+
+ if (options.get("-er") != null)
+ embResource=(String)options.get("-er");
+
+ if (options.get("-fn") != null)
+ fontName=(String)options.get("-fn");
+
+ if (options.get("-cn") != null)
+ className=(String)options.get("-cn");
+
+ if (arguments.length != 2 ||
+ options.get("-h") != null ||
+ options.get("-help") != null ||
+ options.get("--help") != null)
+ displayUsage();
+ else {
+ PFMFile pfm = app.loadPFM(arguments[0]);
+ if (pfm != null) {
+ app.preview(pfm);
+
+ org.w3c.dom.Document doc = app.constructFontXML(pfm,
+ fontName,
+ className,
+ embResource,
+ embFile);
+
+ doc = app.postProcessXML(doc);
+ if (doc != null) {
+ app.writeFontXML(doc, arguments[1]);
+ }
+ }
+ }
}
/**
@@ -191,7 +277,9 @@ public class PFMReader {
* @param pfm The PFM file to generate the font metrics from.
* @return The DOM document representing the font metrics file.
*/
- public org.w3c.dom.Document constructFontXML(PFMFile pfm) {
+ public org.w3c.dom.Document constructFontXML(PFMFile pfm, String fontName,
+ String className, String resource,
+ String file) {
System.out.println("Creating xml font file...");
System.out.println();
@@ -214,8 +302,25 @@ public class PFMReader {
el = doc.createElement("class-name");
root.appendChild(el);
- el.appendChild(doc.createTextNode(s));
+ if (className != null)
+ el.appendChild(doc.createTextNode(className));
+ else
+ el.appendChild(doc.createTextNode(s));
+ el = doc.createElement("embedFile");
+ root.appendChild(el);
+ if (file==null)
+ el.appendChild(doc.createTextNode("null"));
+ else
+ el.appendChild(doc.createTextNode("\""+escapeString(file)+"\""));
+
+ el = doc.createElement("embedResource");
+ root.appendChild(el);
+ if (resource==null)
+ el.appendChild(doc.createTextNode("null"));
+ else
+ el.appendChild(doc.createTextNode("\""+escapeString(resource)+"\""));
+
el = doc.createElement("subtype");
root.appendChild(el);
el.appendChild(doc.createTextNode("Type1"));
@@ -290,6 +395,25 @@ public class PFMReader {
el.setAttribute("width", new Integer(pfm.getCharWidth(i)).toString());
}
+
+ // Get kerning
+ for (Enumeration enum=pfm.getKerning().keys(); enum.hasMoreElements();) {
+ String kpx1=(String)enum.nextElement();
+ el=doc.createElement("kerning");
+ el.setAttribute("kpx1", kpx1);
+ root.appendChild(el);
+ Element el2=null;
+
+ Hashtable h2=(Hashtable)pfm.getKerning().get(kpx1);
+ for (Enumeration enum2=h2.keys(); enum2.hasMoreElements(); ) {
+ String kpx2=(String)enum2.nextElement();
+ el2=doc.createElement("pair");
+ el2.setAttribute("kpx2", kpx2);
+ Integer val=(Integer)h2.get(kpx2);
+ el2.setAttribute("kern", val.toString());
+ el.appendChild(el2);
+ }
+ }
return doc;
}
@@ -301,53 +425,41 @@ public class PFMReader {
* @return A DOM document representing the processed font metrics file.
*/
public org.w3c.dom.Document postProcessXML(org.w3c.dom.Document doc) {
- try {
-
+ try {
+ OutputFormat format = new OutputFormat(doc); //Serialize DOM
+ XMLSerializer serial = new XMLSerializer(System.out, format);
+ serial.asDOMSerializer(); // As a DOM Serializer
+ serial.serialize(doc.getDocumentElement());
+
System.out.println("Postprocessing...");
System.out.println();
- // Create the 3 objects the XSLTProcessor needs to perform the transformation.
- org.apache.xalan.xslt.XSLTInputSource xmlSource =
- new org.apache.xalan.xslt.XSLTInputSource(doc);
+
InputStream xsl = this.getClass().getResourceAsStream(XSL_POSTPROCESS);
if (xsl == null) {
throw new Exception("Resource " + XSL_POSTPROCESS + " not found");
}
- org.apache.xalan.xslt.XSLTInputSource xslSheet =
- new org.apache.xalan.xslt.XSLTInputSource(xsl);
-
+
Document targetDoc = new DocumentImpl();
- org.apache.xalan.xslt.XSLTResultTarget xmlResult =
- new org.apache.xalan.xslt.XSLTResultTarget(targetDoc);
-
- // Use XSLTProcessorFactory to instantiate an XSLTProcessor.
- org.apache.xalan.xslt.XSLTProcessor processor =
- org.apache.xalan.xslt.XSLTProcessorFactory.getProcessor(
- new org.apache.xalan.xpath.xdom.XercesLiaison());
-
- // Perform the transformation.
- processor.process(xmlSource, xslSheet, xmlResult);
-
+ org.apache.fop.tools.xslt.XSLTransform.transform(doc, xsl, targetDoc);
+
System.out.println("Sorting...");
System.out.println();
// Sort the whole thing
- xmlSource.setNode(targetDoc);
+
xsl = this.getClass().getResourceAsStream(XSL_SORT);
if (xsl == null) {
throw new Exception("Resource " + XSL_SORT + " not found");
}
- xslSheet = new org.apache.xalan.xslt.XSLTInputSource(xsl);
+
org.w3c.dom.Document targetDocSorted = new DocumentImpl();
- xmlResult =
- new org.apache.xalan.xslt.XSLTResultTarget(targetDocSorted);
- // Perform the transformation (sort).
- processor.process(xmlSource, xslSheet, xmlResult);
+ org.apache.fop.tools.xslt.XSLTransform.transform(targetDoc, xsl, targetDocSorted);
return targetDocSorted;
@@ -356,4 +468,18 @@ public class PFMReader {
return null;
}
}
+
+
+ private String escapeString(String str) {
+ StringBuffer esc=new StringBuffer();
+
+ for (int i=0; i < str.length(); i++) {
+ if (str.charAt(i)=='\\')
+ esc.append("\\\\");
+ else
+ esc.append(str.charAt(i));
+ }
+
+ return esc.toString();
+ }
}
diff --git a/src/org/apache/fop/fonts/apps/TTFReader.java b/src/org/apache/fop/fonts/apps/TTFReader.java
new file mode 100644
index 000000000..f7dbe0bfd
--- /dev/null
+++ b/src/org/apache/fop/fonts/apps/TTFReader.java
@@ -0,0 +1,504 @@
+/* -- $Id$ --
+
+ ============================================================================
+ The Apache Software License, Version 1.1
+ ============================================================================
+
+ Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modifica-
+ tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ 3. The end-user documentation included with the redistribution, if any, must
+ include the following acknowledgment: "This product includes software
+ developed by the Apache Software Foundation (http://www.apache.org/)."
+ Alternately, this acknowledgment may appear in the software itself, if
+ and wherever such third-party acknowledgments normally appear.
+
+ 4. The names "Fop" and "Apache Software Foundation" must not be used to
+ endorse or promote products derived from this software without prior
+ written permission. For written permission, please contact
+ apache@apache.org.
+
+ 5. Products derived from this software may not be called "Apache", nor may
+ "Apache" appear in their name, without prior written permission of the
+ Apache Software Foundation.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many individuals
+ on behalf of the Apache Software Foundation and was originally created by
+ James Tauber <jtauber@jtauber.com>. For more information on the Apache
+ Software Foundation, please see <http://www.apache.org/>.
+
+ */
+package org.apache.fop.fonts.apps;
+
+import java.io.*;
+import org.w3c.dom.*;
+import org.apache.xerces.dom.*;
+import org.apache.xml.serialize.*;
+import org.apache.xalan.xslt.*;
+import org.apache.fop.fonts.*;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+/**
+ * A tool which reads TTF files and generates
+ * XML font metrics file for use in FOP.
+ *
+ */
+public class TTFReader {
+
+ static private final String XSL_POSTPROCESS = "TTFPostProcess.xsl";
+ static private final String XSL_SORT = "TTFPostProcessSort.xsl";
+
+ private boolean invokedStandalone = false;
+
+ public TTFReader() {
+ }
+
+
+ /**
+ * Parse commandline arguments. put options in the Hashtable and return
+ * arguments in the String array
+ * the arguments: -fn Perpetua,Bold -cn PerpetuaBold per.ttf Perpetua.xml
+ * returns a String[] with the per.ttf and Perpetua.xml. The hash
+ * will have the (key, value) pairs: (-fn, Perpetua) and (-cn, PerpetuaBold)
+ */
+ private static String[] parseArguments(Hashtable options, String[] args) {
+ Vector arguments=new Vector();
+ for (int i=0; i < args.length; i++) {
+ if (args[i].startsWith("-")) {
+ i++;
+ if (i < args.length)
+ options.put(args[i-1], args[i]);
+ else
+ options.put(args[i-1], "");
+ } else {
+ arguments.addElement(args[i]);
+ }
+ }
+
+ String[] argStrings=new String[arguments.size()];
+ arguments.copyInto(argStrings);
+ return argStrings;
+ }
+
+
+ private final static void displayUsage() {
+ System.out.println(" java org.apache.fop.fonts.apps.TTFReader [options] fontfile.ttf xmlfile.xml\n");
+ System.out.println(" where options can be:\n");
+ System.out.println(" -fn <fontname>\n");
+ System.out.println(" default is to use the fontname in the .ttf file, but you can override\n");
+ System.out.println(" that name to make sure that the embedded font is used instead of installed\n");
+ System.out.println(" fonts when viewing documents with Acrobat Reader.\n");
+ System.out.println(" -cn <classname>\n");
+ System.out.println(" default is to use the fontname\n");
+ System.out.println(" -ef <path to the truetype fontfile>\n");
+ System.out.println(" will add the possibility to embed the font. When running fop, fop will look\n");
+ System.out.println(" for this file to embed it\n");
+ System.out.println(" -er <path to truetype fontfile relative to org/apache/fop/render/pdf/fonts>\n");
+ System.out.println(" you can also include the fontfile in the fop.jar file when building fop.\n");
+ System.out.println(" You can use both -ef and -er. The file specified in -ef will be searched first,\n");
+ System.out.println(" then the -er file.\n");
+ }
+
+
+ /**
+ * The main method for the PFM reader tool.
+ *
+ * @param args Command-line arguments: [options] fontfile.ttf xmlfile.xml
+ * where options can be:
+ * -fn <fontname>
+ * default is to use the fontname in the .ttf file, but you can override
+ * that name to make sure that the embedded font is used instead of installed
+ * fonts when viewing documents with Acrobat Reader.
+ * -cn <classname>
+ * default is to use the fontname
+ * -ef <path to the truetype fontfile>
+ * will add the possibility to embed the font. When running fop, fop will look
+ * for this file to embed it
+ * -er <path to truetype fontfile relative to org/apache/fop/render/pdf/fonts>
+ * you can also include the fontfile in the fop.jar file when building fop.
+ * You can use both -ef and -er. The file specified in -ef will be searched first,
+ * then the -er file.
+ */
+ public static void main(String[] args) {
+ String embFile=null;
+ String embResource=null;
+ String className=null;
+ String fontName=null;
+
+ Hashtable options=new Hashtable();
+ String[] arguments=parseArguments(options, args);
+
+ TTFReader app = new TTFReader();
+ app.invokedStandalone = true;
+
+ System.out.println("TTF Reader v1.0");
+ System.out.println();
+
+ if (options.get("-ef") != null)
+ embFile=(String)options.get("-ef");
+
+ if (options.get("-er") != null)
+ embResource=(String)options.get("-er");
+
+ if (options.get("-fn") != null)
+ fontName=(String)options.get("-fn");
+
+ if (options.get("-cn") != null)
+ className=(String)options.get("-cn");
+
+ if (arguments.length != 2 ||
+ options.get("-h") != null ||
+ options.get("-help") != null ||
+ options.get("--help") != null)
+ displayUsage();
+ else {
+ TTFFile ttf = app.loadTTF(arguments[0]);
+ if (ttf != null) {
+ app.preview(ttf);
+
+ org.w3c.dom.Document doc = app.constructFontXML(ttf,
+ fontName,
+ className,
+ embResource,
+ embFile);
+
+ doc = app.postProcessXML(doc);
+ if (doc != null) {
+ app.writeFontXML(doc, arguments[1]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Read a TTF file and returns it as an object.
+ *
+ * @param filename The filename of the PFM file.
+ * @return The PFM as an object.
+ */
+ public TTFFile loadTTF(String filename) {
+ TTFFile ttfFile=new TTFFile();
+ try {
+ System.out.println("Reading " + filename + "...");
+ System.out.println();
+
+ FontFileReader reader = new FontFileReader(filename);
+ ttfFile.readFont(reader);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ return ttfFile;
+ }
+
+ /**
+ * Displays a preview of the TTF file on the console.
+ *
+ * @param ttf The TTF file to preview.
+ */
+ public void preview(TTFFile ttf) {
+ PrintStream out = System.out;
+
+ out.print("Font: ");
+ out.println(ttf.getWindowsName());
+ out.print("Name: ");
+ out.println(ttf.getPostscriptName());
+ out.print("CharSet: ");
+ out.println(ttf.getCharSetName());
+ out.print("CapHeight: ");
+ out.println(ttf.getCapHeight());
+ out.print("XHeight: ");
+ out.println(ttf.getXHeight());
+ out.print("LowerCaseAscent: ");
+ out.println(ttf.getLowerCaseAscent());
+ out.print("LowerCaseDescent: ");
+ out.println(ttf.getLowerCaseDescent());
+ out.print("Having widths for ");
+ out.print(ttf.getLastChar()-ttf.getFirstChar());
+ out.print(" characters (");
+ out.print(ttf.getFirstChar());
+ out.print("-");
+ out.print(ttf.getLastChar());
+ out.println(").");
+ out.print("for example: Char ");
+ out.print(ttf.getFirstChar());
+ out.print(" has a width of ");
+ out.println(ttf.getCharWidth(ttf.getFirstChar()));
+ out.println();
+ if (ttf.isEmbeddable())
+ out.println("This font might be embedded");
+ else
+ out.println("This font might not be embedded");
+ }
+
+ /**
+ * Writes the generated DOM Document to a file.
+ *
+ * @param doc The DOM Document to save.
+ * @param target The target filename for the XML file.
+ */
+ public void writeFontXML(org.w3c.dom.Document doc, String target) {
+ System.out.println("Writing xml font file " + target + "...");
+ System.out.println();
+
+ try {
+ OutputFormat format = new OutputFormat(doc); //Serialize DOM
+ FileWriter out = new FileWriter(target); //Writer will be a String
+ XMLSerializer serial = new XMLSerializer(out, format);
+ serial.asDOMSerializer(); // As a DOM Serializer
+
+ serial.serialize(doc.getDocumentElement());
+ out.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Generates the font metrics file from the PFM file.
+ *
+ * @param pfm The PFM file to generate the font metrics from.
+ * @return The DOM document representing the font metrics file.
+ */
+ public org.w3c.dom.Document constructFontXML(TTFFile ttf, String fontName,
+ String className, String resource,
+ String file) {
+ System.out.println("Creating xml font file...");
+ System.out.println();
+
+ Document doc = new DocumentImpl();
+ Element root = doc.createElement("font-metrics");
+ doc.appendChild(root);
+
+ Element el = doc.createElement("font-name");
+ root.appendChild(el);
+
+ // Note that the PostScript name usually is something like
+ // "Perpetua-Bold", but the TrueType spec says that in the ttf file
+ // it should be "Perpetua,Bold".
+
+ String s = ttf.getPostscriptName();
+
+ if (fontName != null)
+ el.appendChild(doc.createTextNode(fontName));
+ else
+ el.appendChild(doc.createTextNode(s.replace('-', ',')));
+
+ int pos = s.indexOf("-");
+ if (pos >= 0) {
+ char sb[] = new char[s.length() - 1];
+ s.getChars(0, pos, sb, 0);
+ s.getChars(pos + 1, s.length(), sb, pos);
+ s = new String(sb);
+ }
+
+ el = doc.createElement("class-name");
+ root.appendChild(el);
+ if (className != null)
+ el.appendChild(doc.createTextNode(className));
+ else
+ el.appendChild(doc.createTextNode(s));
+
+ el = doc.createElement("embedFile");
+ root.appendChild(el);
+ //if (file==null || !ttf.isEmbeddable())
+ if (file==null)
+ el.appendChild(doc.createTextNode("null"));
+ else
+ el.appendChild(doc.createTextNode("\""+escapeString(file)+"\""));
+
+ el = doc.createElement("embedResource");
+ root.appendChild(el);
+ //if (resource==null || !ttf.isEmbeddable())
+ if (resource==null)
+ el.appendChild(doc.createTextNode("null"));
+ else
+ el.appendChild(doc.createTextNode("\""+escapeString(resource)+"\""));
+
+ el = doc.createElement("subtype");
+ root.appendChild(el);
+ el.appendChild(doc.createTextNode("TRUETYPE"));
+
+ el = doc.createElement("encoding");
+ root.appendChild(el);
+ el.appendChild(doc.createTextNode(ttf.getCharSetName()+"Encoding"));
+
+ el = doc.createElement("cap-height");
+ root.appendChild(el);
+ Integer value = new Integer(ttf.getCapHeight());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("x-height");
+ root.appendChild(el);
+ value = new Integer(ttf.getXHeight());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("ascender");
+ root.appendChild(el);
+ value = new Integer(ttf.getLowerCaseAscent());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("descender");
+ root.appendChild(el);
+ value = new Integer(ttf.getLowerCaseDescent());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ Element bbox = doc.createElement("bbox");
+ root.appendChild(bbox);
+ int[] bb = ttf.getFontBBox();
+ String[] names = {"left","bottom","right","top"};
+ for (int i=0; i<4; i++) {
+ el = doc.createElement(names[i]);
+ bbox.appendChild(el);
+ value = new Integer(bb[i]);
+ el.appendChild(doc.createTextNode(value.toString()));
+ }
+
+ el = doc.createElement("flags");
+ root.appendChild(el);
+ value = new Integer(ttf.getFlags());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("stemv");
+ root.appendChild(el);
+ value = new Integer(ttf.getStemV());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("italicangle");
+ root.appendChild(el);
+ value = new Integer(ttf.getItalicAngle());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("first-char");
+ root.appendChild(el);
+ value = new Integer(ttf.getFirstChar());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ el = doc.createElement("last-char");
+ root.appendChild(el);
+ value = new Integer(ttf.getLastChar());
+ el.appendChild(doc.createTextNode(value.toString()));
+
+ Element widths = doc.createElement("widths");
+ root.appendChild(widths);
+
+ for (short i = ttf.getFirstChar(); i < ttf.getLastChar(); i++) {
+ el = doc.createElement("char");
+ widths.appendChild(el);
+ //el.setAttribute("ansichar", "0x00" + Integer.toHexString(i).toUpperCase());
+ el.setAttribute("name", "0x00" +
+ Integer.toHexString(i).toUpperCase());
+ el.setAttribute("width",
+ new Integer(ttf.getCharWidth(i)).toString());
+ }
+
+ // Get kerning
+ for (Enumeration enum=ttf.getKerning().keys(); enum.hasMoreElements();) {
+ String kpx1=(String)enum.nextElement();
+ el=doc.createElement("kerning");
+ el.setAttribute("kpx1", kpx1);
+ root.appendChild(el);
+ Element el2=null;
+
+ Hashtable h2=(Hashtable)ttf.getKerning().get(kpx1);
+ for (Enumeration enum2=h2.keys(); enum2.hasMoreElements(); ) {
+ String kpx2=(String)enum2.nextElement();
+ el2=doc.createElement("pair");
+ el2.setAttribute("kpx2", kpx2);
+ Integer val=(Integer)h2.get(kpx2);
+ el2.setAttribute("kern", val.toString());
+ el.appendChild(el2);
+ }
+ }
+ return doc;
+ }
+
+ /**
+ * Modifies the generated font metrics file. First, it processes the
+ * character mmappings, then it sorts them.
+ *
+ * @param doc The DOM document representing the font metrics file.
+ * @return A DOM document representing the processed font metrics file.
+ */
+ public org.w3c.dom.Document postProcessXML(org.w3c.dom.Document doc) {
+ if (true)
+ return doc;
+ try {
+ OutputFormat format = new OutputFormat(doc); //Serialize DOM
+ XMLSerializer serial = new XMLSerializer(System.out, format);
+ serial.asDOMSerializer(); // As a DOM Serializer
+ serial.serialize(doc.getDocumentElement());
+
+ System.out.println("Postprocessing...");
+ System.out.println();
+
+
+
+ InputStream xsl = this.getClass().getResourceAsStream(XSL_POSTPROCESS);
+ if (xsl == null) {
+ throw new Exception("Resource " + XSL_POSTPROCESS + " not found");
+ }
+
+ Document targetDoc = new DocumentImpl();
+ org.apache.fop.tools.xslt.XSLTransform.transform(doc, xsl, targetDoc);
+
+
+ System.out.println("Sorting...");
+ System.out.println();
+
+ // Sort the whole thing
+
+
+ xsl = this.getClass().getResourceAsStream(XSL_SORT);
+ if (xsl == null) {
+ throw new Exception("Resource " + XSL_SORT + " not found");
+ }
+
+
+ org.w3c.dom.Document targetDocSorted = new DocumentImpl();
+
+ org.apache.fop.tools.xslt.XSLTransform.transform(targetDoc, xsl, targetDocSorted);
+
+ return targetDocSorted;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private String escapeString(String str) {
+ StringBuffer esc=new StringBuffer();
+
+ for (int i=0; i < str.length(); i++) {
+ if (str.charAt(i)=='\\')
+ esc.append("\\\\");
+ else
+ esc.append(str.charAt(i));
+ }
+
+ return esc.toString();
+ }
+}
+