diff options
author | fotis <fotis@unknown> | 2001-03-22 18:17:02 +0000 |
---|---|---|
committer | fotis <fotis@unknown> | 2001-03-22 18:17:02 +0000 |
commit | 7f41a1391a0554393795b4bf4ca7bcbf79bc8645 (patch) | |
tree | fa70dd99b1ade894f025ea3ebb969bda138da814 /src/org/apache/fop/fonts | |
parent | 75cbd9c88de7a315de189c4c98b7c3992b23bc40 (diff) | |
download | xmlgraphics-fop-7f41a1391a0554393795b4bf4ca7bcbf79bc8645.tar.gz xmlgraphics-fop-7f41a1391a0554393795b4bf4ca7bcbf79bc8645.zip |
subset fonts embedding (submitted by Tore Engvig)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194168 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache/fop/fonts')
-rw-r--r-- | src/org/apache/fop/fonts/FontFileReader.java | 432 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/PFMFile.java | 417 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/TTFCmapEntry.java | 66 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/TTFDirTabEntry.java | 94 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/TTFFile.java | 1312 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/TTFMtxEntry.java | 75 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/TTFSegEntry.java | 66 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/apps/FontPostProcess.xsl | 2 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/apps/PFMReader.java | 358 | ||||
-rw-r--r-- | src/org/apache/fop/fonts/apps/TTFReader.java | 563 |
10 files changed, 1550 insertions, 1835 deletions
diff --git a/src/org/apache/fop/fonts/FontFileReader.java b/src/org/apache/fop/fonts/FontFileReader.java index f6bc3cff9..e6c7ce859 100644 --- a/src/org/apache/fop/fonts/FontFileReader.java +++ b/src/org/apache/fop/fonts/FontFileReader.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -58,170 +14,220 @@ import java.io.IOException; 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 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 */ - private void init(InputStream stream, int start, int inc) - throws java.io.IOException { - fsize=0; - current=0; - - file=new byte[start]; - - int l=stream.read(file, 0, start); - fsize+=l; - - if (l==start) { - // More to read - needs to extend - byte[] tmpbuf; - - while (l>0) { - tmpbuf=new byte[file.length + inc]; - System.arraycopy(file, 0, tmpbuf, 0, file.length); - l=stream.read(tmpbuf, file.length, inc); - fsize+=l; - file=tmpbuf; - - if (l<inc) // whole file read. No need to loop again - l=0; - } - } - } - - /** - * Constructor - * @param fileName filename to read - */ - public FontFileReader(String fileName) - throws java.io.IOException { - - // Get estimates for file size and increment - File f=new File(fileName); - FileInputStream ins = new FileInputStream(fileName); - init(ins, (int)(f.length()+1), (int)(f.length()/10)); - ins.close(); - } - - - /** Set current file position to offset */ - public void seek_set(long offset) throws IOException { - if (offset > fsize || offset < 0) - throw new java.io.EOFException("Reached EOF, file size="+fsize+ - " offset="+offset); - current=(int)offset; - } - - /** Set current file position to offset */ - public void seek_add(long add) throws IOException { - seek_set(current+add); - } - - public void skip(long add) throws IOException { - seek_add(add); - } - - /** return current file position */ - public int getCurrentPos() { - return current; - } - - public int getFileSize() { - return fsize; - } - - - /** Read 1 byte, throws EOFException on end of file */ - public byte read() throws IOException { - if (current>fsize) - throw new java.io.EOFException("Reached EOF, file size="+fsize); - - byte ret=file[current++]; - return ret; - } - - - - /** Read 1 signed byte from InputStream */ - public final byte readTTFByte() throws IOException { - return read(); - } - - /** Read 1 unsigned byte from InputStream */ - public final int readTTFUByte() throws IOException { - byte buf=read(); - - if (buf < 0) - return (int)(256+buf); - else - return (int)buf; - } - - /** Read 2 bytes signed from InputStream */ - public final short readTTFShort() throws IOException { - int ret=(readTTFUByte() << 8) + - readTTFUByte(); - short sret=(short)ret; - - return sret; - } - - /** Read 2 bytes unsigned from InputStream */ - public final int readTTFUShort() throws IOException { - int ret=(readTTFUByte() << 8) + - readTTFUByte(); - - return (int)ret; - } - - /** Read 4 bytes from InputStream */ - public final int readTTFLong() throws IOException { - long ret=readTTFUByte();// << 8; - ret=(ret << 8) + readTTFUByte(); - ret=(ret << 8) + readTTFUByte(); - ret=(ret << 8) + readTTFUByte(); - - return (int)ret; - } - - /** Read 4 bytes from InputStream */ - public final long readTTFULong() throws IOException { - long ret=readTTFUByte(); - ret=(ret << 8) + readTTFUByte(); - ret=(ret << 8) + readTTFUByte(); - ret=(ret << 8) + readTTFUByte(); - - return ret; - } - - /** Read a 0 terminatet ISO-8859-1 string */ - public final String readTTFString() throws IOException { - int i=current; - while (file[i++]!=0) { - if (i > fsize) - throw new java.io.EOFException("Reached EOF, file size="+fsize); - } - - byte[] tmp=new byte[i-current]; - System.arraycopy(file, current, tmp, 0, i-current); - return new String(tmp, "ISO-8859-1"); - } - - - /** Read an ISO-8859-1 string of len bytes*/ - public final String readTTFString(int len) throws IOException { - if ((len+current) > fsize) - throw new java.io.EOFException("Reached EOF, file size="+fsize); - - byte[] tmp=new byte[len]; - System.arraycopy(file, current, tmp, 0, len); - current+=len; - return new String(tmp, "ISO-8859-1"); - } + 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; + } + + } diff --git a/src/org/apache/fop/fonts/PFMFile.java b/src/org/apache/fop/fonts/PFMFile.java index f1cae42d3..83c265437 100644 --- a/src/org/apache/fop/fonts/PFMFile.java +++ b/src/org/apache/fop/fonts/PFMFile.java @@ -1,52 +1,8 @@ /*-- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -61,40 +17,40 @@ import java.util.Hashtable; 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; + 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; + private int etmCapHeight; + private int etmXHeight; + private int etmLowerCaseAscent; + private int etmLowerCaseDescent; //Extent table - private int[] extentTable; + private int[] extentTable; - private Hashtable kerningTab; + private Hashtable kerningTab; public PFMFile() { - kerningTab=new Hashtable(); + kerningTab = new Hashtable(); } /** - * Parses a PFM file - * - * @param inStream The stream from which to read the PFM file. - */ + * 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); @@ -103,8 +59,8 @@ public class PFMFile { long filesize = in.readInt(); bufin.reset(); - byte[] buf = new byte[(int)filesize]; - bufin.read(buf, 0, (int)filesize); + byte[] buf = new byte[(int) filesize]; + bufin.read(buf, 0, (int) filesize); bufin = new ByteArrayInputStream(buf); in = new PFMInputStream(bufin); @@ -113,10 +69,10 @@ public class PFMFile { } /** - * Parses the header of the PFM file. - * - * @param inStream The stream from which to read the PFM file. - */ + * 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(); @@ -128,9 +84,9 @@ public class PFMFile { dfAvgWidth = inStream.readShort(); dfMaxWidth = inStream.readShort(); dfFirstChar = inStream.readByte(); - dfLastChar = inStream.readByte(); + dfLastChar = inStream.readByte(); inStream.skip(8); - long faceOffset = inStream.readInt(); + long faceOffset = inStream.readInt(); inStream.reset(); inStream.skip(faceOffset); @@ -141,10 +97,10 @@ public class PFMFile { } /** - * Parses the extension part of the PFM file. - * - * @param inStream The stream from which to read the PFM file. - */ + * 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(); @@ -155,11 +111,11 @@ public class PFMFile { long driverInfoOffset = inStream.readInt(); if (kernPairOffset > 0) { - inStream.reset(); - inStream.skip(kernPairOffset); - loadKernPairs(inStream); + inStream.reset(); + inStream.skip(kernPairOffset); + loadKernPairs(inStream); } - + inStream.reset(); inStream.skip(driverInfoOffset); postscriptName = inStream.readString(); @@ -178,190 +134,195 @@ public class PFMFile { } /** - * Parses the kernPairs part of the pfm file - * - * @param inStream The stream from which to read the PFM file. - */ + * 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); + 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 { + * 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(); + 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]; + * 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]; + 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. - */ + * 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. - */ + * 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). - */ + * 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. - */ + * 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"; + 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. - */ + * 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. - */ + * 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. - */ + * 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. - */ + * 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. - */ + * 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. - */ + * 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. - */ + * 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. - */ + * 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]; @@ -378,44 +339,54 @@ public class PFMFile { } /** - * Returns the characteristics flags for the font as - * needed for a PDF font descriptor (See PDF specs). - * - * @return The characteristics flags. - */ + * 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; } + 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. - */ + * 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); + return (int) Math.round(dfMinWidth * 0.25); } else { - return (int)Math.round(dfMinWidth * 0.6); + 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. - */ + * 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.... @@ -425,12 +396,12 @@ public class PFMFile { } /** - * 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. - */ + * 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]; + return extentTable[which - dfFirstChar]; } } diff --git a/src/org/apache/fop/fonts/TTFCmapEntry.java b/src/org/apache/fop/fonts/TTFCmapEntry.java index 3e8dd746a..b4a9c3bbc 100644 --- a/src/org/apache/fop/fonts/TTFCmapEntry.java +++ b/src/org/apache/fop/fonts/TTFCmapEntry.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -58,16 +14,14 @@ 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) { + TTFCmapEntry (int unicodeStart, int unicodeEnd, int glyphStartIndex) { this.unicodeStart = unicodeStart; this.unicodeEnd = unicodeEnd; this.glyphStartIndex = glyphStartIndex; @@ -75,13 +29,13 @@ public class TTFCmapEntry { public boolean equals (Object o) { if (o instanceof TTFCmapEntry) { - TTFCmapEntry ce = (TTFCmapEntry)o; + TTFCmapEntry ce = (TTFCmapEntry) o; if (ce.unicodeStart == this.unicodeStart && - ce.unicodeEnd == this.unicodeEnd && - ce.glyphStartIndex == this.glyphStartIndex) + ce.unicodeEnd == this.unicodeEnd && + ce.glyphStartIndex == this.glyphStartIndex) return true; } return false; } - + } diff --git a/src/org/apache/fop/fonts/TTFDirTabEntry.java b/src/org/apache/fop/fonts/TTFDirTabEntry.java index 30f0c4cfe..9a2b0ea12 100644 --- a/src/org/apache/fop/fonts/TTFDirTabEntry.java +++ b/src/org/apache/fop/fonts/TTFDirTabEntry.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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.*; @@ -56,32 +12,32 @@ class TTFDirTabEntry { int checksum; long offset; long length; - + TTFDirTabEntry() { tag = new byte[4]; } - - /** Read Dir Tab, return tag name */ + + /** 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(); - + 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)); - */ + + offset = in.readTTFULong(); + length = in.readTTFULong(); + + /* + System.out.println ("Read dir tab [" + tag[0]+ + " "+tag[1] + + " "+tag[2] + + " "+tag[3] + + "] offset: " + offset + + " length: " + length + + " name: " + new String(tag)); + */ return new String(tag, "ISO-8859-1"); } } diff --git a/src/org/apache/fop/fonts/TTFFile.java b/src/org/apache/fop/fonts/TTFFile.java index 02c49bfe1..682233dbc 100644 --- a/src/org/apache/fop/fonts/TTFFile.java +++ b/src/org/apache/fop/fonts/TTFFile.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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.*; @@ -64,33 +20,34 @@ public class TTFFile { 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 + + 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 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=""; - + int[] mtx_encoded = null; + + String fontName = ""; + String fullName = ""; + String notice = ""; + String familyName = ""; + String subFamilyName = ""; + long italicAngle = 0; long isFixedPitch = 0; int fontBBox1 = 0; @@ -108,158 +65,157 @@ public class TTFFile { 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) { + + /** 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); + + 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 - */ + + /** 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); + 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; + 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 { + + /** 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; - + + /** 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; + 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 + + // 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) { + 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(); + 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); + */ - /* - 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(); + 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_startCounts[i] = in.readTTFUShort(); } - - for (int i=0; i < (cmap_segCountX2/2); i++) { - cmap_deltas[i]=in.readTTFShort(); + + 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.readTTFShort(); + + int startRangeOffset = in.getCurrentPos(); + + for (int i = 0; i < (cmap_segCountX2 / 2); i++) { + cmap_rangeOffsets[i] = in.readTTFShort(); } - - int glyphIdArrayOffset=in.getCurrentPos(); - - // Insert the unicode id for the glyphs in mtx_tab - // and fill in the cmaps Vector - + + 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; - + /* + 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) { if (cmap_rangeOffsets[i] != 0) { - int glyphOffset = glyphIdArrayOffset+ - ((cmap_rangeOffsets[i]/2)+ - (j-cmap_startCounts[i])+ - (i)- - cmap_segCountX2/2)*2; + int glyphOffset = glyphIdArrayOffset + + ((cmap_rangeOffsets[i] / 2) + + (j - cmap_startCounts[i]) + (i) - + cmap_segCountX2 / 2) * 2; in.seek_set(glyphOffset); - int glyphIdx=(in.readTTFUShort()+ - cmap_deltas[i]) & 0xffff; + int glyphIdx = (in.readTTFUShort() + + cmap_deltas[i]) & 0xffff; unicodeMapping.addElement( - new UnicodeMapping(glyphIdx, j)); - mtx_tab[glyphIdx].unicodeIndex.addElement(new Integer(j)); + new UnicodeMapping(glyphIdx, j)); + mtx_tab[glyphIdx].unicodeIndex.addElement( + new Integer(j)); - // Also add winAnsiWidth + // Also add winAnsiWidth if (false) { int d = j; if (j > 127) @@ -268,71 +224,89 @@ public class TTFFile { if (d < ansiWidth.length) ansiWidth[d] = mtx_tab[glyphIdx].wx; } else { - Vector v= - (Vector)ansiIndex.get(new Integer(j)); + 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()); - */ + 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 { - int glyphIdx=(j+cmap_deltas[i]) & 0xffff; - - mtx_tab[glyphIdx].unicodeIndex.addElement(new Integer(j)); - + /* + System.out.println("Idx: "+ + glyphIdx + + " Delta: " + cmap_deltas[i]+ + " Unicode: " + j + + " name: " + + mtx_tab[glyphIdx].name); + */ + + } + else { + + int 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)); + 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 + + // 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)); + 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; + 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); - */ + + /* + System.out.println("IIdx: "+ + mtxPtr + + " Delta: " + cmap_deltas[i]+ + " Unicode: " + j + + " name: " + + mtx_tab[(j+cmap_deltas[i]) & 0xffff].name); + */ } mtxPtr++; } @@ -341,16 +315,16 @@ public class TTFFile { } return true; } - - - - /** - * Print first char/last char - */ + + + + /** + * 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++) { + 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) @@ -361,26 +335,26 @@ public class TTFFile { } public void readFont(FontFileReader in) throws IOException { - readFont(in, (String)null); + readFont(in, (String) null); } - /** initialize the ansiWidths array (for winAnsiEncoding) - * and fill with the missingwidth - */ + /** initialize the ansiWidths array (for winAnsiEncoding) + * and fill with the missingwidth + */ private void initAnsiWidths() { - ansiWidth=new int[256]; + 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++) { + // 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); + Integer uni = new Integer((int) Glyphs.winAnsiEncoding[i]); + + Vector v = (Vector) ansiIndex.get(uni); if (v == null) { v = new Vector(); ansiIndex.put(uni, v); @@ -389,23 +363,26 @@ public class TTFFile { } } - - /** - * Read the font data - * If the fontfile is a TrueType Collection (.ttf 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)) + + /** + * 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(); @@ -417,8 +394,8 @@ public class TTFFile { readPCLT(in); readCMAP(in); // Read cmap table and fill in ansiwidths createCMaps(); // Create cmaps for bfentries - //print_max_min(); - + //print_max_min(); + readKerning(in); } @@ -427,26 +404,26 @@ public class TTFFile { TTFCmapEntry tce = new TTFCmapEntry(); Enumeration e = unicodeMapping.elements(); - UnicodeMapping um = (UnicodeMapping)e.nextElement(); + 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)) { + 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); } @@ -457,51 +434,52 @@ public class TTFFile { 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("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.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)+"]"); + System.out.println("FontBBox: [" + + (int) get_ttf_funit(fontBBox1) + " " + + (int) get_ttf_funit(fontBBox2) + " " + + (int) get_ttf_funit(fontBBox3) + " " + + (int) get_ttf_funit(fontBBox4) + "]"); } - + public static void main(String[] args) { try { - TTFFile ttfFile=new TTFFile(); - FontFileReader reader= - new FontFileReader(args[0]); + TTFFile ttfFile = new TTFFile(); + FontFileReader reader = new FontFileReader(args[0]); - String name=null; + String name = null; if (args.length >= 2) - name=args[1]; - + 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); + return new String(familyName + ","+subFamilyName); } - + public String getPostscriptName() { if ("Regular".equals(subFamilyName) || - "Roman".equals(subFamilyName)) + "Roman".equals(subFamilyName)) return familyName; else - return familyName+","+subFamilyName; + return familyName + ","+subFamilyName; } public String getFamilyName() { return familyName; @@ -510,14 +488,14 @@ public class TTFFile { return encoding; } public int getCapHeight() { - return (int)get_ttf_funit(capHeight); + return (int) get_ttf_funit(capHeight); } public int getXHeight() { - return (int)get_ttf_funit(xHeight); + return (int) get_ttf_funit(xHeight); } - + public int getFlags() { - int flags=32; // Use Adobe Standard charset + int flags = 32; // Use Adobe Standard charset if (italicAngle != 0) flags = flags | 64; if (isFixedPitch != 0) @@ -527,39 +505,43 @@ public class TTFFile { return flags; } - + public String getStemV() { return "0"; } - + public String getItalicAngle() { - String ia=Short.toString((short)(italicAngle/0x10000)); - if ((italicAngle % 0x10000) > 0 ) - ia=ia+("."+Short.toString((short)((short)((italicAngle % 0x10000)*1000)/0x10000))); - + 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); - + 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); + return (int) get_ttf_funit(ascender); } - + public int getLowerCaseDescent() { - return (int)get_ttf_funit(descender); + return (int) get_ttf_funit(descender); } - - // This is only for WinAnsiEncoding, so the last char is - // the last char < 256 + + // This is only for WinAnsiEncoding, so the last char is + // the last char < 256 public short getLastChar() { return lastChar; } @@ -571,192 +553,195 @@ public class TTFFile { 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); + wx[i] = (int) get_ttf_funit(mtx_tab[i].wx); return wx; } - + public int getCharWidth(int idx) { - return (int)get_ttf_funit(ansiWidth[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. - */ - private void readDirTabs(FontFileReader in) throws IOException { + + + /** + * 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(); + 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]); + + 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 - */ - private void readFontHeader(FontFileReader in) throws IOException { - seek_tab(in, "head", 2*4 + 2*4 + 2); - upem=in.readTTFUShort(); + /** + * 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(); + + 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 - */ - private void getNumGlyphs(FontFileReader in) throws IOException { + /** + * Read the number of glyphs from the "maxp" table + */ + protected void getNumGlyphs(FontFileReader in) throws IOException { seek_tab(in, "maxp", 4); - nglyphs=in.readTTFUShort(); - System.out.println("Number of glyphs in font: " + nglyphs); + 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 - */ - private void readHorizontalHeader(FontFileReader in) throws IOException { + /** 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); + 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 - */ - private void readHorizontalMetrics(FontFileReader in) throws IOException { + /** + * 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(); - /* - System.out.println(" width["+i+"] = "+ - get_ttf_funit(mtx_tab[i].wx)+";"); - */ - in.skip(2); // Skip left side bearing + + 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; + // 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 { + /** + * 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); + 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]; + //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; + 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; - + //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); + + //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()); + //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++) { + + for (i = 0; i < l; i++) { if (mtx_tab[i].index < NMACGLYPHS) { - mtx_tab[i].name = Glyphs.mac_glyph_names[mtx_tab[i].index]; + 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]; + /* + 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 + // Postscript format 3 contains no glyph names System.out.println("Postscript format 3"); break; default: @@ -766,308 +751,327 @@ public class TTFFile { } - /** - * Read the "OS/2" table - */ + /** + * Read the "OS/2" table + */ private final void readOS2(FontFileReader in) throws IOException { - // Check if font is embeddable + // 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) == fsType) - is_embeddable=false; + seek_tab(in, "OS/2", 2 * 4); + int fsType = in.readTTFUShort(); + if (fsType == 2) + is_embeddable = false; else - is_embeddable=true; + is_embeddable = true; } else - is_embeddable=true; + is_embeddable = true; } - /** - * Read the "loca" table - */ - private final void readIndexToLocation(FontFileReader in) - throws IOException { + /** + * Read the "loca" table + */ + protected final void readIndexToLocation(FontFileReader in) + throws IOException { seek_tab(in, "loca", 0); - for (int i=0; i < nglyphs ; i++) { + 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 - */ + /** + * 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) { + 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(); + 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]; + 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); + + + 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(); + 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]; + 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)); + //System.out.println(mtx_tab[i].toString(this)); } } - /** - * Read the "name" table - */ + /** + * 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; + i += 2 * 2; while (n-- > 0) { - //System.out.println("Iteration: "+n); + //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()); + 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; - } + //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; + i += 6 * 2; } } - /** - * Read the "PCLT" table to find xHeight and capHeight - */ + /** + * 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) { + 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; + 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; + hasSerifs = false; else - hasSerifs=true; - + 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++) { + // 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]; + capHeight = mtx_tab[i].bbox[3] - mtx_tab[i].bbox[1]; } } } - /** - * Read the kerning table, create a table for both CIDs and - * winAnsiEncoding - */ + /** + * 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(); - TTFDirTabEntry dirTab= - (TTFDirTabEntry)dirTabs.get("kern"); - if (dirTab!=null) { + // 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) + 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) + if ((k >> 8) != 0) continue; - - k=in.readTTFUShort(); + + k = in.readTTFUShort(); in.skip(3 * 2); while (k-- > 0) { - int i=in.readTTFUShort(); - int j=in.readTTFUShort(); - int kpx=in.readTTFShort(); + 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(); + // 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))); + new Integer((int) get_ttf_funit(kpx))); kerningTab.put(iObj, adjTab); } } } - //System.out.println(kerningTab.toString()); - - // Create winAnsiEncoded kerning table - - ansiKerningTab = new Hashtable(); + //System.out.println(kerningTab.toString()); + + // Create winAnsiEncoded kerning table + for (Enumeration ae = kerningTab.keys(); - ae.hasMoreElements();) { - Integer cidKey = (Integer)ae.nextElement(); + ae.hasMoreElements();) { + Integer cidKey = (Integer) ae.nextElement(); Hashtable akpx = new Hashtable(); - Hashtable ckpx = (Hashtable)kerningTab.get(cidKey); + 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()); + 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()); + 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 - */ + /** 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 - */ - private final boolean checkTTC(FontFileReader in, String name) - throws IOException { - String tag=in.readTTFString(4); - + /** + * 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 + // 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(); - } - 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; + // 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(); + } - // Iterate through all name tables even if font - // Is found, just to show all the names - for (int i=0; (i < numDirectories); i++) { + 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; - in.seek_set(dirOffsets[i]); - System.out.println("* " + fullName); + found = true; + dirTabOffset = dirOffsets[i]; + if (verbose) + System.out.println("* " + fullName); } else { - System.out.println(fullName); + if (verbose) + System.out.println(fullName); } - - // Reset names - notice=""; - fullName=""; - familyName=""; - fontName=""; - subFamilyName=""; + + // Reset names + notice = ""; + fullName = ""; + familyName = ""; + fontName = ""; + subFamilyName = ""; } + in.seek_set(dirTabOffset); return found; - } else { + } + else { in.seek_set(0); return true; } } - /* Helper classes, they are not very efficient, but that really - doesn't matter... */ + /* 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++) + 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()]; @@ -1078,8 +1082,8 @@ public class TTFFile { /** - * Key-value helper class - */ + * Key-value helper class + */ class UnicodeMapping { int uIdx; int gIdx; diff --git a/src/org/apache/fop/fonts/TTFMtxEntry.java b/src/org/apache/fop/fonts/TTFMtxEntry.java index e1333bd24..56b27e62e 100644 --- a/src/org/apache/fop/fonts/TTFMtxEntry.java +++ b/src/org/apache/fop/fonts/TTFMtxEntry.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -55,26 +11,27 @@ 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; + name = ""; + found = 0; unicodeIndex = new Vector(); - bbox=new int[4]; + 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)); + return new String("Glyph "+name + " index: " + index + " bbox [ "+ + t.get_ttf_funit(bbox[0]) + " " + + t.get_ttf_funit(bbox[1]) + " " + + t.get_ttf_funit(bbox[2]) + " " + + t.get_ttf_funit(bbox[3]) + "]" + "wx: "+ + t.get_ttf_funit(wx)); } } diff --git a/src/org/apache/fop/fonts/TTFSegEntry.java b/src/org/apache/fop/fonts/TTFSegEntry.java index 9c7cbad8c..e63c024bd 100644 --- a/src/org/apache/fop/fonts/TTFSegEntry.java +++ b/src/org/apache/fop/fonts/TTFSegEntry.java @@ -1,61 +1,17 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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() { - } + int endCode; + int startCode; + int idDelta; + int idRangeOffset; + + TTFSegEntry() { + } } diff --git a/src/org/apache/fop/fonts/apps/FontPostProcess.xsl b/src/org/apache/fop/fonts/apps/FontPostProcess.xsl index 5739a07e7..120fd36a3 100644 --- a/src/org/apache/fop/fonts/apps/FontPostProcess.xsl +++ b/src/org/apache/fop/fonts/apps/FontPostProcess.xsl @@ -13,7 +13,7 @@ <xsl:element name="widths"> <xsl:for-each select="char"> <xsl:variable name="char-num" select="@ansichar"/> - <xsl:variable name="char-name" select="document('charlist.xml')/font-mappings/map[@win-ansi=$char-num]/@adobe-name"/> + <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> diff --git a/src/org/apache/fop/fonts/apps/PFMReader.java b/src/org/apache/fop/fonts/apps/PFMReader.java index 581ba20db..cf98ce434 100644 --- a/src/org/apache/fop/fonts/apps/PFMReader.java +++ b/src/org/apache/fop/fonts/apps/PFMReader.java @@ -1,52 +1,8 @@ /*-- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -73,106 +29,104 @@ public class 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. - */ + * 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); - + 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"); - + embFile = (String) options.get("-ef"); + if (options.get("-er") != null) - embResource=(String)options.get("-er"); - + embResource = (String) options.get("-er"); + if (options.get("-fn") != null) - fontName=(String)options.get("-fn"); - + 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) + 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); - + + org.w3c.dom.Document doc = + app.constructFontXML(pfm, fontName, className, + embResource, embFile); + app.writeFontXML(doc, arguments[1]); } } @@ -180,11 +134,11 @@ public class PFMReader { /** - * Read a PFM file and returns it as an object. - * - * @param filename The filename of the PFM file. - * @return The PFM as an object. - */ + * 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 + "..."); @@ -200,10 +154,10 @@ public class PFMReader { } /** - * Displays a preview of the PFM file on the console. - * - * @param pfm The PFM file to preview. - */ + * 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; @@ -222,7 +176,7 @@ public class PFMReader { out.print("LowerCaseDescent: "); out.println(pfm.getLowerCaseDescent()); out.print("Having widths for "); - out.print(pfm.getLastChar()-pfm.getFirstChar()); + out.print(pfm.getLastChar() - pfm.getFirstChar()); out.print(" characters ("); out.print(pfm.getFirstChar()); out.print("-"); @@ -236,20 +190,20 @@ public class PFMReader { } /** - * Writes the generated DOM Document to a file. - * - * @param doc The DOM Document to save. - * @param target The target filename for the XML file. - */ + * 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 + 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.asDOMSerializer(); // As a DOM Serializer serial.serialize(doc.getDocumentElement()); out.close(); @@ -259,14 +213,14 @@ public class PFMReader { } /** - * 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) { + * 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(); @@ -274,7 +228,7 @@ public class PFMReader { 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())); @@ -282,22 +236,22 @@ public class PFMReader { 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); + 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); + 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.appendChild(doc.createTextNode(pfm.getCharSetName() + "Encoding")); el = doc.createElement("cap-height"); root.appendChild(el); @@ -323,7 +277,7 @@ public class PFMReader { root.appendChild(bbox); int[] bb = pfm.getFontBBox(); String[] names = {"left","bottom","right","top"}; - for (int i=0; i<4; i++) { + for (int i = 0; i < 4; i++) { el = doc.createElement(names[i]); bbox.appendChild(el); value = new Integer(bb[i]); @@ -358,48 +312,50 @@ public class PFMReader { Element widths = doc.createElement("widths"); root.appendChild(widths); - for (short i = pfm.getFirstChar(); i < pfm.getLastChar(); i++) { + 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()); + el.setAttribute("wdt", + new Integer(pfm.getCharWidth(i)).toString()); } - // Get kerning - for (Enumeration enum=pfm.getKerning().keys(); enum.hasMoreElements();) { - String kpx1=(String)enum.nextElement(); - el=doc.createElement("kerning"); - el.setAttribute("kpx1", kpx1); - root.appendChild(el); - Element el2=null; - - Hashtable h2=(Hashtable)pfm.getKerning().get(kpx1); - for (Enumeration enum2=h2.keys(); enum2.hasMoreElements(); ) { - 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); - } + // Get kerning + for (Enumeration enum = pfm.getKerning().keys(); + enum.hasMoreElements();) { + String kpx1 = (String) enum.nextElement(); + el = doc.createElement("kerning"); + el.setAttribute("kpx1", kpx1); + root.appendChild(el); + Element el2 = null; + + Hashtable h2 = (Hashtable) pfm.getKerning().get(kpx1); + for (Enumeration enum2 = h2.keys(); enum2.hasMoreElements();) { + 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(); - } + + private String escapeString(String str) { + StringBuffer esc = new StringBuffer(); + + for (int i = 0; i < str.length(); i++) { + if (str.charAt(i) == '\\') + esc.append("\\\\"); + else + esc.append(str.charAt(i)); + } + + return esc.toString(); + } } diff --git a/src/org/apache/fop/fonts/apps/TTFReader.java b/src/org/apache/fop/fonts/apps/TTFReader.java index e4ff7774b..61b3b01f6 100644 --- a/src/org/apache/fop/fonts/apps/TTFReader.java +++ b/src/org/apache/fop/fonts/apps/TTFReader.java @@ -1,52 +1,8 @@ /* -- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "Fop" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber <jtauber@jtauber.com>. For more information on the Apache - Software Foundation, please see <http://www.apache.org/>. - + * + * 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; @@ -72,180 +28,182 @@ public class 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 cid"); - System.out.println(" With this option you create a CID keyed font."); - System.out.println(" If you're going to use characters outside the"); - System.out.println(" pdfencoding range (almost the same as iso-8889-1)"); - System.out.println(" you must 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 PFM reader tool. - * - * @param args Command-line arguments: [options] fontfile.ttf xmlfile.xml - * where options can be: - * -fn <fontname> - * default is to use the fontname in the .ttf file, but you can override - * that name to make sure that the embedded font is used instead of installed - * fonts when viewing documents with Acrobat Reader. - * -cn <classname> - * default is to use the fontname - * -ef <path to the truetype fontfile> - * will add the possibility to embed the font. When running fop, fop will look - * for this file to embed it - * -er <path to truetype fontfile relative to org/apache/fop/render/pdf/fonts> - * you can also include the fontfile in the fop.jar file when building fop. - * You can use both -ef and -er. The file specified in -ef will be searched first, - * then the -er file. - */ + * 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=false; - - Hashtable options=new Hashtable(); - String[] arguments=parseArguments(options, args); - - TTFReader app = new TTFReader(); - app.invokedStandalone = true; - - System.out.println("TTF Reader v1.1"); - System.out.println(); - - if (options.get("-enc") != null) { - String enc = (String)options.get("-enc"); - if ("cid".equals(enc)) - isCid=true; - } - - 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 (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 can't be embedded."); - - } - } + 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; + + /** + * 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. - */ + * 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 + 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.asDOMSerializer(); // As a DOM Serializer serial.serialize(doc.getDocumentElement()); out.close(); @@ -255,15 +213,14 @@ public class TTFReader { } /** - * 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) { + * 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(); @@ -274,18 +231,18 @@ public class TTFReader { 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". + // 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))); + el.appendChild(doc.createTextNode(stripWhiteSpace(fontName))); else el.appendChild(doc.createTextNode(s)); @@ -298,66 +255,62 @@ public class TTFReader { el = doc.createElement("cap-height"); root.appendChild(el); - Integer value = new Integer(ttf.getCapHeight()); - el.appendChild(doc.createTextNode(value.toString())); + el.appendChild( + doc.createTextNode(String.valueOf(ttf.getCapHeight()))); el = doc.createElement("x-height"); root.appendChild(el); - value = new Integer(ttf.getXHeight()); - el.appendChild(doc.createTextNode(value.toString())); - + el.appendChild( + doc.createTextNode(String.valueOf(ttf.getXHeight()))); + el = doc.createElement("ascender"); root.appendChild(el); - value = new Integer(ttf.getLowerCaseAscent()); - el.appendChild(doc.createTextNode(value.toString())); - + el.appendChild( doc.createTextNode( + String.valueOf(ttf.getLowerCaseAscent()))); + el = doc.createElement("descender"); root.appendChild(el); - value = new Integer(ttf.getLowerCaseDescent()); - el.appendChild(doc.createTextNode(value.toString())); + 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++) { + 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.appendChild(doc.createTextNode(String.valueOf(bb[i]))); } el = doc.createElement("flags"); root.appendChild(el); - value = new Integer(ttf.getFlags()); - el.appendChild(doc.createTextNode(value.toString())); - + el.appendChild(doc.createTextNode(String.valueOf(ttf.getFlags()))); + el = doc.createElement("stemv"); root.appendChild(el); - value = new Integer(ttf.getStemV()); - el.appendChild(doc.createTextNode(value.toString())); - + el.appendChild(doc.createTextNode(ttf.getStemV())); + el = doc.createElement("italicangle"); root.appendChild(el); - value = new Integer(ttf.getItalicAngle()); - el.appendChild(doc.createTextNode(value.toString())); + 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 + + // 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")); @@ -368,117 +321,119 @@ public class TTFReader { 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"); + for (Enumeration e = ttf.getCMaps().elements(); + e.hasMoreElements();) { + TTFCmapEntry ce = (TTFCmapEntry) e.nextElement(); + Element el2 = doc.createElement("bf"); el.appendChild(el2); - el2.setAttribute("us", Integer.toString(ce.unicodeStart)); - el2.setAttribute("ue", Integer.toString(ce.unicodeEnd)); - el2.setAttribute("gi", Integer.toString(ce.glyphStartIndex)); + 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", Integer.toString(wx[i])); + Element wxel = doc.createElement("wx"); + wxel.setAttribute("w", String.valueOf(wx[i])); el.appendChild(wxel); } } else { - // Fill in extras for singlebyte fonts + // Fill in extras for singlebyte fonts el.appendChild(doc.createTextNode("TRUETYPE")); - Element sel=doc.createElement("singlebyte-extras"); + 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); - value = new Integer(ttf.getFirstChar()); - el.appendChild(doc.createTextNode(value.toString())); - + el.appendChild( + doc.createTextNode(String.valueOf(ttf.getFirstChar()))); + el = doc.createElement("last-char"); sel.appendChild(el); - value = new Integer(ttf.getLastChar()); - el.appendChild(doc.createTextNode(value.toString())); - + 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++) { + + for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); + i++) { el = doc.createElement("char"); widths.appendChild(el); - el.setAttribute("idx", Integer.toString(i)); - el.setAttribute("wdt", Integer.toString(ttf.getCharWidth(i))); + el.setAttribute("idx", String.valueOf(i)); + el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i))); } } - - // Get kerning + + // Get kerning Enumeration enum; if (isCid) - enum=ttf.getKerning().keys(); + enum = ttf.getKerning().keys(); else - enum=ttf.getAnsiKerning().keys(); - + enum = ttf.getAnsiKerning().keys(); + while (enum.hasMoreElements()) { - Integer kpx1=(Integer)enum.nextElement(); + Integer kpx1 = (Integer) enum.nextElement(); - el=doc.createElement("kerning"); + el = doc.createElement("kerning"); el.setAttribute("kpx1", kpx1.toString()); root.appendChild(el); - Element el2=null; - + Element el2 = null; + Hashtable h2; if (isCid) - h2 = (Hashtable)ttf.getKerning().get(kpx1); + 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(); + 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 = doc.createElement("pair"); el2.setAttribute("kpx2", kpx2.toString()); - Integer val=(Integer)h2.get(kpx2); + 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') + 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(); - } + + 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(); + } } |