aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfotis <fotis@unknown>2001-03-22 18:17:02 +0000
committerfotis <fotis@unknown>2001-03-22 18:17:02 +0000
commit7f41a1391a0554393795b4bf4ca7bcbf79bc8645 (patch)
treefa70dd99b1ade894f025ea3ebb969bda138da814
parent75cbd9c88de7a315de189c4c98b7c3992b23bc40 (diff)
downloadxmlgraphics-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
-rw-r--r--src/org/apache/fop/fonts/FontFileReader.java432
-rw-r--r--src/org/apache/fop/fonts/PFMFile.java417
-rw-r--r--src/org/apache/fop/fonts/TTFCmapEntry.java66
-rw-r--r--src/org/apache/fop/fonts/TTFDirTabEntry.java94
-rw-r--r--src/org/apache/fop/fonts/TTFFile.java1312
-rw-r--r--src/org/apache/fop/fonts/TTFMtxEntry.java75
-rw-r--r--src/org/apache/fop/fonts/TTFSegEntry.java66
-rw-r--r--src/org/apache/fop/fonts/apps/FontPostProcess.xsl2
-rw-r--r--src/org/apache/fop/fonts/apps/PFMReader.java358
-rw-r--r--src/org/apache/fop/fonts/apps/TTFReader.java563
-rw-r--r--src/org/apache/fop/layout/LineArea.java65
-rw-r--r--src/org/apache/fop/render/pdf/FontReader.java134
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java582
-rw-r--r--src/org/apache/fop/render/pdf/fonts/MultiByteFont.java300
-rw-r--r--src/org/apache/fop/render/pdf/fonts/SingleByteFont.java14
15 files changed, 2102 insertions, 2378 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();
+ }
}
diff --git a/src/org/apache/fop/layout/LineArea.java b/src/org/apache/fop/layout/LineArea.java
index bbdc6f66f..1c0a94f3f 100644
--- a/src/org/apache/fop/layout/LineArea.java
+++ b/src/org/apache/fop/layout/LineArea.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.layout;
@@ -220,6 +176,8 @@ public class LineArea extends Area {
data[count] = odata[count];
}
+ boolean isText = false;
+
/* iterate over each character */
for (int i = start; i < end; i++) {
int charWidth;
@@ -229,14 +187,12 @@ public class LineArea extends Area {
(c == '\t'))) {
c = data[i] = currentFontState.mapChar(c);
charWidth = currentFontState.width(c);
+ isText = true;
if (charWidth <= 0)
charWidth = whitespaceWidth;
} else {
charWidth = whitespaceWidth;
- }
-
- if ((c == ' ') || (c == '\n') || (c == '\r') ||
- (c == '\t')) { // whitespace
+ isText = false;
if (prev == WHITESPACE) {
@@ -370,11 +326,12 @@ public class LineArea extends Area {
spaceWidth = whitespaceWidth;
} else {
// skip over it
- start++;
+ wordStart++;
}
}
- } else { // current is TEXT
+ }
+ if(isText) { // current is TEXT
if (prev == WHITESPACE) {
diff --git a/src/org/apache/fop/render/pdf/FontReader.java b/src/org/apache/fop/render/pdf/FontReader.java
index 153ab4a36..ce79dce42 100644
--- a/src/org/apache/fop/render/pdf/FontReader.java
+++ b/src/org/apache/fop/render/pdf/FontReader.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/>.
-
+/*-- $Id$ --
+ *
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources."
*/
package org.apache.fop.render.pdf;
@@ -81,7 +37,7 @@ public class FontReader extends DefaultHandler {
private MultiByteFont multiFont = null;
private SingleByteFont singleFont = null;
private Font returnFont = null;
- //private SingleByteFont singleFont = null;
+ //private SingleByteFont singleFont = null;
private String text = null;
private Vector cidWidths = null;
@@ -90,7 +46,7 @@ public class FontReader extends DefaultHandler {
private Hashtable currentKerning = null;
private Vector bfranges = null;
-
+
private void createFont(String path) throws IOException {
XMLReader parser = ConfigurationReader.createParser();
if (parser == null)
@@ -100,8 +56,8 @@ public class FontReader extends DefaultHandler {
parser.setFeature("http://xml.org/sax/features/namespace-prefixes",
false);
} catch (SAXException e) {
- throw new IOException ("You need a SAX parser which supports " +
- "SAX version 2");
+ throw new IOException (
+ "You need a SAX parser which supports " + "SAX version 2");
}
parser.setContentHandler(this);
@@ -113,38 +69,38 @@ public class FontReader extends DefaultHandler {
}
}
- /**
- * Sets the path to embed a font. a null value disables font embedding
- */
+ /**
+ * Sets the path to embed a font. a null value disables font embedding
+ */
public void setFontEmbedPath(String path) {
if (isCID)
- multiFont.embedFileName=path;
+ multiFont.embedFileName = path;
else
- singleFont.embedFileName=path;
+ singleFont.embedFileName = path;
}
-
- /**
- * Enable/disable use of kerning for the font
- */
+
+ /**
+ * Enable/disable use of kerning for the font
+ */
public void useKerning(boolean kern) {
if (isCID)
multiFont.useKerning = true;
else
singleFont.useKerning = true;
}
-
-
- /**
- * Get the generated font object
- */
+
+
+ /**
+ * Get the generated font object
+ */
public Font getFont() {
return returnFont;
}
- /**
- * Construct a FontReader object from a path to a metric.xml file
- * and read metric data
- */
+ /**
+ * Construct a FontReader object from a path to a metric.xml file
+ * and read metric data
+ */
public FontReader(String path) throws IOException {
createFont(path);
}
@@ -176,25 +132,27 @@ public class FontReader extends DefaultHandler {
}
} else if ("embed".equals(localName)) {
if (isCID) {
- // This *is* annoying... should create a common
- // interface for sing/multibytefonts...
+ // This *is* annoying... should create a common
+ // interface for sing/multibytefonts...
multiFont.embedFileName = attributes.getValue("file");
multiFont.embedResourceName = attributes.getValue("class");
} else {
singleFont.embedFileName = attributes.getValue("file");
singleFont.embedResourceName = attributes.getValue("class");
- }
+ }
} else if ("cid-widths".equals(localName)) {
cidWidthIndex = getInt(attributes.getValue("start-index"));
cidWidths = new Vector();
} else if ("kerning".equals(localName)) {
currentKerning = new Hashtable();
if (isCID)
- multiFont.kerning.put(new Integer(attributes.getValue("kpx1")),
- currentKerning);
+ multiFont.kerning.put(
+ new Integer(attributes.getValue("kpx1")),
+ currentKerning);
else
- singleFont.kerning.put(new Integer(attributes.getValue("kpx1")),
- currentKerning);
+ singleFont.kerning.put(
+ new Integer(attributes.getValue("kpx1")),
+ currentKerning);
} else if ("bfranges".equals(localName)) {
bfranges = new Vector();
} else if ("bf".equals(localName)) {
@@ -209,15 +167,16 @@ public class FontReader extends DefaultHandler {
singleFont.width = new int[256];
} else if ("char".equals(localName)) {
try {
- singleFont.width[Integer.parseInt(attributes.getValue("idx"))] =
+ singleFont.width[
+ Integer.parseInt(attributes.getValue("idx"))] =
Integer.parseInt(attributes.getValue("wdt"));
} catch (NumberFormatException ne) {
System.out.println("Malformed width in metric file: " +
ne.getMessage());
}
} else if ("pair".equals(localName)) {
- currentKerning.put(new Integer(attributes.getValue("kpx2")),
- new Integer(attributes.getValue("kern")));
+ currentKerning.put( new Integer(attributes.getValue("kpx2")),
+ new Integer(attributes.getValue("kern")));
}
}
@@ -228,13 +187,15 @@ public class FontReader extends DefaultHandler {
} catch (Exception e) {}
return ret;
}
-
+
public void endElement(String uri, String localName, String qName) {
if ("font-name".equals(localName))
if (isCID)
multiFont.fontName = text;
else
singleFont.fontName = text;
+ if ("ttc-name".equals(localName) && isCID)
+ multiFont.ttcName = text;
else if ("cap-height".equals(localName))
if (isCID)
multiFont.capHeight = getInt(text);
@@ -307,14 +268,15 @@ public class FontReader extends DefaultHandler {
} else if ("cid-widths".equals(localName)) {
int[] wds = new int[cidWidths.size()];
int j = 0;
- for (Enumeration e = cidWidths.elements(); e.hasMoreElements();) {
- Integer i = (Integer)e.nextElement();
+ for (Enumeration e = cidWidths.elements();
+ e.hasMoreElements();) {
+ Integer i = (Integer) e.nextElement();
wds[j++] = i.intValue();
}
multiFont.warray.addEntry(cidWidthIndex, wds);
multiFont.width = wds;
-
+
} else if ("bfranges".equals(localName)) {
BFEntry[] entries = new BFEntry[bfranges.size()];
bfranges.copyInto(entries);
@@ -328,7 +290,7 @@ public class FontReader extends DefaultHandler {
System.arraycopy(ch, start, c, 0, length);
text = new String(c);
}
-
+
}
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
index fabbb1802..eb4ab80e3 100644
--- a/src/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -37,7 +37,7 @@ import java.util.Hashtable;
public class PDFRenderer extends PrintRenderer {
private static final boolean OPTIMIZE_TEXT = true;
-
+
/** the PDF Document being created */
protected PDFDocument pdfDoc;
@@ -68,7 +68,7 @@ public class PDFRenderer extends PrintRenderer {
int prevWordWidth = 0;
private PDFOutline rootOutline;
-
+
/**
* create the PDF renderer
*/
@@ -77,20 +77,20 @@ public class PDFRenderer extends PrintRenderer {
}
/**
- * set the PDF document's producer
- *
- * @param producer string indicating application producing PDF
- */
+ * set the PDF document's producer
+ *
+ * @param producer string indicating application producing PDF
+ */
public void setProducer(String producer) {
this.pdfDoc.setProducer(producer);
}
/**
- * render the areas into PDF
- *
- * @param areaTree the laid-out area tree
- * @param stream the OutputStream to write the PDF to
- */
+ * render the areas into PDF
+ *
+ * @param areaTree the laid-out area tree
+ * @param stream the OutputStream to write the PDF to
+ */
public void render(AreaTree areaTree,
OutputStream stream) throws IOException, FOPException {
MessageHandler.logln("rendering areas to PDF");
@@ -108,15 +108,37 @@ public class PDFRenderer extends PrintRenderer {
idReferences.getInvalidIds() + "\n");
}
- renderRootExtensions(areaTree);
-
+ renderRootExtensions(areaTree);
+
FontSetup.addToResources(this.pdfDoc, fontInfo);
-
+
MessageHandler.logln("writing out PDF");
this.pdfDoc.output(stream);
}
/**
+ * add a line to the current stream
+ *
+ * @param x1 the start x location in millipoints
+ * @param y1 the start y location in millipoints
+ * @param x2 the end x location in millipoints
+ * @param y2 the end y location in millipoints
+ * @param th the thickness in millipoints
+ * @param r the red component
+ * @param g the green component
+ * @param b the blue component
+ */
+ protected void addLine(int x1, int y1, int x2, int y2, int th,
+ PDFPathPaint stroke) {
+ closeText();
+
+ currentStream.add("ET\nq\n" + stroke.getColorSpaceOut(false) +
+ (x1 / 1000f) + " "+ (y1 / 1000f) + " m " +
+ (x2 / 1000f) + " "+ (y2 / 1000f) + " l " +
+ (th / 1000f) + " w S\n" + "Q\nBT\n");
+ }
+
+ /**
* add a line to the current stream
*
* @param x1 the start x location in millipoints
@@ -124,72 +146,50 @@ public class PDFRenderer extends PrintRenderer {
* @param x2 the end x location in millipoints
* @param y2 the end y location in millipoints
* @param th the thickness in millipoints
+ * @param rs the rule style
* @param r the red component
* @param g the green component
* @param b the blue component
*/
protected void addLine(int x1, int y1, int x2, int y2, int th,
- PDFPathPaint stroke) {
- closeText();
-
- currentStream.add("ET\nq\n" + stroke.getColorSpaceOut(false) +
- (x1 / 1000f) + " "+ (y1 / 1000f) + " m " +
- (x2 / 1000f) + " "+ (y2 / 1000f) + " l " +
- (th / 1000f) + " w S\n" + "Q\nBT\n");
- }
-
- /**
- * add a line to the current stream
- *
- * @param x1 the start x location in millipoints
- * @param y1 the start y location in millipoints
- * @param x2 the end x location in millipoints
- * @param y2 the end y location in millipoints
- * @param th the thickness in millipoints
- * @param rs the rule style
- * @param r the red component
- * @param g the green component
- * @param b the blue component
- */
- protected void addLine(int x1, int y1, int x2, int y2, int th,
int rs, PDFPathPaint stroke) {
- closeText();
+ closeText();
currentStream.add("ET\nq\n" + stroke.getColorSpaceOut(false) +
- setRuleStylePattern(rs) + (x1 / 1000f) + " "+ (y1 / 1000f) + " m " +
- (x2 / 1000f) + " "+ (y2 / 1000f) + " l " +
- (th / 1000f) + " w S\n" + "Q\nBT\n");
+ setRuleStylePattern(rs) + (x1 / 1000f) + " "+
+ (y1 / 1000f) + " m " + (x2 / 1000f) + " "+
+ (y2 / 1000f) + " l " + (th / 1000f) + " w S\n" + "Q\nBT\n");
}
/**
- * add a rectangle to the current stream
- *
- * @param x the x position of left edge in millipoints
- * @param y the y position of top edge in millipoints
- * @param w the width in millipoints
- * @param h the height in millipoints
- * @param stroke the stroke color/gradient
- */
+ * add a rectangle to the current stream
+ *
+ * @param x the x position of left edge in millipoints
+ * @param y the y position of top edge in millipoints
+ * @param w the width in millipoints
+ * @param h the height in millipoints
+ * @param stroke the stroke color/gradient
+ */
protected void addRect(int x, int y, int w, int h,
PDFPathPaint stroke) {
- closeText();
+ closeText();
currentStream.add("ET\nq\n" + stroke.getColorSpaceOut(false) +
(x / 1000f) + " " + (y / 1000f) + " " + (w / 1000f) +
" " + (h / 1000f) + " re s\n" + "Q\nBT\n");
}
/**
- * add a filled rectangle to the current stream
- *
- * @param x the x position of left edge in millipoints
- * @param y the y position of top edge in millipoints
- * @param w the width in millipoints
- * @param h the height in millipoints
- * @param fill the fill color/gradient
- * @param stroke the stroke color/gradient
- */
+ * add a filled rectangle to the current stream
+ *
+ * @param x the x position of left edge in millipoints
+ * @param y the y position of top edge in millipoints
+ * @param w the width in millipoints
+ * @param h the height in millipoints
+ * @param fill the fill color/gradient
+ * @param stroke the stroke color/gradient
+ */
protected void addRect(int x, int y, int w, int h,
PDFPathPaint stroke, PDFPathPaint fill) {
- closeText();
+ closeText();
currentStream.add("ET\nq\n" + fill.getColorSpaceOut(true) +
stroke.getColorSpaceOut(false) + (x / 1000f) + " " +
(y / 1000f) + " " + (w / 1000f) + " " + (h / 1000f) +
@@ -197,10 +197,10 @@ public class PDFRenderer extends PrintRenderer {
}
/**
- * render image area to PDF
- *
- * @param area the image area to render
- */
+ * render image area to PDF
+ *
+ * @param area the image area to render
+ */
public void renderImageArea(ImageArea area) {
// adapted from contribution by BoBoGi
int x = this.currentAreaContainerXPosition + area.getXOffset();
@@ -213,8 +213,8 @@ public class PDFRenderer extends PrintRenderer {
FopImage img = area.getImage();
if (img instanceof SVGImage) {
try {
- closeText();
-
+ closeText();
+
SVGSVGElement svg =
((SVGImage) img).getSVGDocument().getRootElement();
currentStream.add("ET\nq\n" + (((float) w) / 1000f) +
@@ -227,8 +227,8 @@ public class PDFRenderer extends PrintRenderer {
}
} else {
int xObjectNum = this.pdfDoc.addImage(img);
- closeText();
-
+ closeText();
+
currentStream.add("ET\nq\n" + (((float) w) / 1000f) +
" 0 0 " + (((float) h) / 1000f) + " " +
(((float) x) / 1000f) + " " +
@@ -269,8 +269,8 @@ public class PDFRenderer extends PrintRenderer {
case VerticalAlign.BOTTOM:
break;
}
- closeText();
-
+ closeText();
+
// in general the content will not be text
currentStream.add("ET\n");
// align and scale
@@ -296,64 +296,66 @@ public class PDFRenderer extends PrintRenderer {
currentStream.add("Q\n");
currentStream.add("BT\n");
this.currentXPosition += area.getEffectiveWidth();
-// this.currentYPosition -= area.getEffectiveHeight();
+ // this.currentYPosition -= area.getEffectiveHeight();
}
/**
- * render SVG area to PDF
- *
- * @param area the SVG area to render
- */
+ * render SVG area to PDF
+ *
+ * @param area the SVG area to render
+ */
public void renderSVGArea(SVGArea area) {
// place at the current instream offset
int x = this.currentXPosition;
- // Buggy: Method getXOffset() not found in class org.apache.fop.dom.svg.SVGArea
+ // Buggy: Method getXOffset() not found in class org.apache.fop.dom.svg.SVGArea
//int x = this.currentAreaContainerXPosition + area.getXOffset();
int y = this.currentYPosition;
SVGSVGElement svg = area.getSVGDocument().getRootElement();
int w = (int)(svg.getWidth().getBaseVal().getValue() * 1000);
int h = (int)(svg.getHeight().getBaseVal().getValue() * 1000);
- float sx = 1, sy = -1;
- int xOffset = x, yOffset = y;
-
- // translate and scale according to viewbox.
- if (svg.getViewBox () != null) {
- SVGRect view = svg.getViewBox().getBaseVal();
-
- // TODO take aspect constraints (attribute preserveAspectRatio)
- // into account.
- // Viewbox coordinates are all relative to the viewport
- // (ie. the x,y,w and h values calculated above).
- sx = svg.getWidth().getBaseVal().getValue() / view.getWidth ();
- sy = svg.getHeight().getBaseVal().getValue() / view.getHeight ();
-
- // move the origin
- xOffset -= (int)(sx * view.getX () * 1000f);
- yOffset -= (int)(sy * view.getY () * 1000f);
-
- sy = -sy;
- }
+ float sx = 1, sy = -1;
+ int xOffset = x, yOffset = y;
+
+ // translate and scale according to viewbox.
+ if (svg.getViewBox () != null) {
+ SVGRect view = svg.getViewBox().getBaseVal();
+
+ // TODO take aspect constraints (attribute preserveAspectRatio)
+ // into account.
+ // Viewbox coordinates are all relative to the viewport
+ // (ie. the x,y,w and h values calculated above).
+ sx = svg.getWidth().getBaseVal().getValue() / view.getWidth ();
+ sy = svg.getHeight().getBaseVal().getValue() /
+ view.getHeight ();
+
+ // move the origin
+ xOffset -= (int)(sx * view.getX () * 1000f);
+ yOffset -= (int)(sy * view.getY () * 1000f);
+
+ sy = -sy;
+ }
/*
- * Clip to the svg area.
- * Note: To have the svg overlay (under) a text area then use
- * an fo:block-container
- */
+ * Clip to the svg area.
+ * Note: To have the svg overlay (under) a text area then use
+ * an fo:block-container
+ */
currentStream.add("q\n");
- if (w != 0 && h != 0) {
- currentStream.add(x / 1000f + " " + y / 1000f + " m\n");
- currentStream.add((x + w) / 1000f + " " + y / 1000f + " l\n");
- currentStream.add((x + w) / 1000f + " " + (y - h) / 1000f + " l\n");
- currentStream.add(x / 1000f + " " + (y - h) / 1000f + " l\n");
- currentStream.add("h\n");
- currentStream.add("W\n");
- currentStream.add("n\n");
- }
+ if (w != 0 && h != 0) {
+ currentStream.add(x / 1000f + " " + y / 1000f + " m\n");
+ currentStream.add((x + w) / 1000f + " " + y / 1000f + " l\n");
+ currentStream.add((x + w) / 1000f + " " + (y - h) / 1000f +
+ " l\n");
+ currentStream.add(x / 1000f + " " + (y - h) / 1000f + " l\n");
+ currentStream.add("h\n");
+ currentStream.add("W\n");
+ currentStream.add("n\n");
+ }
// transform so that the coordinates (0,0) is from the top left
// and positive is down and to the right. (0,0) is where the
- // viewBox puts it.
- currentStream.add(sx + " 0 0 " + sy + " " +
- xOffset / 1000f + " " + yOffset / 1000f + " cm\n");
+ // viewBox puts it.
+ currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f +
+ " " + yOffset / 1000f + " cm\n");
SVGRenderer svgRenderer =
new SVGRenderer(area.getFontState(), pdfDoc,
@@ -366,17 +368,17 @@ public class PDFRenderer extends PrintRenderer {
}
/**
- * render inline area to PDF
- *
- * @param area inline area to render
- */
+ * render inline area to PDF
+ *
+ * @param area inline area to render
+ */
public void renderWordArea(WordArea area) {
- // char ch;
+ // char ch;
StringBuffer pdf = new StringBuffer();
- Hashtable kerning = null;
- boolean kerningAvailable = false;
-
+ Hashtable kerning = null;
+ boolean kerningAvailable = false;
+
kerning = area.getFontState().getKerning();
if (kerning != null && !kerning.isEmpty()) {
kerningAvailable = true;
@@ -385,23 +387,23 @@ public class PDFRenderer extends PrintRenderer {
String name = area.getFontState().getFontName();
int size = area.getFontState().getFontSize();
- // This assumes that *all* CIDFonts use a /ToUnicode mapping
+ // This assumes that *all* CIDFonts use a /ToUnicode mapping
boolean useMultiByte = false;
- Font f = (Font)area.getFontState().getFontInfo().getFonts().get(name);
+ Font f = (Font) area.getFontState().getFontInfo().getFonts().get(
+ name);
if (f instanceof CIDFont)
- useMultiByte=true;
- //String startText = useMultiByte ? "<FEFF" : "(";
+ useMultiByte = true;
+ //String startText = useMultiByte ? "<FEFF" : "(";
String startText = useMultiByte ? "<" : "(";
String endText = useMultiByte ? ">" : ")";
-
+
PDFColor theAreaColor = new PDFColor((double) area.getRed(),
- (double) area.getGreen(),
- (double) area.getBlue());
+ (double) area.getGreen(), (double) area.getBlue());
if ((!name.equals(this.currentFontName)) ||
(size != this.currentFontSize)) {
- closeText();
-
+ closeText();
+
this.currentFontName = name;
this.currentFontSize = size;
pdf = pdf.append("/" + name + " " + (size / 1000) + " Tf\n");
@@ -409,48 +411,47 @@ public class PDFRenderer extends PrintRenderer {
if (!(theAreaColor.equals(this.currentFill))) {
- closeText();
- this.currentFill = theAreaColor;
- pdf.append(this.currentFill.getColorSpaceOut(true));
+ closeText();
+ this.currentFill = theAreaColor;
+ pdf.append(this.currentFill.getColorSpaceOut(true));
}
int rx = this.currentXPosition;
int bl = this.currentYPosition;
- addWordLines(area, rx, bl, size, theAreaColor);
-
- if (OPTIMIZE_TEXT) {
- if (!textOpen || bl != prevWordY) {
- closeText();
-
- pdf.append("1 0 0 1 " +(rx / 1000f) + " " +
- (bl / 1000f) + " Tm [" + startText);
- prevWordY = bl;
- textOpen = true;
- }
- else {
- // express the space between words in thousandths of an em
- int space = prevWordX - rx + prevWordWidth;
- float emDiff = (float)space / (float)currentFontSize * 1000f;
- pdf.append(emDiff + " " + startText);
- }
- prevWordWidth = area.getContentWidth();
- prevWordX = rx;
-
- }
- else {
- // original text render code sets the text transformation matrix
- // for every word.
- pdf.append("1 0 0 1 " +(rx / 1000f) + " " + (bl / 1000f) + " Tm ");
- if (kerningAvailable) {
- pdf.append(" [" + startText);
- }
- else {
- pdf.append(" " + startText);
- }
- }
-
+ addWordLines(area, rx, bl, size, theAreaColor);
+
+ if (OPTIMIZE_TEXT) {
+ if (!textOpen || bl != prevWordY) {
+ closeText();
+
+ pdf.append("1 0 0 1 " +(rx / 1000f) + " " +
+ (bl / 1000f) + " Tm [" + startText);
+ prevWordY = bl;
+ textOpen = true;
+ } else {
+ // express the space between words in thousandths of an em
+ int space = prevWordX - rx + prevWordWidth;
+ float emDiff =
+ (float) space / (float) currentFontSize * 1000f;
+ pdf.append(emDiff + " " + startText);
+ }
+ prevWordWidth = area.getContentWidth();
+ prevWordX = rx;
+
+ } else {
+ // original text render code sets the text transformation matrix
+ // for every word.
+ pdf.append("1 0 0 1 " +(rx / 1000f) + " " + (bl / 1000f) +
+ " Tm ");
+ if (kerningAvailable) {
+ pdf.append(" [" + startText);
+ } else {
+ pdf.append(" " + startText);
+ }
+ }
+
String s;
if (area.getPageNumberID() != null) { // this text is a page number, so resolve it
s = idReferences.getPageNumber(area.getPageNumberID());
@@ -465,10 +466,10 @@ public class PDFRenderer extends PrintRenderer {
for (int i = 0; i < l; i++) {
char ch = s.charAt(i);
- String prepend = "";
-
+ String prepend = "";
+
if (!useMultiByte) {
- if(ch > 127) {
+ if (ch > 127) {
pdf.append("\\");
pdf.append(Integer.toOctalString((int) ch));
} else {
@@ -479,115 +480,110 @@ public class PDFRenderer extends PrintRenderer {
prepend = "\\";
break;
}
- pdf.append(getUnicodeString(prepend+ch, useMultiByte));
+ pdf.append(
+ getUnicodeString(prepend + ch, useMultiByte));
}
- } else {
- pdf.append(getUnicodeString(prepend+ch, useMultiByte));
- }
-
- if (kerningAvailable && (i+1) < l) {
- pdf.append(addKerning((new Integer((int)ch)),
- (new Integer((int)s.charAt(i+1))),
- kerning,
- startText, endText));
+ } else {
+ pdf.append(getUnicodeString(prepend + ch, useMultiByte));
+ }
+
+ if (kerningAvailable && (i + 1) < l) {
+ addKerning(pdf, (new Integer((int) ch)),
+ (new Integer((int) s.charAt(i + 1))), kerning,
+ startText, endText);
}
-
+
}
pdf.append(endText + " ");
- if (!OPTIMIZE_TEXT) {
- if (kerningAvailable) {
- pdf.append("] TJ\n");
- }
- else {
- pdf.append("Tj\n");
- }
-
- }
-
+ if (!OPTIMIZE_TEXT) {
+ if (kerningAvailable) {
+ pdf.append("] TJ\n");
+ } else {
+ pdf.append("Tj\n");
+ }
+
+ }
+
currentStream.add(pdf.toString());
this.currentXPosition += area.getContentWidth();
-
+
}
- /**
- * Convert a string to a unicode hex representation
- */
- private String getUnicodeString(StringBuffer str, boolean useMultiByte) {
+ /**
+ * Convert a string to a unicode hex representation
+ */
+ private String getUnicodeString(StringBuffer str,
+ boolean useMultiByte) {
return getUnicodeString(str.toString(), useMultiByte);
}
-
- /**
- * Convert a string to a multibyte hex representation
- */
+
+ /**
+ * Convert a string to a multibyte hex representation
+ */
private String getUnicodeString(String str, boolean useMultiByte) {
if (!useMultiByte) {
return str;
} else {
- StringBuffer buf = new StringBuffer(str.length()*4);
+ StringBuffer buf = new StringBuffer(str.length() * 4);
byte[] uniBytes = null;
try {
uniBytes = str.getBytes("UnicodeBigUnmarked");
} catch (Exception e) {
- // This should never fail
+ // This should never fail
}
-
+
for (int i = 0; i < uniBytes.length; i++) {
- int b = (uniBytes[i] < 0) ? (int)(256+uniBytes[i])
- : (int)uniBytes[i];
-
- String hexString=Integer.toHexString(b);
- if (hexString.length()==1)
- buf=buf.append("0"+hexString);
+ int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) :
+ (int) uniBytes[i];
+
+ String hexString = Integer.toHexString(b);
+ if (hexString.length() == 1)
+ buf = buf.append("0"+hexString);
else
- buf=buf.append(hexString);
+ buf = buf.append(hexString);
}
return buf.toString();
}
}
-
-
+
+
/** Checks to see if we have some text rendering commands open
- * still and writes out the TJ command to the stream if we do
- */
- private void closeText()
- {
- if (OPTIMIZE_TEXT && textOpen) {
- currentStream.add("] TJ\n");
- textOpen = false;
- prevWordX = 0;
- prevWordY = 0;
- }
+ * still and writes out the TJ command to the stream if we do
+ */
+ private void closeText() {
+ if (OPTIMIZE_TEXT && textOpen) {
+ currentStream.add("] TJ\n");
+ textOpen = false;
+ prevWordX = 0;
+ prevWordY = 0;
+ }
}
- private StringBuffer addKerning(Integer ch1, Integer ch2,
- Hashtable kerning, String startText,
- String endText) {
- Hashtable h2=(Hashtable)kerning.get(ch1);
- int pwdt=0;
- StringBuffer buf=new StringBuffer("");
-
- if (h2!=null) {
- Integer wdt=(Integer)h2.get(ch2);
- if (wdt!=null) {
- pwdt=-wdt.intValue();
- buf=buf.append(endText + " " + pwdt + " " + startText);
- }
- }
- return buf;
- }
+ private void addKerning(StringBuffer buf, Integer ch1, Integer ch2,
+ Hashtable kerning, String startText, String endText) {
+ Hashtable h2 = (Hashtable) kerning.get(ch1);
+
+ if (h2 != null) {
+ Integer wdt = (Integer) h2.get(ch2);
+ if (wdt != null) {
+ buf.append(endText).append(' ').append(-
+ wdt.intValue()).append(' ').append(startText);
+ }
+ }
+ }
/**
- * render page into PDF
- *
- * @param page page to render
- */
+ * render page into PDF
+ *
+ * @param page page to render
+ */
public void renderPage(Page page) {
- BodyAreaContainer body;
+ BodyAreaContainer body;
AreaContainer before, after, start, end;
currentStream = this.pdfDoc.makeStream();
@@ -600,7 +596,7 @@ public class PDFRenderer extends PrintRenderer {
this.currentFontName = "";
this.currentFontSize = 0;
- currentStream.add("BT\n");
+ currentStream.add("BT\n");
renderBodyAreaContainer(body);
@@ -612,20 +608,19 @@ public class PDFRenderer extends PrintRenderer {
renderAreaContainer(after);
}
- if (start != null) {
+ if (start != null) {
renderAreaContainer(start);
}
- if (end != null) {
+ if (end != null) {
renderAreaContainer(end);
}
- closeText();
-
+ closeText();
+
currentStream.add("ET\n");
currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream,
- page.getWidth() / 1000,
- page.getHeight() / 1000, page);
+ page.getWidth() / 1000, page.getHeight() / 1000, page);
if (page.hasLinks()) {
currentAnnotList = this.pdfDoc.makeAnnotList();
@@ -654,8 +649,8 @@ public class PDFRenderer extends PrintRenderer {
}
/**
- * defines a string containing dashArray and dashPhase for the rule style
- */
+ * defines a string containing dashArray and dashPhase for the rule style
+ */
private String setRuleStylePattern (int style) {
String rs = "";
switch (style) {
@@ -677,52 +672,49 @@ public class PDFRenderer extends PrintRenderer {
return rs;
}
- protected void renderRootExtensions(AreaTree areaTree)
- {
- Vector v = areaTree.getExtensions();
- if (v != null) {
- Enumeration e = v.elements();
- while (e.hasMoreElements()) {
- ExtensionObj ext = (ExtensionObj)e.nextElement();
- if (ext instanceof Outline) {
- renderOutline((Outline)ext);
- }
- }
- }
-
+ protected void renderRootExtensions(AreaTree areaTree) {
+ Vector v = areaTree.getExtensions();
+ if (v != null) {
+ Enumeration e = v.elements();
+ while (e.hasMoreElements()) {
+ ExtensionObj ext = (ExtensionObj) e.nextElement();
+ if (ext instanceof Outline) {
+ renderOutline((Outline) ext);
+ }
+ }
+ }
+
}
- private void renderOutline(Outline outline)
- {
- if (rootOutline == null) {
- rootOutline = this.pdfDoc.makeOutlineRoot();
- }
- PDFOutline pdfOutline = null;
- Outline parent = outline.getParentOutline();
- if (parent == null) {
- pdfOutline = this.pdfDoc.makeOutline(rootOutline,
- outline.getLabel().toString(),
- outline.getInternalDestination());
- }
- else {
- PDFOutline pdfParentOutline = (PDFOutline)parent.getRendererObject();
- if (pdfParentOutline == null) {
- MessageHandler.errorln("Error: pdfParentOutline is null");
- }
- else {
- pdfOutline = this.pdfDoc.makeOutline(pdfParentOutline,
- outline.getLabel().toString(),
- outline.getInternalDestination());
- }
-
- }
- outline.setRendererObject(pdfOutline);
-
- // handle sub outlines
- Vector v = outline.getOutlines();
- Enumeration e = v.elements();
- while (e.hasMoreElements()) {
- renderOutline((Outline)e.nextElement());
- }
+ private void renderOutline(Outline outline) {
+ if (rootOutline == null) {
+ rootOutline = this.pdfDoc.makeOutlineRoot();
+ }
+ PDFOutline pdfOutline = null;
+ Outline parent = outline.getParentOutline();
+ if (parent == null) {
+ pdfOutline = this.pdfDoc.makeOutline(rootOutline,
+ outline.getLabel().toString(),
+ outline.getInternalDestination());
+ } else {
+ PDFOutline pdfParentOutline =
+ (PDFOutline) parent.getRendererObject();
+ if (pdfParentOutline == null) {
+ MessageHandler.errorln("Error: pdfParentOutline is null");
+ } else {
+ pdfOutline = this.pdfDoc.makeOutline(pdfParentOutline,
+ outline.getLabel().toString(),
+ outline.getInternalDestination());
+ }
+
+ }
+ outline.setRendererObject(pdfOutline);
+
+ // handle sub outlines
+ Vector v = outline.getOutlines();
+ Enumeration e = v.elements();
+ while (e.hasMoreElements()) {
+ renderOutline((Outline) e.nextElement());
+ }
}
}
diff --git a/src/org/apache/fop/render/pdf/fonts/MultiByteFont.java b/src/org/apache/fop/render/pdf/fonts/MultiByteFont.java
index 7b55e843d..f8305c3d6 100644
--- a/src/org/apache/fop/render/pdf/fonts/MultiByteFont.java
+++ b/src/org/apache/fop/render/pdf/fonts/MultiByteFont.java
@@ -1,17 +1,26 @@
-
+/* $Id$
+ *
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources."
+ */
package org.apache.fop.render.pdf.fonts;
import org.apache.fop.render.pdf.Font;
import org.apache.fop.layout.FontDescriptor;
import org.apache.fop.fonts.Glyphs;
+import org.apache.fop.fonts.TTFSubSetFile;
+import org.apache.fop.fonts.FontFileReader;
import org.apache.fop.pdf.PDFStream;
import org.apache.fop.pdf.PDFWArray;
import org.apache.fop.pdf.PDFCIDFont;
import org.apache.fop.render.pdf.CIDFont;
import org.apache.fop.render.pdf.CMap;
import org.apache.fop.pdf.PDFTTFStream;
+import org.apache.fop.messaging.MessageHandler;
import java.io.InputStream;
+import java.io.IOException;
import java.io.FileInputStream;
import java.io.File;
import java.io.BufferedInputStream;
@@ -22,143 +31,185 @@ import java.util.Hashtable;
*/
public class MultiByteFont extends CIDFont implements FontDescriptor {
public String fontName = null;
+ public String ttcName = null;
public String encoding = "Identity-H";
-
+
public int capHeight = 0;
public int xHeight = 0;
public int ascender = 0;
public int descender = 0;
public int[] fontBBox = {0, 0, 0, 0};
-
+
public String embedFileName = null;
public String embedResourceName = null;
- public PDFTTFStream embeddedFont=null;
-
+ public PDFTTFStream embeddedFont = null;
+
public int flags = 4;
public int stemV = 0;
public int italicAngle = 0;
public int missingWidth = 0;
public int defaultWidth = 0;
public byte cidType = PDFCIDFont.CID_TYPE2;
-
- public Hashtable kerning=new Hashtable();
+
+ public Hashtable kerning = new Hashtable();
public boolean useKerning = true;
-
- public PDFWArray warray=new PDFWArray();
+ private String namePrefix = null; // Quasi unique prefix
+ private static int uniqueCounter = 1;
+ public PDFWArray warray = new PDFWArray();
public int width[] = null;
public BFEntry[] bfentries = null;
-
- public MultiByteFont() {}
-
+
+ /** usedGlyphs contains orginal, new glyph index */
+ private Hashtable usedGlyphs = new Hashtable();
+ /** usedGlyphsIndex contains new glyph, original index */
+ private Hashtable usedGlyphsIndex = new Hashtable();
+ int usedGlyphsCount = 0;
+
+ public MultiByteFont() {
+ // Make sure that the 3 first glyphs are included
+ usedGlyphs.put(new Integer(0), new Integer(0));
+ usedGlyphsIndex.put(new Integer(0), new Integer(0));
+ usedGlyphsCount++;
+ usedGlyphs.put(new Integer(1), new Integer(1));
+ usedGlyphsIndex.put(new Integer(1), new Integer(1));
+ usedGlyphsCount++;
+ usedGlyphs.put(new Integer(2), new Integer(2));
+ usedGlyphsIndex.put(new Integer(2), new Integer(2));
+ usedGlyphsCount++;
+
+ // Create a quasiunique prefix for fontname
+ int cnt = 0;
+ synchronized (this.getClass()) {
+ cnt = uniqueCounter++;
+ }
+ int ctm = (int)(System.currentTimeMillis() & 0xffff);
+ namePrefix = new String(cnt + "E"+ Integer.toHexString(ctm));
+ }
+
public final boolean hasKerningInfo() {
return (useKerning & kerning.isEmpty());
}
- public final java.util.Hashtable getKerningInfo() {return kerning;}
+ public final java.util.Hashtable getKerningInfo() {
+ if (useKerning)
+ return kerning;
+ else
+ return new Hashtable();
+ }
public byte getSubType() {
return org.apache.fop.pdf.PDFFont.TYPE0;
}
- public String getLang() {return null;}
- public String getPanose() {return null;}
- public int getAvgWidth() {return -1;}
- public int getMinWidth() {return -1;}
- public int getMaxWidth() {return -1;}
- public int getleading() {return -1;}
- public int getStemH() {return 0;}
- public int getMissingWidth() {return missingWidth;}
- public int getDefaultWidth() {return defaultWidth;}
- public String getRegistry() {return "Adobe";}
- public String getOrdering() {return "UCS";}
- public int getSupplement() {return 0;}
- public byte getCidType() {return cidType;}
- public String getCidBaseFont() {return fontName;}
- public String getCharEncoding() {return "Identity-H";}
+ public String getLang() {
+ return null;
+ }
+ public String getPanose() {
+ return null;
+ }
+ public int getAvgWidth() {
+ return -1;
+ }
+ public int getMinWidth() {
+ return -1;
+ }
+ public int getMaxWidth() {
+ return -1;
+ }
+ public int getleading() {
+ return -1;
+ }
+ public int getStemH() {
+ return 0;
+ }
+ public int getMissingWidth() {
+ return missingWidth;
+ }
+ public int getDefaultWidth() {
+ return defaultWidth;
+ }
+ public String getRegistry() {
+ return "Adobe";
+ }
+ public String getOrdering() {
+ return "UCS";
+ }
+ public int getSupplement() {
+ return 0;
+ }
+ public byte getCidType() {
+ return cidType;
+ }
+ public String getCidBaseFont() {
+ return isEmbeddable() ? namePrefix + fontName : fontName;
+ }
+
+ public String getCharEncoding() {
+ return "Identity-H";
+ }
public PDFWArray getWidths() {
+ if (isEmbeddable()) {
+ // Create widths for reencoded chars
+ warray = new PDFWArray();
+ int[] tmpWidth = new int[usedGlyphsCount];
+
+ for (int i = 0; i < usedGlyphsCount; i++) {
+ Integer nw = (Integer) usedGlyphsIndex.get(new Integer(i));
+ int nwx = (nw == null) ? 0 : nw.intValue();
+ tmpWidth[i] = width[nwx];
+ }
+ warray.addEntry(0, tmpWidth);
+ }
return warray;
}
public boolean isEmbeddable() {
- return (embedFileName==null && embedResourceName==null) ? false : true;
+ return (embedFileName == null && embedResourceName == null) ?
+ false : true;
}
-
- public PDFStream getFontFile(int i) {
- InputStream instream=null;
- int iniSize = 256000;
- int incSize = 128000;
- // Get file first
- if (embedFileName!=null)
- try {
- File ef = new File(embedFileName);
- iniSize = (int)ef.length()+1;
- incSize = (int)ef.length()/10;
- instream=new FileInputStream(embedFileName);
- } catch (Exception e) {
- System.out.println("Failed to embed fontfile: "+embedFileName);
- }
-
- // Get resource
- if (instream==null && embedResourceName!=null)
+ public PDFStream getFontFile(int i) {
try {
- instream=new BufferedInputStream(this.getClass().getResourceAsStream(embedResourceName));
- } catch (Exception e) {
- System.out.println("Failed to embed fontresource: "+embedResourceName);
+ FontFileReader reader = new FontFileReader(embedFileName);
+ TTFSubSetFile subset = new TTFSubSetFile();
+
+ byte[] subsetFont =
+ subset.readFont(reader, ttcName, usedGlyphs);
+ // Only TrueType CID fonts are supported now
+
+ embeddedFont = new PDFTTFStream(i, subsetFont.length);
+ embeddedFont.addFilter("flate");
+ embeddedFont.addFilter("ascii-85");
+ embeddedFont.setData(subsetFont, subsetFont.length);
+ } catch (IOException ioe) {
+ MessageHandler.error("Failed to embed font " + fontName +
+ ": " + ioe.getMessage());
+ return (PDFStream) null;
}
-
- if (instream==null)
- return (PDFStream)null;
-
- // Read fontdata
- byte[] file = new byte[iniSize];
- int fsize = 0;
-
- try {
- int l = instream.read(file, 0, iniSize);
- fsize += l;
-
- if (l==iniSize) {
- // More to read - needs to extend
- byte[] tmpbuf;
-
- while (l > 0) {
- tmpbuf = new byte[file.length + incSize];
- System.arraycopy(file, 0, tmpbuf, 0, file.length);
- l=instream.read(tmpbuf, file.length, incSize);
- fsize += l;
- file = tmpbuf;
-
- if (l < incSize) // whole file read. No need to loop again
- l=0;
- }
- }
-
- // Only TrueType CID fonts are supported now
- embeddedFont=new PDFTTFStream(i, fsize);
- embeddedFont.addFilter("flate");
- embeddedFont.addFilter("ascii-85");
- embeddedFont.setData(file, fsize);
- instream.close();
- } catch (Exception e) {}
return (PDFStream) embeddedFont;
}
-
+
public String encoding() {
return encoding;
}
-
+
public String fontName() {
- return fontName;
+ return isEmbeddable() ? namePrefix + fontName : fontName;
}
- public int getAscender() {return ascender;}
- public int getDescender() {return descender;}
- public int getCapHeight() {return capHeight;}
+ public int getAscender() {
+ return ascender;
+ }
+ public int getDescender() {
+ return descender;
+ }
+ public int getCapHeight() {
+ return capHeight;
+ }
public int getAscender(int size) {
return size * ascender;
@@ -201,36 +252,73 @@ public class MultiByteFont extends CIDFont implements FontDescriptor {
}
public int width(int i, int size) {
- return size * width[i];
+ if (isEmbeddable()) {
+ Integer idx = (Integer) usedGlyphsIndex.get(new Integer(i));
+ return size * width[idx.intValue()];
+ } else {
+ return size * width[i];
+ }
}
public int[] getWidths(int size) {
int[] arr = new int[width.length];
- System.arraycopy(width, 0, arr, 0, width.length-1);
- for( int i = 0; i < arr.length; i++) arr[i] *= size;
+ System.arraycopy(width, 0, arr, 0, width.length - 1);
+ for (int i = 0; i < arr.length; i++)
+ arr[i] *= size;
return arr;
}
+ public Integer reMap(Integer i) {
+ if (isEmbeddable()) {
+ Integer ret = (Integer) usedGlyphsIndex.get(i);
+ if (ret == null)
+ ret = i;
+ return ret;
+ } else {
+ return i;
+ }
+
+ }
+
public char mapChar(char c) {
- int idx = (int)c;
+ int idx = (int) c;
int retIdx = 0;
for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
-
- /*
- System.out.println("us: "+bfentries[i].unicodeStart +
- " ue: "+bfentries[i].unicodeEnd+
- " gi: "+bfentries[i].glyphStartIndex);
- */
if (bfentries[i].unicodeStart <= idx &&
- bfentries[i].unicodeEnd >= idx) {
- retIdx=bfentries[i].glyphStartIndex + idx -
- bfentries[i].unicodeStart;
+ bfentries[i].unicodeEnd >= idx) {
+ retIdx = bfentries[i].glyphStartIndex + idx -
+ bfentries[i].unicodeStart;
+ }
+ }
+
+ if (isEmbeddable()) {
+ // Reencode to a new subset font or get
+ // the reencoded value
+ Integer newIdx = (Integer) usedGlyphs.get(new Integer(retIdx));
+ if (newIdx == null) {
+ usedGlyphs.put(new Integer(retIdx),
+ new Integer(usedGlyphsCount));
+ usedGlyphsIndex.put(new Integer(usedGlyphsCount),
+ new Integer(retIdx));
+ retIdx = usedGlyphsCount;
+ //System.out.println(c+"("+(int)c+") = "+retIdx);
+ usedGlyphsCount++;
+ } else {
+ retIdx = newIdx.intValue();
}
}
- //System.out.println("Map: "+ c + " (" + idx + ") = " + retIdx);
- return (char)retIdx;
+ return (char) retIdx;
}
}
+
+
+
+
+
+
+
+
+
diff --git a/src/org/apache/fop/render/pdf/fonts/SingleByteFont.java b/src/org/apache/fop/render/pdf/fonts/SingleByteFont.java
index 413d2e7d3..8a847e2c5 100644
--- a/src/org/apache/fop/render/pdf/fonts/SingleByteFont.java
+++ b/src/org/apache/fop/render/pdf/fonts/SingleByteFont.java
@@ -1,4 +1,9 @@
-
+/* $Id$
+ *
+ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * For details on use and redistribution please refer to the
+ * LICENSE file included with these sources."
+ */
package org.apache.fop.render.pdf.fonts;
@@ -47,7 +52,12 @@ public class SingleByteFont extends Font implements FontDescriptor {
return (useKerning & kerning.isEmpty());
}
- public final java.util.Hashtable getKerningInfo() {return kerning;}
+ public final java.util.Hashtable getKerningInfo() {
+ if (useKerning)
+ return kerning;
+ else
+ return new Hashtable();
+ }
public byte getSubType() {
return subType;