aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/fonts/apps/TTFReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/apache/fop/fonts/apps/TTFReader.java')
-rw-r--r--src/org/apache/fop/fonts/apps/TTFReader.java402
1 files changed, 227 insertions, 175 deletions
diff --git a/src/org/apache/fop/fonts/apps/TTFReader.java b/src/org/apache/fop/fonts/apps/TTFReader.java
index 2aac271d9..239221492 100644
--- a/src/org/apache/fop/fonts/apps/TTFReader.java
+++ b/src/org/apache/fop/fonts/apps/TTFReader.java
@@ -1,40 +1,39 @@
/*
* $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
+ * Copyright (C) 2001-2002 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
package org.apache.fop.fonts.apps;
-import java.io.FileWriter;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.apache.xerces.dom.DocumentImpl;
-import org.apache.xml.serialize.OutputFormat;
-import org.apache.xml.serialize.XMLSerializer;
-import org.apache.fop.fonts.*;
+import java.io.File;
+import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.Iterator;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+//Avalon
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
+//FOP
+import org.apache.fop.fonts.FontFileReader;
+import org.apache.fop.fonts.TTFCmapEntry;
+import org.apache.fop.fonts.TTFFile;
+
/**
* A tool which reads TTF files and generates
* XML font metrics file for use in FOP.
- *
*/
-public class TTFReader {
-
- private boolean invokedStandalone = false;
- private Logger log;
-
- public TTFReader() {}
-
- public void setLogger(Logger l) {
- log = l;
- }
+public class TTFReader extends AbstractLogEnabled {
/**
* Parse commandline arguments. put options in the HashMap and return
@@ -47,7 +46,7 @@ public class TTFReader {
List arguments = new java.util.ArrayList();
for (int i = 0; i < args.length; i++) {
if (args[i].startsWith("-")) {
- if ((i + 1) < args.length &&!args[i + 1].startsWith("-")) {
+ if ((i + 1) < args.length && !args[i + 1].startsWith("-")) {
options.put(args[i], args[i + 1]);
i++;
} else {
@@ -62,26 +61,28 @@ public class TTFReader {
}
- private static final 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");
+ private void displayUsage() {
+ getLogger().info(
+ " java org.apache.fop.fonts.apps.TTFReader [options] fontfile.ttf xmlfile.xml");
+ getLogger().info(" where options can be:");
+ getLogger().info("-enc ansi");
+ getLogger().info(" With this option you create a WinAnsi encoded font.");
+ getLogger().info(" The default is to create a CID keyed font.");
+ getLogger().info(" If you're not going to use characters outside the");
+ getLogger().info(" pdfencoding range (almost the same as iso-8889-1)");
+ getLogger().info(" you can add this option.");
+ getLogger().info("-ttcname <fontname>");
+ getLogger().info(" If you're reading data from a TrueType Collection");
+ getLogger().info(" (.ttc file) you must specify which font from the");
+ getLogger().info(" collection you will read metrics from. If you read");
+ getLogger().info(" from a .ttc file without this option, the fontnames");
+ getLogger().info(" will be listed for you.");
+ getLogger().info(" -fn <fontname>");
+ getLogger().info(" default is to use the fontname in the .ttf file, but");
+ getLogger().info(" you can override that name to make sure that the");
+ getLogger().info(" embedded font is used (if you're embedding fonts)");
+ getLogger().info(" instead of installed fonts when viewing documents ");
+ getLogger().info(" with Acrobat Reader.");
}
@@ -118,66 +119,77 @@ public class TTFReader {
int level = ConsoleLogger.LEVEL_INFO;
if (options.get("-d") != null) {
String lev = (String)options.get("-d");
- if(lev.equals("DEBUG")) {
+ if (lev.equals("DEBUG")) {
level = ConsoleLogger.LEVEL_DEBUG;
- } else if(lev.equals("INFO")) {
+ } else if (lev.equals("INFO")) {
level = ConsoleLogger.LEVEL_INFO;
}
}
Logger log = new ConsoleLogger(level);
TTFReader app = new TTFReader();
- app.setLogger(log);
- app.invokedStandalone = true;
+ app.enableLogging(log);
- log.info("TTF Reader v1.1.2");
+ log.info("TTF Reader v1.1.3");
if (options.get("-enc") != null) {
String enc = (String)options.get("-enc");
- if ("ansi".equals(enc))
+ if ("ansi".equals(enc)) {
isCid = false;
+ }
}
- if (options.get("-ttcname") != null)
+ if (options.get("-ttcname") != null) {
ttcName = (String)options.get("-ttcname");
+ }
- if (options.get("-ef") != null)
+ if (options.get("-ef") != null) {
embFile = (String)options.get("-ef");
+ }
- if (options.get("-er") != null)
+ if (options.get("-er") != null) {
embResource = (String)options.get("-er");
+ }
- if (options.get("-fn") != null)
+ if (options.get("-fn") != null) {
fontName = (String)options.get("-fn");
+ }
- if (options.get("-cn") != null)
+ 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)
- log.info("Creating CID encoded metrics");
- else
- log.info("Creating WinAnsi encoded metrics");
-
- if (doc != null) {
- app.writeFontXML(doc, arguments[1]);
+ || options.get("-help") != null || options.get("--help") != null) {
+ app.displayUsage();
+ } else {
+ try {
+ 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) {
+ log.info("Creating CID encoded metrics");
+ } else {
+ log.info("Creating WinAnsi encoded metrics");
+ }
+
+ if (doc != null) {
+ app.writeFontXML(doc, arguments[1]);
+ }
+
+ if (ttf.isEmbeddable()) {
+ log.info("This font contains no embedding license restrictions");
+ } else {
+ log.info("** Note: This font contains license retrictions for\n"
+ + " embedding. This font shouldn't be embedded.");
+ }
}
-
- if (ttf.isEmbeddable())
- log.info("This font contains no embedding license restrictions");
- else
- log.info("** Note: This font contains license retrictions for\n"
- + " embedding. This font shouldn't be embedded.");
-
+ } catch (Exception e) {
+ log.error("Error while building XML font metrics file", e);
+ System.exit(-1);
}
}
}
@@ -185,22 +197,19 @@ public class TTFReader {
/**
* Read a TTF file and returns it as an object.
*
- * @param filename The filename of the PFM file.
- * @return The TTF as an object.
+ * @param fileName The filename of the TTF file.
+ * @param fontName The name of the font
+ * @return The TTF as an object, null if the font is incompatible.
+ * @throws IOException In case of an I/O problem
*/
- public TTFFile loadTTF(String fileName, String fontName) {
+ public TTFFile loadTTF(String fileName, String fontName) throws IOException {
TTFFile ttfFile = new TTFFile();
- ttfFile.enableLogging(log);
- try {
- log.info("Reading " + fileName + "...");
+ setupLogger(ttfFile);
+ getLogger().info("Reading " + fileName + "...");
- FontFileReader reader = new FontFileReader(fileName);
- boolean supported = ttfFile.readFont(reader, fontName);
- if(!supported) {
- return null;
- }
- } catch (Exception e) {
- e.printStackTrace();
+ FontFileReader reader = new FontFileReader(fileName);
+ boolean supported = ttfFile.readFont(reader, fontName);
+ if (!supported) {
return null;
}
return ttfFile;
@@ -214,39 +223,52 @@ public class TTFReader {
* @param target The target filename for the XML file.
*/
public void writeFontXML(org.w3c.dom.Document doc, String target) {
- log.info("Writing xml font file " + target + "...");
+ getLogger().info("Writing xml font file " + target + "...");
try {
- OutputFormat format = new OutputFormat(doc); // Serialize DOM
- FileWriter out = new FileWriter(target); // Writer will be a String
- XMLSerializer serial = new XMLSerializer(out, format);
- serial.asDOMSerializer(); // As a DOM Serializer
-
- serial.serialize(doc.getDocumentElement());
- out.close();
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ transformer.transform(
+ new javax.xml.transform.dom.DOMSource(doc),
+ new javax.xml.transform.stream.StreamResult(new File(target)));
} catch (Exception e) {
- e.printStackTrace();
+ throw new CascadingRuntimeException(
+ "Error while serializing XML font metrics file", e);
}
}
/**
* 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.
+ * @param ttf The PFM file to generate the font metrics from.
+ * @param fontName Name of the font
+ * @param className Class name for the font
+ * @param resource path to the font as embedded resource
+ * @param file path to the font as file
+ * @param isCid True if the font is CID encoded
+ * @param ttcName Name of the TrueType Collection
+ * @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) {
- log.info("Creating xml font file...");
+ getLogger().info("Creating xml font file...");
- Document doc = new DocumentImpl();
+ Document doc;
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ doc = factory.newDocumentBuilder().newDocument();
+ } catch (javax.xml.parsers.ParserConfigurationException e) {
+ getLogger().error("Can't create DOM implementation", e);
+ return null;
+ }
Element root = doc.createElement("font-metrics");
doc.appendChild(root);
- if (isCid)
+ if (isCid) {
root.setAttribute("type", "TYPE0");
- else
+ } else {
root.setAttribute("type", "TRUETYPE");
+ }
Element el = doc.createElement("font-name");
root.appendChild(el);
@@ -257,17 +279,20 @@ public class TTFReader {
String s = stripWhiteSpace(ttf.getPostscriptName());
- if (fontName != null)
+ if (fontName != null) {
el.appendChild(doc.createTextNode(stripWhiteSpace(fontName)));
- else
+ } else {
el.appendChild(doc.createTextNode(s));
+ }
el = doc.createElement("embed");
root.appendChild(el);
- if (file != null && ttf.isEmbeddable())
+ if (file != null && ttf.isEmbeddable()) {
el.setAttribute("file", file);
- if (resource != null && ttf.isEmbeddable())
+ }
+ if (resource != null && ttf.isEmbeddable()) {
el.setAttribute("class", resource);
+ }
el = doc.createElement("cap-height");
root.appendChild(el);
@@ -288,10 +313,8 @@ public class TTFReader {
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++) {
+ final String[] names = {"left", "bottom", "right", "top"};
+ for (int i = 0; i < names.length; i++) {
el = doc.createElement(names[i]);
bbox.appendChild(el);
el.appendChild(doc.createTextNode(String.valueOf(bb[i])));
@@ -322,91 +345,117 @@ public class TTFReader {
if (isCid) {
el.appendChild(doc.createTextNode("TYPE0"));
- Element mel = doc.createElement("multibyte-extras");
- root.appendChild(mel);
-
- el = doc.createElement("cid-type");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("CIDFontType2"));
-
- el = doc.createElement("default-width");
- mel.appendChild(el);
- el.appendChild(doc.createTextNode("0"));
-
- el = doc.createElement("bfranges");
- mel.appendChild(el);
- for (Iterator e = ttf.getCMaps().listIterator();
- e.hasNext(); ) {
- TTFCmapEntry ce = (TTFCmapEntry)e.next();
- Element el2 = doc.createElement("bf");
- el.appendChild(el2);
- el2.setAttribute("us", String.valueOf(ce.getUnicodeStart()));
- el2.setAttribute("ue", String.valueOf(ce.getUnicodeEnd()));
- el2.setAttribute("gi", String.valueOf(ce.getGlyphStartIndex()));
- }
-
- el = doc.createElement("cid-widths");
- el.setAttribute("start-index", "0");
- mel.appendChild(el);
-
- int[] wx = ttf.getWidths();
- for (int i = 0; i < wx.length; i++) {
- Element wxel = doc.createElement("wx");
- wxel.setAttribute("w", String.valueOf(wx[i]));
- el.appendChild(wxel);
- }
+ generateDOM4MultiByteExtras(root, ttf, isCid);
} else {
// Fill in extras for singlebyte fonts
el.appendChild(doc.createTextNode("TRUETYPE"));
- Element sel = doc.createElement("singlebyte-extras");
- root.appendChild(sel);
+ generateDOM4SingleByteExtras(root, ttf, isCid);
+ }
- el = doc.createElement("encoding");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(ttf.getCharSetName()));
+ generateDOM4Kerning(root, ttf, isCid);
- el = doc.createElement("first-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getFirstChar())));
+ return doc;
+ }
- el = doc.createElement("last-char");
- sel.appendChild(el);
- el.appendChild(doc.createTextNode(String.valueOf(ttf.getLastChar())));
+ private void generateDOM4MultiByteExtras(Element parent, TTFFile ttf, boolean isCid) {
+ Element el;
+ Document doc = parent.getOwnerDocument();
+
+ Element mel = doc.createElement("multibyte-extras");
+ parent.appendChild(mel);
+
+ el = doc.createElement("cid-type");
+ mel.appendChild(el);
+ el.appendChild(doc.createTextNode("CIDFontType2"));
+
+ el = doc.createElement("default-width");
+ mel.appendChild(el);
+ el.appendChild(doc.createTextNode("0"));
+
+ el = doc.createElement("bfranges");
+ mel.appendChild(el);
+ Iterator e = ttf.getCMaps().listIterator();
+ while (e.hasNext()) {
+ TTFCmapEntry ce = (TTFCmapEntry)e.next();
+ Element el2 = doc.createElement("bf");
+ el.appendChild(el2);
+ el2.setAttribute("us", String.valueOf(ce.getUnicodeStart()));
+ el2.setAttribute("ue", String.valueOf(ce.getUnicodeEnd()));
+ el2.setAttribute("gi", String.valueOf(ce.getGlyphStartIndex()));
+ }
- Element widths = doc.createElement("widths");
- sel.appendChild(widths);
+ el = doc.createElement("cid-widths");
+ el.setAttribute("start-index", "0");
+ mel.appendChild(el);
- for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); i++) {
- el = doc.createElement("char");
- widths.appendChild(el);
- el.setAttribute("idx", String.valueOf(i));
- el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i)));
- }
+ int[] wx = ttf.getWidths();
+ for (int i = 0; i < wx.length; i++) {
+ Element wxel = doc.createElement("wx");
+ wxel.setAttribute("w", String.valueOf(wx[i]));
+ el.appendChild(wxel);
}
+ }
+
+ private void generateDOM4SingleByteExtras(Element parent, TTFFile ttf, boolean isCid) {
+ Element el;
+ Document doc = parent.getOwnerDocument();
+
+ Element sel = doc.createElement("singlebyte-extras");
+ parent.appendChild(sel);
+
+ el = doc.createElement("encoding");
+ sel.appendChild(el);
+ el.appendChild(doc.createTextNode(ttf.getCharSetName()));
+
+ el = doc.createElement("first-char");
+ sel.appendChild(el);
+ el.appendChild(doc.createTextNode(String.valueOf(ttf.getFirstChar())));
+
+ el = doc.createElement("last-char");
+ sel.appendChild(el);
+ el.appendChild(doc.createTextNode(String.valueOf(ttf.getLastChar())));
+ Element widths = doc.createElement("widths");
+ sel.appendChild(widths);
+
+ for (short i = ttf.getFirstChar(); i <= ttf.getLastChar(); i++) {
+ el = doc.createElement("char");
+ widths.appendChild(el);
+ el.setAttribute("idx", String.valueOf(i));
+ el.setAttribute("wdt", String.valueOf(ttf.getCharWidth(i)));
+ }
+ }
+
+ private void generateDOM4Kerning(Element parent, TTFFile ttf, boolean isCid) {
+ Element el;
+ Document doc = parent.getOwnerDocument();
+
// Get kerning
Iterator enum;
- if (isCid)
+ if (isCid) {
enum = ttf.getKerning().keySet().iterator();
- else
+ } else {
enum = ttf.getAnsiKerning().keySet().iterator();
+ }
while (enum.hasNext()) {
Integer kpx1 = (Integer)enum.next();
el = doc.createElement("kerning");
el.setAttribute("kpx1", kpx1.toString());
- root.appendChild(el);
+ parent.appendChild(el);
Element el2 = null;
Map h2;
- if (isCid)
+ if (isCid) {
h2 = (Map)ttf.getKerning().get(kpx1);
- else
+ } else {
h2 = (Map)ttf.getAnsiKerning().get(kpx1);
+ }
- for (Iterator enum2 = h2.keySet().iterator(); enum2.hasNext(); ) {
+ Iterator enum2 = h2.keySet().iterator();
+ while (enum2.hasNext()) {
Integer kpx2 = (Integer)enum2.next();
if (isCid || kpx2.intValue() < 256) {
el2 = doc.createElement("pair");
@@ -417,8 +466,6 @@ public class TTFReader {
}
}
}
-
- return doc;
}
@@ -426,10 +473,14 @@ public class TTFReader {
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')
+ for (int i = 0; i < ch.length; i++) {
+ if (ch[i] != ' '
+ && ch[i] != '\r'
+ && ch[i] != '\n'
+ && ch[i] != '\t') {
stb.append(ch[i]);
+ }
+ }
return stb.toString();
}
@@ -438,10 +489,11 @@ public class TTFReader {
StringBuffer esc = new StringBuffer();
for (int i = 0; i < str.length(); i++) {
- if (str.charAt(i) == '\\')
+ if (str.charAt(i) == '\\') {
esc.append("\\\\");
- else
+ } else {
esc.append(str.charAt(i));
+ }
}
return esc.toString();