You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by je...@apache.org on 2002/12/02 15:27:58 UTC

cvs commit: xml-fop/src/org/apache/fop/fonts/apps PFMReader.java TTFReader.java

jeremias    2002/12/02 06:27:58

  Modified:    src/org/apache/fop/fonts Glyphs.java TTFFile.java
               src/org/apache/fop/fonts/apps PFMReader.java TTFReader.java
  Removed:     src/org/apache/fop/fonts PFMFile.java PFMInputStream.java
  Log:
  Moved PFM classes to type1 subpackage
  Style and javadocs
  Remove dependencies on Xerces (using JAXP instead)
  PFMReader uses Avalon Logging
  Setting logger now following Avalon lifecycle
  
  Revision  Changes    Path
  1.9       +45 -29    xml-fop/src/org/apache/fop/fonts/Glyphs.java
  
  Index: Glyphs.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fonts/Glyphs.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Glyphs.java	29 Nov 2002 23:18:54 -0000	1.8
  +++ Glyphs.java	2 Dec 2002 14:27:57 -0000	1.9
  @@ -1,18 +1,28 @@
   /*
    * $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;
   
  +/**
  + * This class provides a number of constants for glyph management.
  + */
   public class Glyphs {
  -    static String notdef = ".notdef";
   
  -    static String mac_glyph_names[] = {
  +    /**
  +     * Glyph name for the "notdef" glyph
  +     */
  +    public static final String NOTDEF = ".notdef";
  +
  +    /**
  +     * Glyph names for Mac encoding
  +     */
  +    public static final String MAC_GLYPH_NAMES[] = {
           /* 0x00 */
  -        notdef, ".null", "CR", "space", "exclam", "quotedbl", "numbersign",
  +        NOTDEF, ".null", "CR", "space", "exclam", "quotedbl", "numbersign",
                   "dollar", "percent", "ampersand", "quotesingle", "parenleft",
                   "parenright", "asterisk", "plus", "comma", /* 0x10 */
           "hyphen", "period", "slash", "zero", "one", "two", "three", "four",
  @@ -68,9 +78,12 @@
           "ccaron", "dmacron"
       };
   
  -    static String[] tex8r = {
  +    /**
  +     * Glyph names for tex8r encoding
  +     */
  +    public static final String[] TEX8R_GLYPH_NAMES = {
           // 0x00
  -        ".notdef", "dotaccent", "fi", "fl", "fraction", "hungarumlaut",
  +        NOTDEF, "dotaccent", "fi", "fl", "fraction", "hungarumlaut",
                      "Lslash", "lslash", "ogonek", "ring", ".notdef", "breve",
                      "minus", ".notdef", "Zcaron", "zcaron", // 0x10
           "caron", "dotlessi", "dotlessj", "ff", "ffi", "ffl", ".notdef",
  @@ -127,7 +140,7 @@
       /**
        * The characters in WinAnsiEncoding
        */
  -    public static char[] winAnsiEncoding = {
  +    public static final char[] WINANSI_ENCODING = {
           // not used until char 32
           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
              0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
  @@ -143,7 +156,8 @@
                'n', 'o', // 0x70
           'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\u007b', '\u007c', '\u007d',
                '\u007e', '\u2022', // 0x80
  -        '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022',
  +        '\u20ac', '\u2022', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020',
  +             '\u2021', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\u2022',
                '\u017d', '\u2022', // 0x90
           '\u2022', '\u2018',                             // quoteleft
           '\u2019',                                       // quoteright
  @@ -158,8 +172,8 @@
                '\u00a6', '\u00a7', '\u00a8', '\u00a9', '\u00aa', '\u00ab',
                '\u00ac', '\u00ad',  '\u00ae', '\u00af', // 0xb0
           '\u00b0', '\u00b1', '\u00b2', '\u00b3', '\u00b4',
  -             '\u00b5',                                  // This is hand-coded, the rest is assumption
  -        '\u00b6',                                       // and *might* not be correct...
  +             '\u00b5',                      // This is hand-coded, the rest is assumption
  +        '\u00b6',                           // and *might* not be correct...
           '\u00b7', '\u00b8', '\u00b9', '\u00ba', '\u00bb', '\u00bc', '\u00bd',
                '\u00be', '\u00bf', // 0xc0
           '\u00c0', '\u00c1', '\u00c2', '\u00c3', '\u00c4', '\u00c5', // Aring
  @@ -179,8 +193,11 @@
                '\u00fc', '\u00fd', '\u00fe', '\u00ff'
       };
   
  -    static String[] unicode_glyphs = {
  -              "\u0041", "A",
  +    /**
  +     * List of unicode glyphs
  +     */
  +    public static final String[] UNICODE_GLYPHS = {
  +        "\u0041", "A",
           "\u00C6", "AE",
           "\u01FC", "AEacute",
           "\uF7E6", "AEsmall",
  @@ -1233,39 +1250,38 @@
           "\uF730", "zerooldstyle",
           "\u2070", "zerosuperior",
           "\u03B6", "zeta"
  -
       };
   
       /**
        * Return the glyphname from a string,
        * eg, glyphToString("\\") returns "backslash"
  +     *
  +     * @param name glyph to evaluate
  +     * @return the name of the glyph
        */
  -    public static String glyphToString(String name) {
  -        String ret = "";
  -        int i = unicode_glyphs.length;
  -        for (int j = 0; j < i; j += 2) {
  -            if (unicode_glyphs[j + 1].equals(name)) {
  -                ret = unicode_glyphs[j];
  -                j = i;
  +    public static final String glyphToString(String name) {
  +        for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) {
  +            if (UNICODE_GLYPHS[i + 1].equals(name)) {
  +                return UNICODE_GLYPHS[i];
               }
           }
  -        return ret;
  +        return "";
       }
   
       /**
        * Return the string representation of a glyphname,
        * eg stringToGlyph("backslash") returns "\\"
  +     *
  +     * @param name name of the glyph
  +     * @return the string representation
        */
       public static String stringToGlyph(String name) {
  -        String ret = "";
  -        int i = unicode_glyphs.length;
  -        for (int j = 0; j < i; j += 2) {
  -            if (unicode_glyphs[j].equals(name)) {
  -                ret = unicode_glyphs[j + 1];
  -                j = i;
  +        for (int i = 0; i < UNICODE_GLYPHS.length; i += 2) {
  +            if (UNICODE_GLYPHS[i].equals(name)) {
  +                return UNICODE_GLYPHS[i + 1];
               }
           }
  -        return ret;
  +        return "";
       }
   
   }
  
  
  
  1.13      +8 -8      xml-fop/src/org/apache/fop/fonts/TTFFile.java
  
  Index: TTFFile.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fonts/TTFFile.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- TTFFile.java	29 Nov 2002 23:18:54 -0000	1.12
  +++ TTFFile.java	2 Dec 2002 14:27:57 -0000	1.13
  @@ -351,9 +351,9 @@
           // Can't just index the winAnsiEncoding when inserting widths
           // same char (eg bullet) is repeated more than one place
           ansiIndex = new java.util.HashMap();
  -        for (int i = 32; i < Glyphs.winAnsiEncoding.length; i++) {
  +        for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
               Integer ansi = new Integer(i);
  -            Integer uni = new Integer((int)Glyphs.winAnsiEncoding[i]);
  +            Integer uni = new Integer((int)Glyphs.WINANSI_ENCODING[i]);
   
               List v = (List)ansiIndex.get(uni);
               if (v == null) {
  @@ -761,8 +761,8 @@
           switch (postFormat) {
           case 0x00010000:
               getLogger().debug("Postscript format 1");
  -            for (i = 0; i < Glyphs.mac_glyph_names.length; i++) {
  -                mtxTab[i].setName(Glyphs.mac_glyph_names[i]);
  +            for (i = 0; i < Glyphs.MAC_GLYPH_NAMES.length; i++) {
  +                mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[i]);
               }
               break;
           case 0x00020000:
  @@ -791,7 +791,7 @@
   
               for (i = 0; i < l; i++) {
                   if (mtxTab[i].getIndex() < NMACGLYPHS) {
  -                    mtxTab[i].setName(Glyphs.mac_glyph_names[mtxTab[i].getIndex()]);
  +                    mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[mtxTab[i].getIndex()]);
                   } else {
                       k = mtxTab[i].getIndex() - NMACGLYPHS;
   
  @@ -1150,8 +1150,8 @@
        */
       private Integer[] unicodeToWinAnsi(int unicode) {
           List ret = new java.util.ArrayList();
  -        for (int i = 32; i < Glyphs.winAnsiEncoding.length; i++) {
  -            if (unicode == Glyphs.winAnsiEncoding[i]) {
  +        for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
  +            if (unicode == Glyphs.WINANSI_ENCODING[i]) {
                   ret.add(new Integer(i));
               }
           }
  
  
  
  1.10      +115 -100  xml-fop/src/org/apache/fop/fonts/apps/PFMReader.java
  
  Index: PFMReader.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fonts/apps/PFMReader.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- PFMReader.java	25 Oct 2002 09:29:44 -0000	1.9
  +++ PFMReader.java	2 Dec 2002 14:27:58 -0000	1.10
  @@ -1,33 +1,40 @@
   /*
    * $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.*;
  -import org.w3c.dom.*;
  -import org.apache.xerces.dom.*;
  -import org.apache.xml.serialize.*;
  -import org.apache.xalan.xslt.*;
  -import org.apache.fop.fonts.*;
  -import java.util.HashMap;
  -import java.util.ArrayList;
  +import java.io.File;
  +import java.io.InputStream;
  +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.Logger;
  +import org.apache.avalon.framework.logger.ConsoleLogger;
  +
  +//FOP
  +import org.apache.fop.fonts.type1.PFMFile;
   
   /**
    * A tool which reads PFM files from Adobe Type 1 fonts and creates
    * XML font metrics file for use in FOP.
  - *
  - * @author  jeremias.maerki@outline.ch
    */
  -public class PFMReader {
  -    private boolean invokedStandalone = false;
  -
  -    public PFMReader() { }
  -
  +public class PFMReader extends AbstractLogEnabled {
  +    
       /**
        * Parse commandline arguments. put options in the HashMap and return
        * arguments in the String array
  @@ -35,8 +42,8 @@
        * 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(HashMap options, String[] args) {
  -        ArrayList arguments = new ArrayList();
  +    private static String[] parseArguments(Map options, String[] args) {
  +        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("-")) {
  @@ -50,17 +57,19 @@
               }
           }
   
  -        return (String[])arguments.toArray(new String[0]);
  +        return (String[])arguments.toArray(new String[arguments.size()]);
       }
   
  -    private static final 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");
  +    private void displayUsage() {
  +        getLogger().info(
  +            " java org.apache.fop.fonts.apps.PFMReader [options] metricfile.pfm xmlfile.xml");
  +        getLogger().info(" where options can be:");
  +        getLogger().info(" -fn <fontname>");
  +        getLogger().info("     default is to use the fontname in the .pfm 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.");
       }
   
   
  @@ -89,14 +98,20 @@
           String className = null;
           String fontName = null;
   
  -        HashMap options = new HashMap();
  +        Map options = new java.util.HashMap();
           String[] arguments = parseArguments(options, args);
   
           PFMReader app = new PFMReader();
  -        app.invokedStandalone = true;
  +        Logger log;
  +        if (options.get("-d") != null) {
  +            log = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);
  +        } else {
  +            log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
  +        }
  +        app.enableLogging(log);
   
  -        System.out.println("PFM Reader v1.1");
  -        System.out.println();
  +        log.info("PFM Reader v1.1a");
  +        log.info("");
   
           if (options.get("-ef") != null) {
               embFile = (String)options.get("-ef");
  @@ -116,16 +131,21 @@
   
           if (arguments.length != 2 || options.get("-h") != null
               || options.get("-help") != null || options.get("--help") != null) {
  -            displayUsage();
  +            app.displayUsage();
           } else {
  -            PFMFile pfm = app.loadPFM(arguments[0]);
  -            if (pfm != null) {
  -                app.preview(pfm);
  -
  -                org.w3c.dom.Document doc = app.constructFontXML(pfm,
  -                        fontName, className, embResource, embFile);
  -
  -                app.writeFontXML(doc, arguments[1]);
  +            try {
  +                PFMFile pfm = app.loadPFM(arguments[0]);
  +                if (pfm != null) {
  +                    app.preview(pfm);
  +    
  +                    Document doc = app.constructFontXML(pfm,
  +                            fontName, className, embResource, embFile);
  +    
  +                    app.writeFontXML(doc, arguments[1]);
  +                }
  +            } catch (Exception e) {
  +                log.error("Error while building XML font metrics file", e);
  +                System.exit(-1);
               }
           }
       }
  @@ -136,18 +156,19 @@
        *
        * @param   filename The filename of the PFM file.
        * @return  The PFM as an object.
  +     * @throws IOException In case of an I/O problem
        */
  -    public PFMFile loadPFM(String filename) {
  +    public PFMFile loadPFM(String filename) throws IOException {
  +        getLogger().info("Reading " + filename + "...");
  +        getLogger().info("");
  +        InputStream in = new java.io.FileInputStream(filename);
           try {
  -            System.out.println("Reading " + filename + "...");
  -            System.out.println();
  -            FileInputStream in = new FileInputStream(filename);
               PFMFile pfm = new PFMFile();
  +            setupLogger(pfm);
               pfm.load(in);
               return pfm;
  -        } catch (Exception e) {
  -            e.printStackTrace();
  -            return null;
  +        } finally {
  +            in.close();
           }
       }
   
  @@ -157,34 +178,19 @@
        * @param   pfm The PFM file to preview.
        */
       public void preview(PFMFile pfm) {
  -        PrintStream out = System.out;
  -
  -        out.print("Font: ");
  -        out.println(pfm.getWindowsName());
  -        out.print("Name: ");
  -        out.println(pfm.getPostscriptName());
  -        out.print("CharSet: ");
  -        out.println(pfm.getCharSetName());
  -        out.print("CapHeight: ");
  -        out.println(pfm.getCapHeight());
  -        out.print("XHeight: ");
  -        out.println(pfm.getXHeight());
  -        out.print("LowerCaseAscent: ");
  -        out.println(pfm.getLowerCaseAscent());
  -        out.print("LowerCaseDescent: ");
  -        out.println(pfm.getLowerCaseDescent());
  -        out.print("Having widths for ");
  -        out.print(pfm.getLastChar() - pfm.getFirstChar());
  -        out.print(" characters (");
  -        out.print(pfm.getFirstChar());
  -        out.print("-");
  -        out.print(pfm.getLastChar());
  -        out.println(").");
  -        out.print("for example: Char ");
  -        out.print(pfm.getFirstChar());
  -        out.print(" has a width of ");
  -        out.println(pfm.getCharWidth(pfm.getFirstChar()));
  -        out.println();
  +        getLogger().info("Font: " + pfm.getWindowsName());
  +        getLogger().info("Name: " + pfm.getPostscriptName());
  +        getLogger().info("CharSet: " + pfm.getCharSetName());
  +        getLogger().info("CapHeight: " + pfm.getCapHeight());
  +        getLogger().info("XHeight: " + pfm.getXHeight());
  +        getLogger().info("LowerCaseAscent: " + pfm.getLowerCaseAscent());
  +        getLogger().info("LowerCaseDescent: " + pfm.getLowerCaseDescent());
  +        getLogger().info("Having widths for " + (pfm.getLastChar() - pfm.getFirstChar()) 
  +                    + " characters (" + pfm.getFirstChar()
  +                    + "-" + pfm.getLastChar() + ").");
  +        getLogger().info("for example: Char " + pfm.getFirstChar()
  +                    + " has a width of " + pfm.getCharWidth(pfm.getFirstChar()));
  +        getLogger().info("");
       }
   
       /**
  @@ -194,34 +200,43 @@
        * @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();
  +        getLogger().info("Writing xml font file " + target + "...");
  +        getLogger().info("");
   
           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 metric file", e);
           }
       }
   
       /**
        * Generates the font metrics file from the PFM file.
        *
  -     * @param   pfm The PFM file to generate the font metrics from.
  +     * @param pfm 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
        * @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();
  +        getLogger().info("Creating xml font file...");
  +        getLogger().info("");
   
  -        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);
           root.setAttribute("type", "TYPE1");
  @@ -275,10 +290,8 @@
           Element bbox = doc.createElement("bbox");
           root.appendChild(bbox);
           int[] bb = pfm.getFontBBox();
  -        String[] names = {
  -            "left", "bottom", "right", "top"
  -        };
  -        for (int i = 0; i < 4; i++) {
  +        final String[] names = {"left", "bottom", "right", "top"};
  +        for (int i = 0; i < names.length; i++) {
               el = doc.createElement(names[i]);
               bbox.appendChild(el);
               value = new Integer(bb[i]);
  @@ -323,16 +336,17 @@
   
   
           // Get kerning
  -        for (Iterator enum = pfm.getKerning().keySet().iterator();
  -                enum.hasNext(); ) {
  +        Iterator enum = pfm.getKerning().keySet().iterator();
  +        while (enum.hasNext()) {
               Integer kpx1 = (Integer)enum.next();
               el = doc.createElement("kerning");
               el.setAttribute("kpx1", kpx1.toString());
               root.appendChild(el);
               Element el2 = null;
   
  -            HashMap h2 = (HashMap)pfm.getKerning().get(kpx1);
  -            for (Iterator enum2 = h2.keySet().iterator(); enum2.hasNext(); ) {
  +            Map h2 = (Map)pfm.getKerning().get(kpx1);
  +            Iterator enum2 = h2.keySet().iterator();
  +            while (enum2.hasNext()) {
                   Integer kpx2 = (Integer)enum2.next();
                   el2 = doc.createElement("pair");
                   el2.setAttribute("kpx2", kpx2.toString());
  @@ -349,10 +363,11 @@
           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();
  
  
  
  1.10      +232 -180  xml-fop/src/org/apache/fop/fonts/apps/TTFReader.java
  
  Index: TTFReader.java
  ===================================================================
  RCS file: /home/cvs/xml-fop/src/org/apache/fop/fonts/apps/TTFReader.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TTFReader.java	22 Nov 2002 15:38:47 -0000	1.9
  +++ TTFReader.java	2 Dec 2002 14:27:58 -0000	1.10
  @@ -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 @@
           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 @@
       }
   
   
  -    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 @@
           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 @@
       /**
        * 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 @@
        * @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 @@
   
           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 @@
           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 @@
           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()));
  -
  -            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)));
  -            }
  +        generateDOM4Kerning(root, ttf, isCid);
  +
  +        return doc;
  +    }
  +
  +    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()));
  +        }
  +
  +        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);
           }
  +    }
   
  +    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 @@
                   }
               }
           }
  -
  -        return doc;
       }
   
   
  @@ -426,10 +473,14 @@
           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 @@
           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();
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: fop-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: fop-cvs-help@xml.apache.org