+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-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;
- }
-
- /**
- * Write a USHort at a given position
- */
- public final void writeTTFUShort(int pos, int val) throws IOException {
- if ((pos + 2) > fsize)
- throw new java.io.EOFException("Reached EOF");
- byte b1 = (byte)((val >> 8) & 0xff);
- byte b2 = (byte)(val & 0xff);
- file[pos] = b1;
- file[pos + 1] = b2;
- }
-
- /**
- * Read 2 bytes signed from InputStream at position pos
- * without changing current position
- */
- public final short readTTFShort(long pos) throws IOException {
- long cp = getCurrentPos();
- seek_set(pos);
- short ret = readTTFShort();
- seek_set(cp);
- return ret;
- }
-
- /**
- * Read 2 bytes unsigned from InputStream at position pos
- * without changing current position
- */
- public final int readTTFUShort(long pos) throws IOException {
- long cp = getCurrentPos();
- seek_set(pos);
- int ret = readTTFUShort();
- seek_set(cp);
- return 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");
- }
-
- /**
- * Return a copy of the internal array
- * @throws IOException if out of bounds
- */
- public byte[] getBytes(int offset,
- int length) throws java.io.IOException {
- if ((offset + length) > fsize)
- throw new java.io.IOException("Reached EOF");
-
- byte[] ret = new byte[length];
- System.arraycopy(file, offset, ret, 0, length);
- return ret;
- }
-
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-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"
- };
-
- /**
- * The characters in WinAnsiEncoding
- */
- public static char[] winAnsiEncoding = {
- // not used until char 32
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
- ' ', '\u0021', '\"', '\u0023', '$', '%', '&', '\'', '(', ')', '*', '+', ',',
- '\u002d', '\u002e', '/', // 0x30
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
- '>', '?', '@', // 0x40
- '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', '\u005b', '\\',
- '\u005d', '^', '_', // 0x60
- '\u2018', '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', '\u007b', '\u007c', '\u007d',
- '\u007e', '\u2022', // 0x80
- '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022',
- '\u017d', '\u2022', // 0x90
- '\u2022', '\u2018', // quoteleft
- '\u2019', // quoteright
- '\u201c', // quotedblleft
- '\u201d', // quotedblright
- '\u2022', // bullet
- '\u2013', // endash
- '\u2014', // emdash
- '~', '\u2022', // bullet
- '\u0161', '\u203a', '\u0153', '\u2022', '\u017e', '\u0178', // 0xA0
- ' ', '\u00a1', '\u00a2', '\u00a3', '\u00a4', '\u00a5',
- '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab',
- '\u00ac', '\u00ad', '\u00ae', '\u00af', // 0xb0
- '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4',
- '\u00b5', // This is hand-coded, the rest is assumption
- '\u00b6', // and *might* not be correct...
- '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd',
- '\u00be', '\u00bf', // 0xc0
- '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', // Aring
- '\u00c6', // AE
- '\u00c7', '\u00c8', '\u00c9', '\u00ca', '\u00cb', '\u00cc',
- '\u00cd', '\u00ce', '\u00cf', // 0xd0
- '\u00d0', '\u00d1', '\u00d2', '\u00d3', '\u00d4', '\u00d5',
- '\u00d6', '\u00d7', '\u00d8', // Oslash
- '\u00d9', '\u00da', '\u00db', '\u00dc', '\u00dd', '\u00de',
- '\u00df', // 0xe0
- '\u00e0', '\u00e1', '\u00e2', '\u00e3', '\u00e4', '\u00e5', // aring
- '\u00e6', // ae
- '\u00e7', '\u00e8', '\u00e9', '\u00ea', '\u00eb', '\u00ec',
- '\u00ed', '\u00ee', '\u00ef', // 0xf0
- '\u00f0', '\u00f1', '\u00f2', '\u00f3', '\u00f4', '\u00f5',
- '\u00f6', '\u00f7', '\u00f8', '\u00f9', '\u00fa', '\u00fb',
- '\u00fc', '\u00fd', '\u00fe', '\u00ff'
- };
-
- 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;
- }
-
-}
-
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-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.
- *
- * @author jeremias.maerki@outline.ch
- */
-public class PFMFile {
-
- // Header stuff
- private String windowsName;
- private String postscriptName;
- private short dfItalic;
- private int dfWeight;
- private short dfCharSet;
- private short dfPitchAndFamily;
- private int dfAvgWidth;
- private int dfMaxWidth;
- private int dfMinWidth;
- private short dfFirstChar;
- private short dfLastChar;
-
- // Extension stuff
- // ---
-
- // Extend Text Metrics
- private int etmCapHeight;
- private int etmXHeight;
- private int etmLowerCaseAscent;
- private int etmLowerCaseDescent;
-
- // Extent table
- private int[] extentTable;
-
- private Hashtable kerningTab;
- public PFMFile() {
- kerningTab = new Hashtable();
- }
-
- /**
- * Parses a PFM file
- *
- * @param inStream The stream from which to read the PFM file.
- */
- public void load(InputStream inStream) throws IOException {
- InputStream bufin = new BufferedInputStream(inStream, 1024);
- bufin.mark(1024);
- PFMInputStream in = new PFMInputStream(bufin);
- int version = in.readShort();
- long filesize = in.readInt();
- bufin.reset();
-
- byte[] buf = new byte[(int)filesize];
- bufin.read(buf, 0, (int)filesize);
-
- bufin = new ByteArrayInputStream(buf);
- in = new PFMInputStream(bufin);
- loadHeader(in);
- loadExtension(in);
- }
-
- /**
- * Parses the header of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadHeader(PFMInputStream inStream) throws IOException {
- inStream.skip(80);
- dfItalic = inStream.readByte();
- inStream.skip(2);
- dfWeight = inStream.readShort();
- dfCharSet = inStream.readByte();
- inStream.skip(4);
- dfPitchAndFamily = inStream.readByte();
- dfAvgWidth = inStream.readShort();
- dfMaxWidth = inStream.readShort();
- dfFirstChar = inStream.readByte();
- dfLastChar = inStream.readByte();
- inStream.skip(8);
- long faceOffset = inStream.readInt();
-
- inStream.reset();
- inStream.skip(faceOffset);
- windowsName = inStream.readString();
-
- inStream.reset();
- inStream.skip(117);
- }
-
- /**
- * Parses the extension part of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtension(PFMInputStream inStream) throws IOException {
- int size = inStream.readShort();
- long extMetricsOffset = inStream.readInt();
- long extentTableOffset = inStream.readInt();
- 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();
-
- if (extMetricsOffset != 0) {
- inStream.reset();
- inStream.skip(extMetricsOffset);
- loadExtMetrics(inStream);
- }
- if (extentTableOffset != 0) {
- inStream.reset();
- inStream.skip(extentTableOffset);
- loadExtentTable(inStream);
- }
-
- }
-
- /**
- * 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(new Integer(g1));
- if (adjTab == null)
- adjTab = new Hashtable();
- adjTab.put(new Integer(g2), new Integer(adj));
- kerningTab.put(new Integer(g1), adjTab);
- }
- }
-
- /**
- * Parses the extended metrics part of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtMetrics(PFMInputStream inStream) throws IOException {
- int size = inStream.readShort();
- inStream.skip(12);
- etmCapHeight = inStream.readShort();
- etmXHeight = inStream.readShort();
- etmLowerCaseAscent = inStream.readShort();
- etmLowerCaseDescent = inStream.readShort();
- }
-
- /**
- * Parses the extent table of the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- private void loadExtentTable(PFMInputStream inStream) throws IOException {
- extentTable = new int[dfLastChar - dfFirstChar + 1];
- dfMinWidth = dfMaxWidth;
- for (short i = dfFirstChar; i <= dfLastChar; i++) {
- extentTable[i - dfFirstChar] = inStream.readShort();
- if (extentTable[i - dfFirstChar] < dfMinWidth) {
- dfMinWidth = extentTable[i - dfFirstChar];
- }
- }
- }
-
- /**
- * Returns the Windows name of the font.
- *
- * @return The Windows name.
- */
- public String getWindowsName() {
- 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.
- *
- * @return The Postscript name.
- */
- public String getPostscriptName() {
- return postscriptName;
- }
-
- /**
- * Returns the charset used for the font.
- *
- * @return The charset (0=WinAnsi).
- */
- public short getCharSet() {
- return dfCharSet;
- }
-
- /**
- * Returns the charset of the font as a string.
- *
- * @return The name of the charset.
- */
- public String getCharSetName() {
- switch (dfCharSet) {
- case 0:
- return "WinAnsi";
- case 128:
- return "Shift-JIS (Japanese)";
- default:
- return "Unknown";
- }
- }
-
- /**
- * Returns the number of the character that defines
- * the first entry in the widths list.
- *
- * @return The number of the first character.
- */
- public short getFirstChar() {
- return dfFirstChar;
- }
-
- /**
- * Returns the number of the character that defines
- * the last entry in the widths list.
- *
- * @return The number of the last character.
- */
- public short getLastChar() {
- return dfLastChar;
- }
-
- /**
- * Returns the CapHeight parameter for the font (height of uppercase H).
- *
- * @return The CapHeight parameter.
- */
- public int getCapHeight() {
- return etmCapHeight;
- }
-
- /**
- * Returns the XHeight parameter for the font (height of lowercase x).
- *
- * @return The CapHeight parameter.
- */
- public int getXHeight() {
- return etmXHeight;
- }
-
- /**
- * Returns the LowerCaseAscent parameter for the font (height of lowercase d).
- *
- * @return The LowerCaseAscent parameter.
- */
- public int getLowerCaseAscent() {
- return etmLowerCaseAscent;
- }
-
- /**
- * Returns the LowerCaseDescent parameter for the font (height of lowercase p).
- *
- * @return The LowerCaseDescent parameter.
- */
- public int getLowerCaseDescent() {
- return etmLowerCaseDescent;
- }
-
- /**
- * Tells whether the font has proportional character spacing.
- *
- * @return ex. true for Times, false for Courier.
- */
- public boolean getIsProportional() {
- return ((dfPitchAndFamily & 1) == 1);
- }
-
- /**
- * Returns the bounding box for the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The calculated Font BBox.
- */
- public int[] getFontBBox() {
- int[] bbox = new int[4];
-
- // Just guessing....
- if (!getIsProportional() && (dfAvgWidth == dfMaxWidth)) {
- bbox[0] = -20;
- } else {
- bbox[0] = -100;
- }
- bbox[1] = -(getLowerCaseDescent() + 5);
- bbox[2] = dfMaxWidth + 10;
- bbox[3] = getLowerCaseAscent() + 5;
- return bbox;
- }
-
- /**
- * Returns the characteristics flags for the font as
- * needed for a PDF font descriptor (See PDF specs).
- *
- * @return The characteristics flags.
- */
- public int getFlags() {
- int flags = 0;
- if (!getIsProportional()) {
- flags |= 1;
- }
- if ((dfPitchAndFamily & 16) == 16) {
- flags |= 2;
- }
- if ((dfPitchAndFamily & 64) == 64) {
- flags |= 4;
- }
- if (dfCharSet == 0) {
- flags |= 6;
- }
- if (dfItalic != 0) {
- flags |= 7;
- }
- return flags;
- }
-
- /**
- * Returns the width of the dominant vertical stems of the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The vertical stem width.
- */
- public int getStemV() {
- // Just guessing....
- if (dfItalic != 0) {
- return (int)Math.round(dfMinWidth * 0.25);
- } else {
- return (int)Math.round(dfMinWidth * 0.6);
- }
- }
-
- /**
- * Returns the italic angle of the font.
- * Note: this value is just an approximation,
- * it does not really exist in the PFM file.
- *
- * @return The italic angle.
- */
- public int getItalicAngle() {
- if (dfItalic != 0) {
- return -16; // Just guessing....
- } else {
- return 0;
- }
- }
-
- /**
- * Returns the width of a character
- *
- * @param which The number of the character for which the width is requested.
- * @return The width of a character.
- */
- public int getCharWidth(short which) {
- return extentTable[which - dfFirstChar];
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-
-import java.io.*;
-
-/**
- * This is a helper class for reading PFM files. It defines functions for
- * extracting specific values out of the stream.
- *
- * @author jeremias.maerki@outline.ch
- */
-public class PFMInputStream extends java.io.FilterInputStream {
-
- DataInputStream inStream;
-
- /**
- * Constructs a PFMInputStream based on an InputStream representing the PFM file.
- *
- * @param inStream The stream from which to read the PFM file.
- */
- public PFMInputStream(InputStream in) {
- super(in);
- inStream = new DataInputStream(in);
- }
-
- /**
- * Parses a one byte value out of the stream.
- *
- * @return The value extracted.
- */
- public short readByte() throws IOException {
- short s = inStream.readByte();
- // Now, we've got to trick Java into forgetting the sign
- int s1 = (((s & 0xF0) >>> 4) << 4) + (s & 0x0F);
- return (short)s1;
- }
-
- /**
- * Parses a two byte value out of the stream.
- *
- * @return The value extracted.
- */
- public int readShort() throws IOException {
- int i = inStream.readShort();
-
- // Change byte order
- int high = (i & 0xFF00) >>> 8;
- int low = (i & 0x00FF) << 8;
- return low + high;
- }
-
- /**
- * Parses a four byte value out of the stream.
- *
- * @return The value extracted.
- */
- public long readInt() throws IOException {
- int i = inStream.readInt();
-
- // Change byte order
- int i1 = (i & 0xFF000000) >>> 24;
- int i2 = (i & 0x00FF0000) >>> 8;
- int i3 = (i & 0x0000FF00) << 8;
- int i4 = (i & 0x000000FF) << 24;
- return i1 + i2 + i3 + i4;
- }
-
- /**
- * Parses a zero-terminated string out of the stream.
- *
- * @return The value extracted.
- */
- public String readString() throws IOException {
- InputStreamReader reader = new InputStreamReader(in, "ISO-8859-1");
- StringBuffer buf = new StringBuffer();
- int ch = reader.read();
- while (ch != 0) {
- buf.append((char)ch);
- ch = reader.read();
- }
- return buf.toString();
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-
-/**
- * The CMap entry contains information of a Unicode range and the
- * the glyph indexes related to the range
- */
-public class TTFCmapEntry {
- public int unicodeStart;
- public int unicodeEnd;
- public int glyphStartIndex;
-
- TTFCmapEntry() {
- unicodeStart = 0;
- unicodeEnd = 0;
- glyphStartIndex = 0;
- }
-
- TTFCmapEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
- this.unicodeStart = unicodeStart;
- this.unicodeEnd = unicodeEnd;
- this.glyphStartIndex = glyphStartIndex;
- }
-
- public boolean equals(Object o) {
- if (o instanceof TTFCmapEntry) {
- TTFCmapEntry ce = (TTFCmapEntry)o;
- if (ce.unicodeStart == this.unicodeStart
- && ce.unicodeEnd == this.unicodeEnd
- && ce.glyphStartIndex == this.glyphStartIndex)
- return true;
- }
- return false;
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-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");
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-import java.io.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-
-/**
- * Reads a TrueType file or a TrueType Collection.
- * The TrueType spec can be found at the Microsoft
- * Typography site: http://www.microsoft.com/truetype/
- */
-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;
-
- static String encoding = "WinAnsiEncoding"; // Deafult encoding
- short firstChar = 0;
- boolean is_embeddable = true;
- boolean hasSerifs = true;
- Hashtable dirTabs; // Table directory
- Hashtable kerningTab; // for CIDs
- Hashtable ansiKerningTab; // For winAnsiEncoding
- Vector cmaps;
- Vector unicodeMapping; //
-
- int upem; // unitsPerEm from "head" table
- int nhmtx; // Number of horizontal metrics
- int post_format;
- int loca_format;
- long lastLoca = 0; // offset to last loca
- int nglyphs; // Number of glyphs in font (read from "maxp" table)
- int nmglyphs; // Used in fixWidths - remove?
-
- TTFMtxEntry mtx_tab[]; // Contains glyph data
- int[] mtx_encoded = null;
-
- 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;
-
- short lastChar = 0;
-
- int ansiWidth[];
- Hashtable ansiIndex;
-
- /**
- * 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);
- }
-
- /**
- * Convert from truetype unit to pdf unit based on the
- * unitsPerEm field in the "head" table
- * @param n truetype unit
- * @return pdf unit
- */
- 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;
- }
-
- /**
- * Read the cmap table,
- * return false if the table is not present or only unsupported
- * tables are present. Currently only unicode cmaps are supported.
- * Set the unicodeIndex in the TTFMtxEntries and fills in the
- * cmaps vector.
- */
- private boolean readCMAP(FontFileReader in) throws IOException {
-
- unicodeMapping = new Vector();
-
- /**
- * Read CMAP table and correct mtx_tab.index
- */
- int mtxPtr = 0;
-
- seek_tab(in, "cmap", 2);
- int num_cmap = in.readTTFUShort(); // Number of cmap subtables
- long cmap_unioffset = 0;
-
- // System.out.println(num_cmap+" cmap tables");
-
- /*
- * Read offset for all tables
- * We are only interested in the unicode table
- */
- for (int i = 0; i < num_cmap; i++) {
- int cmap_pid = in.readTTFUShort();
- int cmap_eid = in.readTTFUShort();
- long cmap_offset = in.readTTFULong();
-
- // System.out.println("Platform ID: "+cmap_pid+
- // " Encoding: "+cmap_eid);
-
- if (cmap_pid == 3 && cmap_eid == 1)
- cmap_unioffset = cmap_offset;
- }
-
- if (cmap_unioffset <= 0) {
- System.out.println("Unicode cmap table not present");
- return false;
- }
-
- // Read unicode cmap
- seek_tab(in, "cmap", cmap_unioffset);
- int cmap_format = in.readTTFUShort();
- int cmap_length = in.readTTFUShort();
-
- // System.out.println("CMAP format: "+cmap_format);
- if (cmap_format == 4) {
- in.skip(2); // Skip version number
- int cmap_segCountX2 = in.readTTFUShort();
- int cmap_searchRange = in.readTTFUShort();
- int cmap_entrySelector = in.readTTFUShort();
- int cmap_rangeShift = in.readTTFUShort();
-
- /*
- * System.out.println("segCountX2 : "+cmap_segCountX2);
- * System.out.println("searchRange : "+cmap_searchRange);
- * System.out.println("entrySelector: "+cmap_entrySelector);
- * System.out.println("rangeShift : "+cmap_rangeShift);
- */
-
- int cmap_endCounts[] = new int[cmap_segCountX2 / 2];
- int cmap_startCounts[] = new int[cmap_segCountX2 / 2];
- int cmap_deltas[] = new int[cmap_segCountX2 / 2];
- int cmap_rangeOffsets[] = new int[cmap_segCountX2 / 2];
-
- for (int i = 0; i < (cmap_segCountX2 / 2); i++) {
- cmap_endCounts[i] = in.readTTFUShort();
- }
-
- in.skip(2); // Skip reservedPad
-
- for (int i = 0; i < (cmap_segCountX2 / 2); i++) {
- cmap_startCounts[i] = in.readTTFUShort();
- }
-
- for (int i = 0; i < (cmap_segCountX2 / 2); i++) {
- cmap_deltas[i] = in.readTTFShort();
- }
-
- int startRangeOffset = in.getCurrentPos();
-
- for (int i = 0; i < (cmap_segCountX2 / 2); i++) {
- cmap_rangeOffsets[i] = in.readTTFUShort();
- }
-
- int glyphIdArrayOffset = in.getCurrentPos();
-
- // Insert the unicode id for the glyphs in mtx_tab
- // and fill in the cmaps Vector
-
- for (int i = 0; i < cmap_startCounts.length; i++) {
- /*
- * System.out.println(i+ ": "+cmap_startCounts[i]+
- * " - "+cmap_endCounts[i]);
- */
- for (int j = cmap_startCounts[i]; j <= cmap_endCounts[i];
- j++) {
-
- // Update lastChar
- if (j < 256 && j > lastChar)
- lastChar = (short)j;
-
- if (mtxPtr < mtx_tab.length) {
- int glyphIdx;
- if (cmap_rangeOffsets[i] != 0) {
- int glyphOffset =
- glyphIdArrayOffset
- + ((cmap_rangeOffsets[i] / 2) + (j - cmap_startCounts[i]) + (i) - cmap_segCountX2 / 2)
- * 2;
- in.seek_set(glyphOffset);
- glyphIdx = (in.readTTFUShort() + cmap_deltas[i])
- & 0xffff;
-
- unicodeMapping.addElement(new UnicodeMapping(glyphIdx,
- j));
- mtx_tab[glyphIdx].unicodeIndex.addElement(new Integer(j));
-
-
- // Also add winAnsiWidth
- if (false) {
- int d = j;
- if (j > 127)
- d = (int)org.apache.fop.render.pdf.CodePointMapping.map[j];
- if (d < ansiWidth.length)
- ansiWidth[d] = mtx_tab[glyphIdx].wx;
- } else {
- Vector v =
- (Vector)ansiIndex.get(new Integer(j));
- if (v != null) {
- for (Enumeration e = v.elements();
- e.hasMoreElements(); ) {
- Integer aIdx =
- (Integer)e.nextElement();
- ansiWidth[aIdx.intValue()] =
- mtx_tab[glyphIdx].wx;
- /*
- * System.out.println("Added width "+
- * mtx_tab[glyphIdx].wx +
- * " uni: " + j +
- * " ansi: " + aIdx.intValue());
- */
- }
- }
- }
- /*
- * System.out.println("Idx: "+
- * glyphIdx +
- * " Delta: " + cmap_deltas[i]+
- * " Unicode: " + j +
- * " name: " +
- * mtx_tab[glyphIdx].name);
- */
-
- } else {
-
- glyphIdx = (j + cmap_deltas[i]) & 0xffff;
-
- if (glyphIdx < mtx_tab.length)
- mtx_tab[glyphIdx].unicodeIndex.addElement(new Integer(j));
- else
- System.out.println("Glyph " + glyphIdx
- + " out of range: "
- + mtx_tab.length);
-
- unicodeMapping.addElement(new UnicodeMapping(glyphIdx,
- j));
- if (glyphIdx < mtx_tab.length)
- mtx_tab[glyphIdx].unicodeIndex.addElement(new Integer(j));
- else
- System.out.println("Glyph " + glyphIdx
- + " out of range: "
- + mtx_tab.length);
-
-
-
- // Also add winAnsiWidth
- if (false) {
- int d = j;
- if (j > 127)
- d = (int)org.apache.fop.render.pdf.CodePointMapping.map[j];
-
- if (d < ansiWidth.length)
- ansiWidth[d] = mtx_tab[glyphIdx].wx;
- } else {
- Vector v =
- (Vector)ansiIndex.get(new Integer(j));
- if (v != null) {
- for (Enumeration e = v.elements();
- e.hasMoreElements(); ) {
- Integer aIdx =
- (Integer)e.nextElement();
- ansiWidth[aIdx.intValue()] =
- mtx_tab[glyphIdx].wx;
- }
- }
- }
-
- /*
- * System.out.println("IIdx: "+
- * mtxPtr +
- * " Delta: " + cmap_deltas[i]+
- * " Unicode: " + j +
- * " name: " +
- * mtx_tab[(j+cmap_deltas[i]) & 0xffff].name);
- */
- }
- if (glyphIdx < mtx_tab.length) {
- if (mtx_tab[glyphIdx].unicodeIndex.size() < 2) {
- mtxPtr++;
- }
- }
- }
- }
- }
- }
- return true;
- }
-
-
-
- /**
- * Print first char/last char
- */
- private void print_max_min() {
- int min = 255;
- int max = 0;
- for (int i = 0; i < mtx_tab.length; i++) {
- if (mtx_tab[i].index < min)
- min = mtx_tab[i].index;
- if (mtx_tab[i].index > max)
- max = mtx_tab[i].index;
- }
- System.out.println("Min: " + min);
- System.out.println("Max: " + max);
- }
-
- public void readFont(FontFileReader in) throws IOException {
- readFont(in, (String)null);
- }
-
- /**
- * initialize the ansiWidths array (for winAnsiEncoding)
- * and fill with the missingwidth
- */
- private void initAnsiWidths() {
- ansiWidth = new int[256];
- for (int i = 0; i < 256; i++)
- ansiWidth[i] = mtx_tab[0].wx;
-
- // Create an index hash to the ansiWidth
- // Can't just index the winAnsiEncoding when inserting widths
- // same char (eg bullet) is repeated more than one place
- ansiIndex = new Hashtable();
- for (int i = 32; i < Glyphs.winAnsiEncoding.length; i++) {
- Integer ansi = new Integer(i);
- Integer uni = new Integer((int)Glyphs.winAnsiEncoding[i]);
-
- Vector v = (Vector)ansiIndex.get(uni);
- if (v == null) {
- v = new Vector();
- ansiIndex.put(uni, v);
- }
- v.addElement(ansi);
- }
- }
-
-
- /**
- * Read the font data
- * If the fontfile is a TrueType Collection (.ttc file)
- * The name of the font to read data for must be supplied,
- * else the name is ignored
- */
- public void readFont(FontFileReader in, String name) throws IOException {
-
- /*
- * Check if TrueType collection, and that the name
- * exists in the collection
- */
- if (!checkTTC(in, name, true))
- throw new IOException("Failed to read font");
-
- readDirTabs(in);
- readFontHeader(in);
- getNumGlyphs(in);
- System.out.println("Number of glyphs in font: " + nglyphs);
- readHorizontalHeader(in);
- readHorizontalMetrics(in);
- initAnsiWidths();
- readPostscript(in);
- readOS2(in);
- readIndexToLocation(in);
- readGlyf(in);
- readName(in);
- readPCLT(in);
- readCMAP(in); // Read cmap table and fill in ansiwidths
- createCMaps(); // Create cmaps for bfentries
- // print_max_min();
-
- readKerning(in);
- }
-
- private void createCMaps() {
- cmaps = new Vector();
- TTFCmapEntry tce = new TTFCmapEntry();
-
- Enumeration e = unicodeMapping.elements();
- UnicodeMapping um = (UnicodeMapping)e.nextElement();
- UnicodeMapping lastMapping = um;
-
- tce.unicodeStart = um.uIdx;
- tce.glyphStartIndex = um.gIdx;
-
- while (e.hasMoreElements()) {
- um = (UnicodeMapping)e.nextElement();
- if (((lastMapping.uIdx + 1) != um.uIdx)
- || ((lastMapping.gIdx + 1) != um.gIdx)) {
- tce.unicodeEnd = lastMapping.uIdx;
- cmaps.addElement(tce);
-
- tce = new TTFCmapEntry();
- tce.unicodeStart = um.uIdx;
- tce.glyphStartIndex = um.gIdx;
- }
- lastMapping = um;
- }
-
- tce.unicodeEnd = um.uIdx;
- cmaps.addElement(tce);
- }
-
- 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]);
-
- String name = null;
- if (args.length >= 2)
- name = args[1];
-
- ttfFile.readFont(reader, name);
- ttfFile.printStuff();
-
- } catch (IOException ioe) {
- System.out.println(ioe.toString());
- }
- }
-
- public String getWindowsName() {
- return new String(familyName + "," + subFamilyName);
- }
-
- public String getPostscriptName() {
- if ("Regular".equals(subFamilyName) || "Roman".equals(subFamilyName))
- return familyName;
- else
- return familyName + "," + subFamilyName;
- }
-
- public String getFamilyName() {
- return familyName;
- }
-
- public String getCharSetName() {
- return encoding;
- }
-
- 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));
-
- // This is the correct italic angle, however only int italic
- // angles are supported at the moment so this is commented out.
- /*
- * if ((italicAngle % 0x10000) > 0 )
- * ia=ia+(comma+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);
- }
-
- // This is only for WinAnsiEncoding, so the last char is
- // the last char < 256
- public short getLastChar() {
- return lastChar;
- }
-
- public short getFirstChar() {
- return firstChar;
- }
-
- public int[] getWidths() {
- int[] wx = new int[mtx_tab.length];
- for (int i = 0; i < wx.length; i++)
- wx[i] = (int)get_ttf_funit(mtx_tab[i].wx);
-
- return wx;
- }
-
- public int getCharWidth(int idx) {
- return (int)get_ttf_funit(ansiWidth[idx]);
- }
-
- public Hashtable getKerning() {
- return kerningTab;
- }
-
- public Hashtable getAnsiKerning() {
- return ansiKerningTab;
- }
-
- public boolean isEmbeddable() {
- return is_embeddable;
- }
-
-
- /**
- * Read Table Directory from the current position in the
- * FontFileReader and fill the global Hashtable dirTabs
- * with the table name (String) as key and a TTFDirTabEntry
- * as value.
- */
- protected void readDirTabs(FontFileReader in) throws IOException {
- in.skip(4); // TTF_FIXED_SIZE
- int ntabs = in.readTTFUShort();
- in.skip(6); // 3xTTF_USHORT_SIZE
-
- dirTabs = new Hashtable();
- TTFDirTabEntry[] pd = new TTFDirTabEntry[ntabs];
- // System.out.println("Reading " + ntabs + " dir tables");
- for (int i = 0; i < ntabs; i++) {
- pd[i] = new TTFDirTabEntry();
- dirTabs.put(pd[i].read(in), pd[i]);
- }
- }
-
- /**
- * Read the "head" table, this reads the bounding box and
- * sets the upem (unitsPerEM) variable
- */
- protected void readFontHeader(FontFileReader in) throws IOException {
- 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();
- }
-
- /**
- * Read the number of glyphs from the "maxp" table
- */
- protected void getNumGlyphs(FontFileReader in) throws IOException {
- seek_tab(in, "maxp", 4);
- nglyphs = in.readTTFUShort();
- }
-
-
- /**
- * Read the "hhea" table to find the ascender and descender and
- * size of "hmtx" table, i.e. a fixed size font might have only
- * one width
- */
- protected void readHorizontalHeader(FontFileReader in)
- throws IOException {
- 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("Number of horizontal metrics: " + nhmtx);
- }
-
- /**
- * Read "hmtx" table and put the horizontal metrics
- * in the mtx_tab array. If the number of metrics is less
- * than the number of glyphs (eg fixed size fonts), extend
- * the mtx_tab array and fill in the missing widths
- */
- protected void readHorizontalMetrics(FontFileReader in)
- throws IOException {
- seek_tab(in, "hmtx", 0);
-
- int mtx_size = (nglyphs > nhmtx) ? nglyphs : nhmtx;
- mtx_tab = new TTFMtxEntry[mtx_size];
-
- // System.out.println("*** Widths array: \n");
- for (int i = 0; i < mtx_size; i++)
- mtx_tab[i] = new TTFMtxEntry();
- for (int i = 0; i < nhmtx; i++) {
- mtx_tab[i].wx = in.readTTFUShort();
- mtx_tab[i].lsb = in.readTTFUShort();
- /*
- * System.out.println(" width["+i+"] = "+
- * get_ttf_funit(mtx_tab[i].wx)+";");
- */
- }
-
- if (nhmtx < mtx_size) {
- // Fill in the missing widths
- int lastWidth = mtx_tab[nhmtx - 1].wx;
- for (int i = nhmtx; i < mtx_size; i++) {
- mtx_tab[i].wx = lastWidth;
- mtx_tab[i].lsb = in.readTTFUShort();
- }
- }
- }
-
-
- /**
- * Read the "post" table
- * containing the postscript names of the glyphs.
- */
- private final void readPostscript(FontFileReader in) throws IOException {
- String[] ps_glyphs_buf;
- int i, k, l;
-
- seek_tab(in, "post", 0);
- post_format = in.readTTFLong();
- italicAngle = in.readTTFULong();
- underlinePosition = in.readTTFShort();
- underlineThickness = in.readTTFShort();
- isFixedPitch = in.readTTFULong();
-
- in.skip(4 * 4);
-
- // System.out.println("Post format: "+post_format);
- 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");
- int numGlyphStrings = 0;
- l = in.readTTFUShort(); // Num Glyphs
- // short minIndex=256;
- for (i = 0; i < l; i++) { // Read indexes
- mtx_tab[i].index = in.readTTFUShort();
- // if (minIndex > mtx_tab[i].index)
- // minIndex=(short)mtx_tab[i].index;
-
- if (mtx_tab[i].index > 257)
- numGlyphStrings++;
-
- // System.out.println("Post index: "+mtx_tab[i].index);
- }
- // firstChar=minIndex;
- ps_glyphs_buf = new String[numGlyphStrings];
- // System.out.println("Reading " + numGlyphStrings +
- // " glyphnames"+
- // ", was n num glyphs="+l);
- for (i = 0; i < ps_glyphs_buf.length; 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;
- /*
- * System.out.println(k+" i="+i+" mtx="+mtx_tab.length+
- * " ps="+ps_glyphs_buf.length);
- */
- mtx_tab[i].name = ps_glyphs_buf[k];
- }
- }
-
- break;
- case 0x00030000:
- // Postscript format 3 contains no glyph names
- System.out.println("Postscript format 3");
- break;
- default:
- System.out.println("Unknown Postscript format : " + post_format);
- }
- }
-
-
- /**
- * Read the "OS/2" table
- */
- private final void readOS2(FontFileReader in) throws IOException {
- // 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)
- is_embeddable = false;
- else
- is_embeddable = true;
- } else
- is_embeddable = true;
- }
-
- /**
- * Read the "loca" table
- */
- protected final void readIndexToLocation(FontFileReader in)
- throws IOException {
- seek_tab(in, "loca", 0);
- for (int i = 0; i < nglyphs; i++) {
- mtx_tab[i].offset = (loca_format == 1 ? in.readTTFULong()
- : (in.readTTFUShort() << 1));
- }
- lastLoca = (loca_format == 1 ? in.readTTFULong()
- : (in.readTTFUShort() << 1));
- }
-
- /**
- * Read the "glyf" table to find the bounding boxes
- */
- private final void readGlyf(FontFileReader in) throws IOException {
- TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("glyf");
- for (int 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];
- }
- }
-
-
- long n = ((TTFDirTabEntry)dirTabs.get("glyf")).offset;
- for (int 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));
- }
- }
-
- /**
- * Read the "name" table
- */
- private final void readName(FontFileReader in) throws IOException {
- int platform_id, encoding_id, language_id;
-
- seek_tab(in, "name", 2);
- int i = in.getCurrentPos();
- int n = in.readTTFUShort();
- int j = in.readTTFUShort() + i - 2;
- i += 2 * 2;
-
- while (n-- > 0) {
- // System.out.println("Iteration: "+n);
- in.seek_set(i);
- platform_id = in.readTTFUShort();
- encoding_id = in.readTTFUShort();
- language_id = in.readTTFUShort();
-
- int k = in.readTTFUShort();
- int l = in.readTTFUShort();
-
- if (((platform_id == 1 || platform_id == 3) && (encoding_id == 0 || encoding_id == 1))
- && (k == 1 || k == 2 || k == 0 || k == 4 || k == 6)) {
- // if (k==1 || k==2 || k==0 || k==4 || k==6) {
- in.seek_set(j + in.readTTFUShort());
- String txt = in.readTTFString(l);
- // System.out.println(platform_id+" "+encoding_id+
- // " "+k+" "+txt);
- 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;
- }
- }
-
- /**
- * Read the "PCLT" table to find xHeight and capHeight
- */
- private final void readPCLT(FontFileReader in) throws IOException {
- TTFDirTabEntry 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"
- // It's most unlikly that a font misses the PCLT table
- // This also assumes that psocriptnames exists ("H")
- // Should look it up int the cmap (that wouldn't help
- // for charsets without H anyway...)
- for (int 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 the kerning table, create a table for both CIDs and
- * winAnsiEncoding
- */
- private final void readKerning(FontFileReader in) throws IOException {
- // Read kerning
- kerningTab = new Hashtable();
- ansiKerningTab = new Hashtable();
- TTFDirTabEntry dirTab = (TTFDirTabEntry)dirTabs.get("kern");
- if (dirTab != null) {
- seek_tab(in, "kern", 2);
- for (int n = in.readTTFUShort(); n > 0; n--) {
- in.skip(2 * 2);
- int 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) {
- int i = in.readTTFUShort();
- int j = in.readTTFUShort();
- int kpx = in.readTTFShort();
- if (kpx != 0) {
- // CID table
- Integer iObj = new Integer(i);
- Hashtable adjTab = (Hashtable)kerningTab.get(iObj);
- if (adjTab == null)
- adjTab = new java.util.Hashtable();
- adjTab.put(new Integer(j),
- new Integer((int)get_ttf_funit(kpx)));
- kerningTab.put(iObj, adjTab);
- }
- }
- }
- // System.out.println(kerningTab.toString());
-
- // Create winAnsiEncoded kerning table
-
- for (Enumeration ae = kerningTab.keys(); ae.hasMoreElements(); ) {
- Integer cidKey = (Integer)ae.nextElement();
- Hashtable akpx = new Hashtable();
- Hashtable ckpx = (Hashtable)kerningTab.get(cidKey);
-
- for (Enumeration aee = ckpx.keys(); aee.hasMoreElements(); ) {
- Integer cidKey2 = (Integer)aee.nextElement();
- Integer kern = (Integer)ckpx.get(cidKey2);
-
- for (Enumeration uniMap = mtx_tab[cidKey2.intValue()].unicodeIndex.elements();
- uniMap.hasMoreElements(); ) {
- Integer unicodeKey = (Integer)uniMap.nextElement();
- Integer[] ansiKeys =
- unicodeToWinAnsi(unicodeKey.intValue());
- for (int u = 0; u < ansiKeys.length; u++) {
- akpx.put(ansiKeys[u], kern);
- }
- }
- }
-
- if (akpx.size() > 0)
- for (Enumeration uniMap = mtx_tab[cidKey.intValue()].unicodeIndex.elements();
- uniMap.hasMoreElements(); ) {
- Integer unicodeKey = (Integer)uniMap.nextElement();
- Integer[] ansiKeys =
- unicodeToWinAnsi(unicodeKey.intValue());
- for (int u = 0; u < ansiKeys.length; u++) {
- ansiKerningTab.put(ansiKeys[u], akpx);
- }
- }
- }
- }
- }
-
- /**
- * Return a vector with TTFCmapEntry
- */
- public Vector getCMaps() {
- return cmaps;
- }
-
- /**
- * Check if this is a TrueType collection and that the given
- * name exists in the collection.
- * If it does, set offset in fontfile to the beginning of
- * the Table Directory for that font
- * @ return true if not collection or font name present, false
- * otherwise
- */
- protected final boolean checkTTC(FontFileReader in, String name,
- boolean verbose) throws IOException {
- String tag = in.readTTFString(4);
-
- if ("ttcf".equals(tag)) {
- // This is a TrueType Collection
- in.skip(4);
-
- // Read directory offsets
- int numDirectories = (int)in.readTTFULong();
- // int numDirectories=in.readTTFUShort();
- long[] dirOffsets = new long[numDirectories];
- for (int i = 0; i < numDirectories; i++) {
- dirOffsets[i] = in.readTTFULong();
- }
-
- if (verbose) {
- System.out.println("This is a TrueType collection file with"
- + numDirectories + " fonts");
- System.out.println("Containing the following fonts: ");
- }
- // Read all the directories and name tables to check
- // If the font exists - this is a bit ugly, but...
- boolean found = false;
-
- // Iterate through all name tables even if font
- // Is found, just to show all the names
- long dirTabOffset = 0;
- for (int i = 0; (i < numDirectories); i++) {
- in.seek_set(dirOffsets[i]);
- readDirTabs(in);
-
- readName(in);
-
- if (fullName.equals(name)) {
- found = true;
- dirTabOffset = dirOffsets[i];
- if (verbose)
- System.out.println("* " + fullName);
- } else {
- if (verbose)
- System.out.println(fullName);
- }
-
- // Reset names
- notice = "";
- fullName = "";
- familyName = "";
- fontName = "";
- subFamilyName = "";
- }
-
- in.seek_set(dirTabOffset);
- return found;
- } else {
- in.seek_set(0);
- return true;
- }
- }
-
- /*
- * Helper classes, they are not very efficient, but that really
- * doesn't matter...
- */
- private Integer[] unicodeToWinAnsi(int unicode) {
- Vector ret = new Vector();
- for (int i = 32; i < Glyphs.winAnsiEncoding.length; i++)
- if (unicode == Glyphs.winAnsiEncoding[i])
- ret.addElement(new Integer(i));
- Integer[] itg = new Integer[ret.size()];
- ret.copyInto(itg);
- return itg;
- }
-
-}
-
-
-/**
- * Key-value helper class
- */
-class UnicodeMapping {
- int uIdx;
- int gIdx;
- UnicodeMapping(int gIdx, int uIdx) {
- this.uIdx = uIdx;
- this.gIdx = gIdx;
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-
-import java.io.*;
-import java.util.Vector;
-
-class TTFMtxEntry {
- int wx;
- int lsb;
- String name;
- int index;
- Vector unicodeIndex;
- int[] bbox;
- long offset;
- byte found;
-
- TTFMtxEntry() {
- name = "";
- found = 0;
- unicodeIndex = new Vector();
- 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));
- }
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-
-class TTFSegEntry {
- int endCode;
- int startCode;
- int idDelta;
- int idRangeOffset;
-
- TTFSegEntry() {}
-
-}
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-package org.apache.fop.fonts;
-import java.io.*;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
-import org.apache.fop.messaging.MessageHandler;
-
-/**
- * Reads a TrueType file and generates a subset
- * That can be used to embed a TrueType CID font
- * TrueType tables needed for embedded CID fonts are:
- * "head", "hhea", "loca", "maxp", "cvt ", "prep", "glyf", "hmtx" and "fpgm"
- * The TrueType spec can be found at the Microsoft
- * Typography site: http://www.microsoft.com/truetype/
- */
-public class TTFSubSetFile extends TTFFile {
- byte[] output = null;
- int realSize = 0;
- int currentPos = 0;
-
- /*
- * Offsets in name table to be filled out by table.
- * The offsets are to the checkSum field
- */
- int cvtDirOffset = 0;
- int fpgmDirOffset = 0;
- int glyfDirOffset = 0;
- int headDirOffset = 0;
- int hheaDirOffset = 0;
- int hmtxDirOffset = 0;
- int locaDirOffset = 0;
- int maxpDirOffset = 0;
- int prepDirOffset = 0;
-
- int checkSumAdjustmentOffset = 0;
- int locaOffset = 0;
-
- /**
- * Initalize the output array
- */
- private void init(int size) {
- output = new byte[size];
- realSize = 0;
- currentPos = 0;
-
- // createDirectory()
- }
-
- /**
- * Create the directory table
- */
- private void createDirectory() {
- int numTables = 9;
- // Create the TrueType header
- writeByte((byte)0);
- writeByte((byte)1);
- writeByte((byte)0);
- writeByte((byte)0);
- realSize += 4;
-
- writeUShort(numTables);
- realSize += 2;
-
- // Create searchRange, entrySelector and rangeShift
- int maxPow = maxPow2(numTables);
- int searchRange = maxPow * 16;
- writeUShort(searchRange);
- realSize += 2;
-
- writeUShort(maxPow);
- realSize += 2;
-
- writeUShort((numTables * 16) - searchRange);
- realSize += 2;
-
- // Create space for the table entries
- writeString("cvt ");
- cvtDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("fpgm");
- fpgmDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("glyf");
- glyfDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("head");
- headDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("hhea");
- hheaDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("hmtx");
- hmtxDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("loca");
- locaDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("maxp");
- maxpDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("prep");
- prepDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
- }
-
-
- /**
- * Copy the cvt table as is from original font to subset font
- */
- private void createCvt(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("cvt ");
- if (entry != null) {
- pad4();
- seek_tab(in, "cvt ", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
-
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(cvtDirOffset, checksum);
- writeULong(cvtDirOffset + 4, currentPos);
- writeULong(cvtDirOffset + 8, (int)entry.length);
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find cvt table");
- }
- }
-
-
-
- /**
- * Copy the fpgm table as is from original font to subset font
- */
- private void createFpgm(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("fpgm");
- if (entry != null) {
- pad4();
- seek_tab(in, "fpgm", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(fpgmDirOffset, checksum);
- writeULong(fpgmDirOffset + 4, currentPos);
- writeULong(fpgmDirOffset + 8, (int)entry.length);
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find fpgm table");
- }
- }
-
-
-
- /**
- * Create an empty loca table without updating checksum
- */
- private void createLoca(int size) throws IOException {
- pad4();
- locaOffset = currentPos;
- writeULong(locaDirOffset + 4, currentPos);
- writeULong(locaDirOffset + 8, size * 4 + 4);
- currentPos += size * 4 + 4;
- realSize += size * 4 + 4;
- }
-
-
- /**
- * Copy the maxp table as is from original font to subset font
- * and set num glyphs to size
- */
- private void createMaxp(FontFileReader in, int size) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("maxp");
- if (entry != null) {
- pad4();
- seek_tab(in, "maxp", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
- writeUShort(currentPos + 4, size);
-
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(maxpDirOffset, checksum);
- writeULong(maxpDirOffset + 4, currentPos);
- writeULong(maxpDirOffset + 8, (int)entry.length);
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find maxp table");
- }
- }
-
-
- /**
- * Copy the prep table as is from original font to subset font
- */
- private void createPrep(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("prep");
- if (entry != null) {
- pad4();
- seek_tab(in, "prep", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
-
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(prepDirOffset, checksum);
- writeULong(prepDirOffset + 4, currentPos);
- writeULong(prepDirOffset + 8, (int)entry.length);
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find prep table");
- }
- }
-
-
- /**
- * Copy the hhea table as is from original font to subset font
- * and fill in size of hmtx table
- */
- private void createHhea(FontFileReader in, int size) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hhea");
- if (entry != null) {
- pad4();
- seek_tab(in, "hhea", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
- writeUShort((int)entry.length + currentPos - 2, size);
-
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(hheaDirOffset, checksum);
- writeULong(hheaDirOffset + 4, currentPos);
- writeULong(hheaDirOffset + 8, (int)entry.length);
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find hhea table");
- }
- }
-
-
- /**
- * Copy the head table as is from original font to subset font
- * and set indexToLocaFormat to long and set
- * checkSumAdjustment to 0, store offset to checkSumAdjustment
- * in checkSumAdjustmentOffset
- */
- private void createHead(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("head");
- if (entry != null) {
- pad4();
- seek_tab(in, "head", 0);
- System.arraycopy(in.getBytes((int)entry.offset, (int)entry.length),
- 0, output, currentPos, (int)entry.length);
-
- checkSumAdjustmentOffset = currentPos + 8;
- output[currentPos + 8] = 0; // Set checkSumAdjustment to 0
- output[currentPos + 9] = 0;
- output[currentPos + 10] = 0;
- output[currentPos + 11] = 0;
- output[currentPos + 50] = 0; // long locaformat
- output[currentPos + 51] = 1; // long locaformat
-
- int checksum = getCheckSum(currentPos, (int)entry.length);
- writeULong(headDirOffset, checksum);
- writeULong(headDirOffset + 4, currentPos);
- writeULong(headDirOffset + 8, (int)entry.length);
-
- currentPos += (int)entry.length;
- realSize += (int)entry.length;
- } else {
- throw new IOException("Can't find head table");
- }
- }
-
-
- /**
- * Create the glyf table and fill in loca table
- */
- private void createGlyf(FontFileReader in,
- Hashtable glyphs) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf");
- int size = 0;
- int start = 0;
- int endOffset = 0; // Store this as the last loca
- if (entry != null) {
- pad4();
- start = currentPos;
-
- for (Enumeration e = glyphs.keys(); e.hasMoreElements(); ) {
- int glyphLength = 0;
- Integer origIndex = (Integer)e.nextElement();
- Integer subsetIndex = (Integer)glyphs.get(origIndex);
-
- int nextOffset = 0;
- if (origIndex.intValue() >= (mtx_tab.length - 1))
- nextOffset = (int)lastLoca;
- else
- nextOffset =
- (int)mtx_tab[origIndex.intValue() + 1].offset;
-
- glyphLength = nextOffset
- - (int)mtx_tab[origIndex.intValue()].offset;
-
- // Copy glyph
- System.arraycopy(in.getBytes((int)entry.offset + (int)mtx_tab[origIndex.intValue()].offset, glyphLength),
- 0, output, currentPos, glyphLength);
-
-
- // Update loca table
- writeULong(locaOffset + subsetIndex.intValue() * 4,
- currentPos - start);
- if ((currentPos - start + glyphLength) > endOffset)
- endOffset = (currentPos - start + glyphLength);
-
- currentPos += glyphLength;
- realSize += glyphLength;
-
- }
-
- size = currentPos - start;
-
- int checksum = getCheckSum(start, size);
- writeULong(glyfDirOffset, checksum);
- writeULong(glyfDirOffset + 4, start);
- writeULong(glyfDirOffset + 8, size);
- currentPos += 12;
- realSize += 12;
-
- // Update loca checksum and last loca index
- writeULong(locaOffset + glyphs.size() * 4, endOffset);
-
- checksum = getCheckSum(locaOffset, glyphs.size() * 4 + 4);
- writeULong(locaDirOffset, checksum);
- } else {
- throw new IOException("Can't find glyf table");
- }
- }
-
-
- /**
- * Create the hmtx table by copying metrics from original
- * font to subset font. The glyphs hashtable contains an
- * Integer key and Integer value that maps the original
- * metric (key) to the subset metric (value)
- */
- private void createHmtx(FontFileReader in,
- Hashtable glyphs) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hmtx");
-
- int longHorMetricSize = glyphs.size() * 2;
- int leftSideBearingSize = glyphs.size() * 2;
- int hmtxSize = longHorMetricSize + leftSideBearingSize;
-
- if (entry != null) {
- pad4();
- int offset = (int)entry.offset;
- for (Enumeration e = glyphs.keys(); e.hasMoreElements(); ) {
- Integer origIndex = (Integer)e.nextElement();
- Integer subsetIndex = (Integer)glyphs.get(origIndex);
-
- writeUShort(currentPos + subsetIndex.intValue() * 4,
- mtx_tab[origIndex.intValue()].wx);
- writeUShort(currentPos + subsetIndex.intValue() * 4 + 2,
- mtx_tab[origIndex.intValue()].lsb);
- }
-
- int checksum = getCheckSum(currentPos, hmtxSize);
- writeULong(hmtxDirOffset, checksum);
- writeULong(hmtxDirOffset + 4, currentPos);
- writeULong(hmtxDirOffset + 8, hmtxSize);
- currentPos += hmtxSize;
- realSize += hmtxSize;
- } else {
- throw new IOException("Can't find hmtx table");
- }
- }
-
- /**
- * Returns a Vector containing the glyph itself plus all glyphs
- * that this composite glyph uses
- */
- private Vector getIncludedGlyphs(FontFileReader in, int glyphOffset,
- Integer glyphIdx) throws IOException {
- Vector ret = new Vector();
- ret.addElement(glyphIdx);
- int offset = glyphOffset + (int)mtx_tab[glyphIdx.intValue()].offset
- + 10;
- Integer compositeIdx = null;
- int flags = 0;
- boolean moreComposites = true;
- while (moreComposites) {
- flags = in.readTTFUShort(offset);
- compositeIdx = new Integer(in.readTTFUShort(offset + 2));
- ret.addElement(compositeIdx);
-
- offset += 4;
- if ((flags & 1) > 0) {
- // ARG_1_AND_ARG_2_ARE_WORDS
- offset += 4;
- } else {
- offset += 2;
- }
-
- if ((flags & 8) > 0)
- offset += 2; // WE_HAVE_A_SCALE
- else if ((flags & 64) > 0)
- offset += 4; // WE_HAVE_AN_X_AND_Y_SCALE
- else if ((flags & 128) > 0)
- offset += 8; // WE_HAVE_A_TWO_BY_TWO
-
- if ((flags & 32) > 0)
- moreComposites = true;
- else
- moreComposites = false;
- }
-
- return ret;
- }
-
-
- /**
- * Rewrite all compositepointers in glyphindex glyphIdx
- *
- */
- private void remapComposite(FontFileReader in, Hashtable glyphs,
- int glyphOffset,
- Integer glyphIdx) throws IOException {
- int offset = glyphOffset + (int)mtx_tab[glyphIdx.intValue()].offset
- + 10;
-
- Integer compositeIdx = null;
- int flags = 0;
- boolean moreComposites = true;
-
- while (moreComposites) {
- flags = in.readTTFUShort(offset);
- compositeIdx = new Integer(in.readTTFUShort(offset + 2));
- Integer newIdx = (Integer)glyphs.get(compositeIdx);
- if (newIdx == null) {
- // This errormessage would look much better
- // if the fontname was printed to
- MessageHandler.error("An embedded font "
- + "contains bad glyph data. "
- + "Characters might not display "
- + "correctly.");
- moreComposites = false;
- continue;
- }
-
- in.writeTTFUShort(offset + 2, newIdx.intValue());
-
- offset += 4;
-
- if ((flags & 1) > 0) {
- // ARG_1_AND_ARG_2_ARE_WORDS
- offset += 4;
- } else {
- offset += 2;
- }
-
- if ((flags & 8) > 0) {
- offset += 2; // WE_HAVE_A_SCALE
- } else if ((flags & 64) > 0) {
- offset += 4; // WE_HAVE_AN_X_AND_Y_SCALE
- } else if ((flags & 128) > 0) {
- offset += 8; // WE_HAVE_A_TWO_BY_TWO
- }
-
- if ((flags & 32) > 0)
- moreComposites = true;
- else
- moreComposites = false;
- }
- }
-
-
- /**
- * Scan all the original glyphs for composite glyphs and add those glyphs
- * to the glyphmapping also rewrite the composite glyph pointers to the new
- * mapping
- */
- private void scanGlyphs(FontFileReader in,
- Hashtable glyphs) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf");
- Hashtable newComposites = null;
- Hashtable allComposites = new Hashtable();
-
- int newIndex = glyphs.size();
-
- if (entry != null) {
- while (newComposites == null || newComposites.size() > 0) {
- // Inefficient to iterate through all glyphs
- newComposites = new Hashtable();
-
- for (Enumeration e = glyphs.keys(); e.hasMoreElements(); ) {
- Integer origIndex = (Integer)e.nextElement();
-
- if (in.readTTFShort(entry.offset
- + mtx_tab[origIndex.intValue()].offset) < 0) {
- // origIndex is a composite glyph
- allComposites.put(origIndex, glyphs.get(origIndex));
- Vector composites =
- getIncludedGlyphs(in, (int)entry.offset,
- origIndex);
-
- // Iterate through all composites pointed to
- // by this composite and check if they exists
- // in the glyphs map, add them if not.
- for (Enumeration cps = composites.elements();
- cps.hasMoreElements(); ) {
-
- Integer cIdx = (Integer)cps.nextElement();
- if (glyphs.get(cIdx) == null
- && newComposites.get(cIdx) == null) {
- newComposites.put(cIdx,
- new Integer(newIndex));
- newIndex++;
- }
- }
- }
- }
-
- // Add composites to glyphs
- for (Enumeration m = newComposites.keys();
- m.hasMoreElements(); ) {
- Integer im = (Integer)m.nextElement();
- glyphs.put(im, newComposites.get(im));
- }
- }
-
- // Iterate through all composites to remap their composite index
-
- for (Enumeration ce = allComposites.keys();
- ce.hasMoreElements(); ) {
- remapComposite(in, glyphs, (int)entry.offset,
- (Integer)ce.nextElement());
- }
-
- } else {
- throw new IOException("Can't find glyf table");
- }
- }
-
-
-
- /**
- * glyphs has old index as (Integer) key and new index
- * as (Integer) value
- */
-
- public byte[] readFont(FontFileReader in, String name,
- Hashtable glyphs) throws IOException {
-
- /*
- * Check if TrueType collection, and that the name
- * exists in the collection
- */
- if (!checkTTC(in, name, false))
- throw new IOException("Failed to read font");
-
- output = new byte[in.getFileSize()];
-
- readDirTabs(in);
- readFontHeader(in);
- getNumGlyphs(in);
- readHorizontalHeader(in);
- readHorizontalMetrics(in);
- readIndexToLocation(in);
-
- scanGlyphs(in, glyphs);
-
- createDirectory(); // Create the TrueType header and directory
-
- createHead(in);
- createHhea(in, glyphs.size()); // Create the hhea table
- createHmtx(in, glyphs); // Create hmtx table
- createMaxp(in, glyphs.size()); // copy the maxp table
-
- try {
- createCvt(in); // copy the cvt table
- } catch (IOException ex) {
- // Cvt is optional (only required for OpenType (MS) fonts)
- MessageHandler.errorln("TrueType warning: " + ex.getMessage());
- }
-
- try {
- createFpgm(in); // copy fpgm table
- } catch (IOException ex) {
- // Fpgm is optional (only required for OpenType (MS) fonts)
- MessageHandler.errorln("TrueType warning: " + ex.getMessage());
- }
-
- try {
- createPrep(in); // copy prep table
- } catch (IOException ex) {
- // Prep is optional (only required for OpenType (MS) fonts)
- MessageHandler.errorln("TrueType warning: " + ex.getMessage());
- }
-
- try {
- createLoca(glyphs.size()); // create empty loca table
- } catch (IOException ex) {
- // Loca is optional (only required for OpenType (MS) fonts)
- MessageHandler.errorln("TrueType warning: " + ex.getMessage());
- }
-
- try {
- createGlyf(in, glyphs);
- } catch (IOException ex) {
- // Glyf is optional (only required for OpenType (MS) fonts)
- MessageHandler.errorln("TrueType warning: " + ex.getMessage());
- }
-
- pad4();
- createCheckSumAdjustment();
-
- byte[] ret = new byte[realSize];
- System.arraycopy(output, 0, ret, 0, realSize);
-
- return ret;
- }
-
- /**
- * writes a ISO-8859-1 string at the currentPosition
- * updates currentPosition but not realSize
- * @return number of bytes written
- */
- private int writeString(String str) {
- int length = 0;
- try {
- byte[] buf = str.getBytes("ISO-8859-1");
- System.arraycopy(buf, 0, output, currentPos, buf.length);
- length = buf.length;
- currentPos += length;
- } catch (Exception e) {
- // This should never happen!
- }
-
- return length;
- }
-
- /**
- * Appends a byte to the output array,
- * updates currentPost but not realSize
- */
- private void writeByte(byte b) {
- output[currentPos++] = b;
- }
-
- /**
- * Appends a USHORT to the output array,
- * updates currentPost but not realSize
- */
- private void writeUShort(int s) {
- byte b1 = (byte)((s >> 8) & 0xff);
- byte b2 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- }
-
- /**
- * Appends a USHORT to the output array,
- * at the given position without changing currentPos
- */
- private void writeUShort(int pos, int s) {
- byte b1 = (byte)((s >> 8) & 0xff);
- byte b2 = (byte)(s & 0xff);
- output[pos] = b1;
- output[pos + 1] = b2;
- }
-
- /**
- * Appends a ULONG to the output array,
- * updates currentPos but not realSize
- */
- private void writeULong(int s) {
- byte b1 = (byte)((s >> 24) & 0xff);
- byte b2 = (byte)((s >> 16) & 0xff);
- byte b3 = (byte)((s >> 8) & 0xff);
- byte b4 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- writeByte(b3);
- writeByte(b4);
- }
-
- /**
- * Appends a ULONG to the output array,
- * at the given position without changing currentPos
- */
- private void writeULong(int pos, int s) {
- byte b1 = (byte)((s >> 24) & 0xff);
- byte b2 = (byte)((s >> 16) & 0xff);
- byte b3 = (byte)((s >> 8) & 0xff);
- byte b4 = (byte)(s & 0xff);
- output[pos] = b1;
- output[pos + 1] = b2;
- output[pos + 2] = b3;
- output[pos + 3] = b4;
- }
-
- /**
- * Read a signed short value at given position
- */
- private short readShort(int pos) {
- int ret = readUShort(pos);
- return (short)ret;
- }
-
- /**
- * Read a unsigned short value at given position
- */
- private int readUShort(int pos) {
- int ret = (int)output[pos];
- if (ret < 0)
- ret += 256;
- ret = ret << 8;
- if ((int)output[pos + 1] < 0) {
- ret |= (int)output[pos + 1] + 256;
- } else
- ret |= (int)output[pos + 1];
-
- return ret;
- }
-
- /**
- * Create a padding in the fontfile to align
- * on a 4-byte boundary
- */
- private void pad4() {
- int padSize = currentPos % 4;
- for (int i = 0; i < padSize; i++) {
- output[currentPos++] = 0;
- realSize++;
- }
- }
-
- /**
- * Returns the maximum power of 2 <= max
- */
- private int maxPow2(int max) {
- int i = 0;
- while (Math.pow(2, (double)i) < max)
- i++;
-
- return (i - 1);
- }
-
- private int log2(int num) {
- return (int)(Math.log((double)num) / Math.log(2));
- }
-
-
- private int getCheckSum(int start, int size) {
- return (int)getLongCheckSum(start, size);
- }
-
- private long getLongCheckSum(int start, int size) {
- // All the tables here are aligned on four byte boundaries
- // Add remainder to size if it's not a multiple of 4
- int remainder = size % 4;
- if (remainder != 0)
- size += remainder;
-
- long sum = 0;
-
- for (int i = 0; i < size; i += 4) {
- int l = (int)(output[start + i] << 24);
- l += (int)(output[start + i + 1] << 16);
- l += (int)(output[start + i + 2] << 16);
- l += (int)(output[start + i + 3] << 16);
- sum += l;
- if (sum > 0xffffffff)
- sum = sum - 0xffffffff;
- }
-
- return sum;
- }
-
- private void createCheckSumAdjustment() {
- long sum = getLongCheckSum(0, realSize);
- int checksum = (int)(0xb1b0afba - sum);
- writeULong(checkSumAdjustmentOffset, checksum);
- }
-
-}
-
-
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- xslt stylesheets belonging to the pfmreader -->
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-<xsl:output method="xml"/>
-
-<xsl:template match="@*|node()">
- <xsl:copy>
- <xsl:apply-templates select="@*|node()"/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="widths">
- <xsl:element name="widths">
- <xsl:for-each select="char">
- <xsl:variable name="char-num" select="@ansichar"/>
- <xsl:variable name="char-name" select="document('file:charlist.xml')/font-mappings/map[@win-ansi=$char-num]/@adobe-name"/>
- <xsl:if test="$char-name!=''">
- <xsl:element name="char">
- <xsl:attribute name="name"><xsl:value-of select="$char-name"/></xsl:attribute>
- <xsl:attribute name="width"><xsl:value-of select="@width"/></xsl:attribute>
- </xsl:element>
- </xsl:if>
- </xsl:for-each>
- </xsl:element>
-</xsl:template>
-
-</xsl:stylesheet>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-<xsl:output method="xml"/>
-
-<xsl:template match="@*|node()">
- <xsl:copy>
- <xsl:apply-templates select="@*|node()"/>
- </xsl:copy>
-</xsl:template>
-
-<xsl:template match="widths">
- <xsl:copy>
- <xsl:apply-templates select="char">
- <xsl:sort select="@name" case-order="upper-first"/>
- </xsl:apply-templates>
- </xsl:copy>
-</xsl:template>
-
-
-</xsl:stylesheet>
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
-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 PFM files from Adobe Type 1 fonts and creates
- * XML font metrics file for use in FOP.
- *
- * @author jeremias.maerki@outline.ch
- */
-public class PFMReader {
- private boolean invokedStandalone = false;
-
- 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("-")) {
- if ((i + 1) < args.length &&!args[i + 1].startsWith("-")) {
- options.put(args[i], args[i + 1]);
- i++;
- } else {
- options.put(args[i], "");
- }
- } 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 .ttf file, but\n"
- + " you can override that name to make sure that the\n");
- System.out.println(" embedded font is used (if you're embedding fonts)\n");
- System.out.println(" instead of installed fonts when viewing documents with Acrobat Reader.\n");
- }
-
-
- /**
- * The main method for the PFM reader tool.
- *
- * @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) {
- 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);
-
- app.writeFontXML(doc, arguments[1]);
- }
- }
- }
-
-
- /**
- * Read a PFM file and returns it as an object.
- *
- * @param filename The filename of the PFM file.
- * @return The PFM as an object.
- */
- public PFMFile loadPFM(String filename) {
- try {
- System.out.println("Reading " + filename + "...");
- System.out.println();
- FileInputStream in = new FileInputStream(filename);
- PFMFile pfm = new PFMFile();
- pfm.load(in);
- return pfm;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * Displays a preview of the PFM file on the console.
- *
- * @param pfm The PFM file to preview.
- */
- public void preview(PFMFile pfm) {
- PrintStream out = System.out;
-
- out.print("Font: ");
- out.println(pfm.getWindowsName());
- out.print("Name: ");
- out.println(pfm.getPostscriptName());
- out.print("CharSet: ");
- out.println(pfm.getCharSetName());
- out.print("CapHeight: ");
- out.println(pfm.getCapHeight());
- out.print("XHeight: ");
- out.println(pfm.getXHeight());
- out.print("LowerCaseAscent: ");
- out.println(pfm.getLowerCaseAscent());
- out.print("LowerCaseDescent: ");
- out.println(pfm.getLowerCaseDescent());
- out.print("Having widths for ");
- out.print(pfm.getLastChar() - pfm.getFirstChar());
- out.print(" characters (");
- out.print(pfm.getFirstChar());
- out.print("-");
- out.print(pfm.getLastChar());
- out.println(").");
- out.print("for example: Char ");
- out.print(pfm.getFirstChar());
- out.print(" has a width of ");
- out.println(pfm.getCharWidth(pfm.getFirstChar()));
- out.println();
- }
-
- /**
- * 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(PFMFile pfm,
- 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);
- root.setAttribute("type", "TYPE1");
-
- Element el = doc.createElement("font-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(pfm.getPostscriptName()));
-
- String s = pfm.getPostscriptName();
- 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("embed");
- root.appendChild(el);
- if (file != null)
- el.setAttribute("file", file);
- if (resource != null)
- el.setAttribute("class", resource);
-
- el = doc.createElement("encoding");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(pfm.getCharSetName() + "Encoding"));
-
- el = doc.createElement("cap-height");
- root.appendChild(el);
- Integer value = new Integer(pfm.getCapHeight());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("x-height");
- root.appendChild(el);
- value = new Integer(pfm.getXHeight());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("ascender");
- root.appendChild(el);
- value = new Integer(pfm.getLowerCaseAscent());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("descender");
- root.appendChild(el);
- value = new Integer(-pfm.getLowerCaseDescent());
- el.appendChild(doc.createTextNode(value.toString()));
-
- Element bbox = doc.createElement("bbox");
- root.appendChild(bbox);
- int[] bb = pfm.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(pfm.getFlags());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("stemv");
- root.appendChild(el);
- value = new Integer(pfm.getStemV());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("italicangle");
- root.appendChild(el);
- value = new Integer(pfm.getItalicAngle());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("first-char");
- root.appendChild(el);
- value = new Integer(pfm.getFirstChar());
- el.appendChild(doc.createTextNode(value.toString()));
-
- el = doc.createElement("last-char");
- root.appendChild(el);
- value = new Integer(pfm.getLastChar());
- el.appendChild(doc.createTextNode(value.toString()));
-
- Element widths = doc.createElement("widths");
- root.appendChild(widths);
-
- for (short i = pfm.getFirstChar(); i <= pfm.getLastChar(); i++) {
- el = doc.createElement("char");
- widths.appendChild(el);
- el.setAttribute("idx", Integer.toString(i));
- el.setAttribute("wdt",
- new Integer(pfm.getCharWidth(i)).toString());
- }
-
-
- // Get kerning
- for (Enumeration enum = pfm.getKerning().keys();
- enum.hasMoreElements(); ) {
- Integer kpx1 = (Integer)enum.nextElement();
- el = doc.createElement("kerning");
- el.setAttribute("kpx1", kpx1.toString());
- root.appendChild(el);
- Element el2 = null;
-
- Hashtable h2 = (Hashtable)pfm.getKerning().get(kpx1);
- for (Enumeration enum2 = h2.keys(); enum2.hasMoreElements(); ) {
- Integer kpx2 = (Integer)enum2.nextElement();
- el2 = doc.createElement("pair");
- el2.setAttribute("kpx2", kpx2.toString());
- Integer val = (Integer)h2.get(kpx2);
- el2.setAttribute("kern", val.toString());
- el.appendChild(el2);
- }
- }
- return doc;
- }
-
-
- 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();
- }
-
-}
-
-
-
-
+++ /dev/null
-/*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-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 {
-
- 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("-")) {
- if ((i + 1) < args.length &&!args[i + 1].startsWith("-")) {
- options.put(args[i], args[i + 1]);
- i++;
- } else {
- options.put(args[i], "");
- }
- } 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("-enc ansi");
- System.out.println(" With this option you create a WinAnsi encoded font.\n");
- System.out.println(" The default is to create a CID keyed font.");
- System.out.println(" If you're not going to use characters outside the");
- System.out.println(" pdfencoding range (almost the same as iso-8889-1)");
- System.out.println(" you can add this option.");
- System.out.println("-ttcname <fontname>");
- System.out.println(" If you're reading data from a TrueType Collection");
- System.out.println(" (.ttc file) you must specify which font from the");
- System.out.println(" collection you will read metrics from. If you read");
- System.out.println(" from a .ttc file without this option, the fontnames");
- System.out.println(" will be listed for you.");
- System.out.println(" -fn <fontname>\n");
- System.out.println(" default is to use the fontname in the .ttf file, but\n"
- + " you can override that name to make sure that the\n");
- System.out.println(" embedded font is used (if you're embedding fonts)\n");
- System.out.println(" instead of installed fonts when viewing documents with Acrobat Reader.\n");
- }
-
-
- /**
- * The main method for the TTFReader 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;
- String ttcName = null;
- boolean isCid = true;
-
- Hashtable options = new Hashtable();
- String[] arguments = parseArguments(options, args);
-
- TTFReader app = new TTFReader();
- app.invokedStandalone = true;
-
- System.out.println("TTF Reader v1.1.1");
- System.out.println();
-
- if (options.get("-enc") != null) {
- String enc = (String)options.get("-enc");
- if ("ansi".equals(enc))
- isCid = false;
- }
-
- if (options.get("-ttcname") != null)
- ttcName = (String)options.get("-ttcname");
-
- 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], ttcName);
- if (ttf != null) {
- org.w3c.dom.Document doc = app.constructFontXML(ttf,
- fontName, className, embResource, embFile, isCid,
- ttcName);
-
- if (isCid)
- System.out.println("Creating CID encoded metrics");
- else
- System.out.println("Creating WinAnsi encoded metrics");
-
- if (doc != null) {
- app.writeFontXML(doc, arguments[1]);
- }
-
- if (ttf.isEmbeddable())
- System.out.println("This font contains no embedding license restrictions");
- else
- System.out.println("** Note: This font contains license retrictions for\n"
- + " embedding. This font shouldn't be embedded.");
-
- }
- }
- }
-
- /**
- * Read a TTF file and returns it as an object.
- *
- * @param filename The filename of the PFM file.
- * @return The TTF as an object.
- */
- public TTFFile loadTTF(String fileName, String fontName) {
- TTFFile ttfFile = new TTFFile();
- try {
- System.out.println("Reading " + fileName + "...");
- System.out.println();
-
- FontFileReader reader = new FontFileReader(fileName);
- ttfFile.readFont(reader, fontName);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- return ttfFile;
- }
-
-
- /**
- * 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 TTF/TTC file.
- *
- * @param ttf 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,
- boolean isCid, String ttcName) {
- System.out.println("Creating xml font file...");
- System.out.println();
-
- Document doc = new DocumentImpl();
- Element root = doc.createElement("font-metrics");
- doc.appendChild(root);
- if (isCid)
- root.setAttribute("type", "TYPE0");
- else
- root.setAttribute("type", "TRUETYPE");
-
- 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 = stripWhiteSpace(ttf.getPostscriptName());
-
- if (fontName != null)
- el.appendChild(doc.createTextNode(stripWhiteSpace(fontName)));
- else
- el.appendChild(doc.createTextNode(s));
-
- el = doc.createElement("embed");
- root.appendChild(el);
- if (file != null && ttf.isEmbeddable())
- el.setAttribute("file", file);
- if (resource != null && ttf.isEmbeddable())
- el.setAttribute("class", resource);
-
- el = doc.createElement("cap-height");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getCapHeight())));
-
- el = doc.createElement("x-height");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getXHeight())));
-
- el = doc.createElement("ascender");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseAscent())));
-
- el = doc.createElement("descender");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLowerCaseDescent())));
-
- 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);
- el.appendChild(doc.createTextNode(String.valueOf(bb[i])));
- }
-
- el = doc.createElement("flags");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getFlags())));
-
- el = doc.createElement("stemv");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getStemV()));
-
- el = doc.createElement("italicangle");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getItalicAngle()));
-
- if (ttcName != null) {
- el = doc.createElement("ttc-name");
- root.appendChild(el);
- el.appendChild(doc.createTextNode(ttcName));
- }
-
- el = doc.createElement("subtype");
- root.appendChild(el);
-
- // Fill in extras for CID keyed fonts
- if (isCid) {
- el.appendChild(doc.createTextNode("TYPE0"));
-
- Element mel = doc.createElement("multibyte-extras");
- root.appendChild(mel);
-
- el = doc.createElement("cid-type");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("CIDFontType2"));
-
- el = doc.createElement("default-width");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("0"));
-
- el = doc.createElement("bfranges");
- mel.appendChild(el);
- for (Enumeration e = ttf.getCMaps().elements();
- e.hasMoreElements(); ) {
- TTFCmapEntry ce = (TTFCmapEntry)e.nextElement();
- Element el2 = doc.createElement("bf");
- el.appendChild(el2);
- el2.setAttribute("us", String.valueOf(ce.unicodeStart));
- el2.setAttribute("ue", String.valueOf(ce.unicodeEnd));
- el2.setAttribute("gi", String.valueOf(ce.glyphStartIndex));
- }
-
- el = doc.createElement("cid-widths");
- el.setAttribute("start-index", "0");
- mel.appendChild(el);
-
- int[] wx = ttf.getWidths();
- for (int i = 0; i < wx.length; i++) {
- Element wxel = doc.createElement("wx");
- wxel.setAttribute("w", String.valueOf(wx[i]));
- el.appendChild(wxel);
- }
- } else {
- // Fill in extras for singlebyte fonts
- el.appendChild(doc.createTextNode("TRUETYPE"));
-
- Element sel = doc.createElement("singlebyte-extras");
- root.appendChild(sel);
-
- el = doc.createElement("encoding");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getCharSetName()));
-
- el = doc.createElement("first-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getFirstChar())));
-
- el = doc.createElement("last-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLastChar())));
-
- Element widths = doc.createElement("widths");
- sel.appendChild(widths);
-
- for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); i++) {
- el = doc.createElement("char");
- widths.appendChild(el);
- el.setAttribute("idx", String.valueOf(i));
- el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i)));
- }
- }
-
- // Get kerning
- Enumeration enum;
- if (isCid)
- enum = ttf.getKerning().keys();
- else
- enum = ttf.getAnsiKerning().keys();
-
- while (enum.hasMoreElements()) {
- Integer kpx1 = (Integer)enum.nextElement();
-
- el = doc.createElement("kerning");
- el.setAttribute("kpx1", kpx1.toString());
- root.appendChild(el);
- Element el2 = null;
-
- Hashtable h2;
- if (isCid)
- h2 = (Hashtable)ttf.getKerning().get(kpx1);
- else
- h2 = (Hashtable)ttf.getAnsiKerning().get(kpx1);
-
- for (Enumeration enum2 = h2.keys(); enum2.hasMoreElements(); ) {
- Integer kpx2 = (Integer)enum2.nextElement();
- if (isCid || kpx2.intValue() < 256) {
- el2 = doc.createElement("pair");
- el2.setAttribute("kpx2", kpx2.toString());
- Integer val = (Integer)h2.get(kpx2);
- el2.setAttribute("kern", val.toString());
- el.appendChild(el2);
- }
- }
- }
-
- return doc;
- }
-
-
- private String stripWhiteSpace(String s) {
- char[] ch = new char[s.length()];
- s.getChars(0, s.length(), ch, 0);
- StringBuffer stb = new StringBuffer();
- for (int i = 0; i < ch.length; i++)
- if (ch[i] != ' ' && ch[i] != '\r' && ch[i] != '\n'
- && ch[i] != '\t')
- stb.append(ch[i]);
-
- return stb.toString();
- }
-
- 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();
- }
-
-}
-