]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added support for relative font config URLs (metrics-url and embed-url). These URLs...
authorManuel Mall <manuel@apache.org>
Sat, 7 Jan 2006 13:15:53 +0000 (13:15 +0000)
committerManuel Mall <manuel@apache.org>
Sat, 7 Jan 2006 13:15:53 +0000 (13:15 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@366718 13f79535-47bb-0310-9956-ffa450edef68

22 files changed:
build.xml
src/documentation/content/xdocs/trunk/configuration.xml
src/documentation/content/xdocs/trunk/embedding.xml
src/documentation/content/xdocs/trunk/fonts.xml
src/java-1.4/org/apache/fop/image/JpegImageIOImage.java [new file with mode: 0644]
src/java/org/apache/fop/apps/FOUserAgent.java
src/java/org/apache/fop/fonts/CustomFont.java
src/java/org/apache/fop/fonts/FontReader.java
src/java/org/apache/fop/fonts/FontSetup.java
src/java/org/apache/fop/fonts/LazyFont.java
src/java/org/apache/fop/image/ImageFactory.java
src/java/org/apache/fop/pdf/PDFFactory.java
src/java/org/apache/fop/render/PrintRenderer.java
src/java/org/apache/fop/render/ps/AbstractPSDocumentGraphics2D.java
src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
src/java/org/apache/fop/render/ps/PSFontUtils.java
src/java/org/apache/fop/render/ps/PSTranscoder.java
src/java/org/apache/fop/render/rtf/RTFHandler.java
src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
src/java/org/apache/fop/svg/PDFGraphics2D.java
src/sandbox/org/apache/fop/render/mif/MIFHandler.java
status.xml

index 6f22ae3c9268ff2fe02f935301f66ffb41469a85..d15aef2e64d75e3489da161e1b08398380a8cadd 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -142,8 +142,8 @@ list of possible build targets.
   <property name="Name" value="Apache FOP"/>
   <property name="name" value="fop"/>
   <property name="NAME" value="FOP"/>
-  <property name="version" value="0.90svn"/>
-  <property name="year" value="1999-2005"/>
+  <property name="version" value="0.91svn"/>
+  <property name="year" value="1999-2006"/>
 
   <property name="javac.debug" value="on"/>
   <property name="javac.optimize" value="off"/>
index 0b845bcf91ccc3571570217de1909ccc073fb5e4..258b5ac04f2616229c8489e68541fc99f3820d56 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" standalone="no"?>
 <!--
-  Copyright 1999-2005 The Apache Software Foundation
+  Copyright 1999-2006 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
         <td>URL</td>
         <td>Specifies the base URL based on which relative URL will be resolved.</td>
       </tr>
+      <tr>
+        <td>font-base</td>
+        <td>URL</td>
+        <td>Specifies the base URL based on which relative font URLs will be resolved.
+        If not specified defaults to the base URL above.
+        </td>
+      </tr>
       <tr>
         <td>source-resolution</td>
         <td>Integer, dpi</td>
   <!-- Base URL for resolving relative URLs -->
   <base>./</base>
 
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+
   <!-- Source resolution in dpi (dots/pixels per inch) for determining the size of pixels in SVG and bitmap images, default: 72dpi -->
   <source-resolution>72</source-resolution>
   <!-- Target resolution in dpi (dots/pixels per inch) for specifying the target resolution for generated bitmaps, default: 72dpi -->
index 9833faa0f99e1b0f72c6c0c8a789d27a1d0c63e5..3dd1115abd62777062f91b84522b0923bc58579b 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" standalone="no"?>
 <!--
-  Copyright 1999-2005 The Apache Software Foundation
+  Copyright 1999-2006 The Apache Software Foundation
 
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
@@ -272,6 +272,12 @@ Fop fop = new Fop(MimeConstants.MIME_POSTSCRIPT, userAgent);]]></source>
         </p>
         <source>userAgent.setBaseURL("file:///C:/Temp/");</source>
       </li>
+      <li>
+        <p>
+          The <strong>font base URL</strong> to use when resolving relative URLs for fonts. Example:
+        </p>
+        <source>userAgent.setFontBaseURL("file:///C:/Temp/fonts");</source>
+      </li>
       <li>
         <p>
           Disable <strong>strict validation</strong>. When disabled FOP is less strict about the rules established by the XSL-FO specification. Example:
index 13478a5c1e6b3330dfc2f38cc2bd7ac829e6b057..683fa355be6ec46e29427ebf55dbca457b342422 100644 (file)
@@ -241,9 +241,8 @@ It will display all of the font names and exit with an Exception.</p>
         <ul>
           <li>
             URLs are used to access the font metric and font files.
-            <!--Relative URLs are resolved relative to the fontBaseDir property (or baseDir) if available.-->
+            Relative URLs are resolved relative to the font-base property (or base) if available.
             See <a href="configuration.html">FOP: Configuration</a> for more information.
-            <note>Relative font URLs are currently not possible. You need to specify absolute URLs. Patches are welcome! :-)</note>
           </li>
           <li>The "kerning" and "embed-url" attributes are optional. Kerning is currently not used at all. If embedding is off, the output will position the text correctly (from the metrics file), but it will not be displayed or printed correctly unless the viewer has the applicable font available to their local system.</li>
           <li>When setting the embed-url attribute for Type 1 fonts, be sure to specify the PFB (actual font data), not PFM (font metrics) file that you used to generate the XML font metrics file.</li>
diff --git a/src/java-1.4/org/apache/fop/image/JpegImageIOImage.java b/src/java-1.4/org/apache/fop/image/JpegImageIOImage.java
new file mode 100644 (file)
index 0000000..5108387
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.image;
+
+// AWT
+import java.awt.Color;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.BufferedImage;
+
+// ImageIO
+import javax.imageio.ImageIO;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * FopImage object using ImageIO.
+ * Special class to allow the use of JpegImage for those
+ * renderers which can embed Jpeg directly but for renderers
+ * which require the decoded data this class delivers it.
+ * @see AbstractFopImage
+ * @see JpegImage
+ */
+public class JpegImageIOImage extends JpegImage {
+
+    /**
+     * Creates a new JpegImageIOImage.
+     * @param info the image info from the ImageReader
+     */
+    public JpegImageIOImage(FopImage.ImageInfo info) {
+        super(info);
+    }
+
+    /**
+     * @see org.apache.fop.image.AbstractFopImage#loadDimensions()
+     */
+    protected boolean loadDimensions() {
+        if (this.bitmaps == null) {
+            return loadBitmap();
+        }
+        return true;
+    }
+    
+    /** @see org.apache.fop.image.AbstractFopImage#loadBitmap() */
+    protected boolean loadBitmap() {
+        try {
+            inputStream.reset();
+            BufferedImage imageData = ImageIO.read(inputStream);
+
+            this.height = imageData.getHeight();
+            this.width = imageData.getWidth();
+
+            ColorModel cm = imageData.getColorModel();
+            this.bitsPerPixel = cm.getComponentSize(0); //only use first, we assume all are equal
+            this.colorSpace = cm.getColorSpace();
+
+            int[] tmpMap = imageData.getRGB(0, 0, this.width,
+                                            this.height, null, 0, this.width);
+
+            if (cm.hasAlpha()) {
+                // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT
+                int transparencyType = cm.getTransparency();
+                
+                if (transparencyType == java.awt.Transparency.OPAQUE) {
+                    this.isTransparent = false;
+                } else if (transparencyType == java.awt.Transparency.BITMASK) {
+                    if (cm instanceof IndexColorModel) {
+                        this.isTransparent = false;
+                        byte[] alphas = new byte[
+                                          ((IndexColorModel) cm).getMapSize()];
+                        byte[] reds = new byte[
+                                        ((IndexColorModel) cm).getMapSize()];
+                        byte[] greens = new byte[
+                                          ((IndexColorModel) cm).getMapSize()];
+                        byte[] blues = new byte[
+                                         ((IndexColorModel) cm).getMapSize()];
+                        ((IndexColorModel) cm).getAlphas(alphas);
+                        ((IndexColorModel) cm).getReds(reds);
+                        ((IndexColorModel) cm).getGreens(greens);
+                        ((IndexColorModel) cm).getBlues(blues);
+                        for (int i = 0;
+                                i < ((IndexColorModel) cm).getMapSize();
+                                i++) {
+                            if ((alphas[i] & 0xFF) == 0) {
+                                this.isTransparent = true;
+                                this.transparentColor = new Color(
+                                                            (int)(reds[i] & 0xFF),
+                                                            (int)(greens[i] & 0xFF),
+                                                            (int)(blues[i] & 0xFF));
+                                break;
+                            }
+                        }
+                    } else {
+                        // TRANSLUCENT
+                        /*
+                         * this.isTransparent = false;
+                         * for (int i = 0; i < this.width * this.height; i++) {
+                         * if (cm.getAlpha(tmpMap[i]) == 0) {
+                         * this.isTransparent = true;
+                         * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]), 
+                         * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i]));
+                         * break;
+                         * }
+                         * }
+                         * // or use special API...
+                         */
+                        this.isTransparent = false;
+                    }
+                } else {
+                    this.isTransparent = false;
+                }
+            } else {
+                this.isTransparent = false;
+            }
+
+            // Should take care of the ColorSpace and bitsPerPixel
+            this.bitmaps = new byte[this.width * this.height * 3];
+            for (int i = 0; i < this.height; i++) {
+                for (int j = 0; j < this.width; j++) {
+                    int p = tmpMap[i * this.width + j];
+                    int r = (p >> 16) & 0xFF;
+                    int g = (p >> 8) & 0xFF;
+                    int b = (p) & 0xFF;
+                    this.bitmaps[3 * (i * this.width + j)] 
+                        = (byte)(r & 0xFF);
+                    this.bitmaps[3 * (i * this.width + j) + 1] 
+                        = (byte)(g & 0xFF);
+                    this.bitmaps[3 * (i * this.width + j) + 2] 
+                        = (byte)(b & 0xFF);
+                }
+            }
+
+        } catch (Exception ex) {
+            log.error("Error while loading image: " + ex.getMessage(), ex);
+            return false; 
+        } finally {
+            IOUtils.closeQuietly(inputStream);
+            inputStream = null;
+        }
+        return true;
+    }
+
+}
+
index 48e4d056675f1fd5ef2fae9f5a12b08199308044..203f7f951e680745b1088eee63a01309d34dedac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -85,8 +85,12 @@ public class FOUserAgent {
     /** Registry for XML handlers */
     private XMLHandlerRegistry xmlHandlers = new XMLHandlerRegistry();
     
+    /** The base URL for all URL resolutions, especially for external-graphics */
     private String baseURL;
     
+    /** The base URL for all font URL resolutions */
+    private String fontBaseURL;
+    
     /** A user settable URI Resolver */
     private URIResolver uriResolver = null;
     /** Our default resolver if none is set */
@@ -389,29 +393,8 @@ public class FOUserAgent {
      */
     public void initUserConfig() throws ConfigurationException {
         log.debug("Initializing User Agent Configuration");
-        if (userConfig.getChild("base", false) != null) {
-            try {
-                String cfgBaseDir = userConfig.getChild("base").getValue(null);
-                if (cfgBaseDir != null) {
-                    File dir = new File(cfgBaseDir);
-                    if (dir.isDirectory()) {
-                        cfgBaseDir = "file://" + dir.getCanonicalPath() 
-                            + System.getProperty("file.separator");
-                        cfgBaseDir = cfgBaseDir.replace(
-                                System.getProperty("file.separator").charAt(0), '/');
-                    } else {
-                        //The next statement is for validation only
-                        new URL(cfgBaseDir);
-                    }
-                }
-                setBaseURL(cfgBaseDir);
-            } catch (MalformedURLException mue) {
-                log.error("Base URL in user config is malformed!");
-            } catch (IOException ioe) {
-                log.error("Error converting relative base directory to absolute URL.");
-            }
-            log.info("Base URL set to: " + baseURL);
-        }
+        setBaseURL(getBaseURLfromConfig("base"));
+        setFontBaseURL(getBaseURLfromConfig("font-base"));
         if (userConfig.getChild("source-resolution", false) != null) {
             this.sourceResolution 
                 = userConfig.getChild("source-resolution").getValueAsFloat(
@@ -444,6 +427,33 @@ public class FOUserAgent {
         }
     }
 
+    private String getBaseURLfromConfig(String name) {
+        if (userConfig.getChild(name, false) != null) {
+            try {
+                String cfgBaseDir = userConfig.getChild(name).getValue(null);
+                if (cfgBaseDir != null) {
+                    File dir = new File(cfgBaseDir);
+                    if (dir.isDirectory()) {
+                        cfgBaseDir = "file://" + dir.getCanonicalPath() 
+                            + System.getProperty("file.separator");
+                        cfgBaseDir = cfgBaseDir.replace(
+                                System.getProperty("file.separator").charAt(0), '/');
+                    } else {
+                        //The next statement is for validation only
+                        new URL(cfgBaseDir);
+                    }
+                }
+                log.info(name + " set to: " + cfgBaseDir);
+                return cfgBaseDir;
+            } catch (MalformedURLException mue) {
+                log.error("Base URL in user config is malformed!");
+            } catch (IOException ioe) {
+                log.error("Error converting relative base directory to absolute URL.");
+            }
+        }
+        return null;
+    }
+    
     /**
      * Returns the configuration subtree for a specific renderer.
      * @param mimeType MIME type of the renderer
@@ -491,6 +501,22 @@ public class FOUserAgent {
         return this.baseURL;
     }
 
+    /**
+     * Sets the font base URL.
+     * @param fontBaseURL font base URL
+     */
+    public void setFontBaseURL(String fontBaseURL) {
+        this.fontBaseURL = fontBaseURL;
+    }
+
+    /**
+     * Returns the font base URL.
+     * @return the font base URL
+     */
+    public String getFontBaseURL() {
+        return this.fontBaseURL != null ? this.fontBaseURL : this.baseURL ;
+    }
+
     /**
      * Sets the URI Resolver.
      * @param uriResolver the new URI resolver
@@ -535,10 +561,24 @@ public class FOUserAgent {
      * @see org.apache.fop.apps.FOURIResolver
      */
     public Source resolveURI(String uri) {
+        return resolveURI(uri, getBaseURL());
+    }
+
+    /**
+     * Attempts to resolve the given URI.
+     * Will use the configured resolver and if not successful fall back
+     * to the default resolver.
+     * @param uri URI to access
+     * @param baseURL the base url to resolve against
+     * @return A {@link javax.xml.transform.Source} object, or null if the URI
+     * cannot be resolved. 
+     * @see org.apache.fop.apps.FOURIResolver
+     */
+    public Source resolveURI(String uri, String baseURL) {
         Source source = null;
         if (uriResolver != null) {
             try {
-                source = uriResolver.resolve(uri, getBaseURL());
+                source = uriResolver.resolve(uri, baseURL);
             } catch (TransformerException te) {
                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
             }
@@ -546,7 +586,7 @@ public class FOUserAgent {
         if (source == null) {
             // URI Resolver not configured or returned null, use default resolver
             try {
-                source = foURIResolver.resolve(uri, getBaseURL());
+                source = foURIResolver.resolve(uri, baseURL);
             } catch (TransformerException te) {
                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
             }
index cc29b77d648b63c649b430a6d3cc4609a962ebfd..f39bb108de3477f930f0a9feef6f423d1f9164c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2004, 2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,9 @@
 package org.apache.fop.fonts;
 
 import java.util.Map;
+import javax.xml.transform.Source;
+
+import org.apache.fop.apps.FOUserAgent;
 
 
 /**
@@ -30,7 +33,8 @@ public abstract class CustomFont extends Typeface
     private String fontName = null;
     private String embedFileName = null;
     private String embedResourceName = null;
-
+    private FOUserAgent userAgent = null;
+    
     private int capHeight = 0;
     private int xHeight = 0;
     private int ascender = 0;
@@ -46,7 +50,6 @@ public abstract class CustomFont extends Typeface
 
     private Map kerning = new java.util.HashMap();
 
-
     private boolean useKerning = true;
 
 
@@ -66,6 +69,17 @@ public abstract class CustomFont extends Typeface
         return embedFileName;
     }
 
+    /**
+     * Returns a Source representing an embeddable font file.
+     * @return Source for an embeddable font file or null if not available.
+     */
+    public Source getEmbedFileSource() {
+        if (userAgent != null && embedFileName != null) {
+            return userAgent.resolveURI(embedFileName, userAgent.getFontBaseURL());
+        }
+        return null;
+    }
+
     /**
      * Returns the lookup name to an embeddable font file available as a
      * resource.
@@ -328,6 +342,14 @@ public abstract class CustomFont extends Typeface
         this.useKerning = enabled;
     }
 
+    /**
+     * Sets the user agent environment. Needed for URI resolution
+     * @param userAgent the user agent
+     */
+    public void setUserAgent(FOUserAgent userAgent) {
+        this.userAgent = userAgent;
+    }
+
     /**
      * @see org.apache.fop.fonts.MutableFont#putKerningEntry(Integer, Map)
      */
index 5953c91fbcfa3050651f458821177da57b6795c5..74ed0657933cab78122892d91cdd32e839d9da37 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004,2006 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,6 +34,8 @@ import org.xml.sax.helpers.DefaultHandler;
 
 //FOP
 import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.xml.sax.InputSource;
 
 /**
  * Class for reading a metric.xml file and creating a font object.
@@ -61,7 +63,7 @@ public class FontReader extends DefaultHandler {
 
     private List bfranges = null;
 
-    private void createFont(String path) throws FOPException {
+    private void createFont(InputSource source) throws FOPException {
         XMLReader parser = null;
 
         try {
@@ -86,7 +88,7 @@ public class FontReader extends DefaultHandler {
         parser.setContentHandler(this);
 
         try {
-            parser.parse(path);
+            parser.parse(source);
         } catch (SAXException e) {
             throw new FOPException(e);
         } catch (IOException e) {
@@ -111,6 +113,14 @@ public class FontReader extends DefaultHandler {
         returnFont.setKerningEnabled(enabled);
     }
 
+    /**
+     * Sets the user agent environment. Needed for URI resolution
+     * @param userAgent the user agent
+     */
+    public void setUserAgent(FOUserAgent userAgent) {
+        returnFont.setUserAgent(userAgent);
+    }
+
 
     /**
      * Get the generated font object
@@ -123,11 +133,11 @@ public class FontReader extends DefaultHandler {
     /**
      * Construct a FontReader object from a path to a metric.xml file
      * and read metric data
-     * @param path URI to the font metric file
+     * @param source Source of the font metric file
      * @throws FOPException if loading the font fails
      */
-    public FontReader(String path) throws FOPException {
-        createFont(path);
+    public FontReader(InputSource source) throws FOPException {
+        createFont(source);
     }
 
     /**
index 1fb153919f622d0ac7181590a2ca11206ab9d9c8..8ac36bbd55a458f0dacf3a2f5f7436ead70cbb9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@
 
 package org.apache.fop.fonts;
 
+import org.apache.fop.apps.FOUserAgent;
+
 // FOP (base 14 fonts)
 import org.apache.fop.fonts.base14.Helvetica;
 import org.apache.fop.fonts.base14.HelveticaBold;
@@ -68,7 +70,7 @@ public class FontSetup {
      * @param fontInfo the font info object to set up
      * @param embedList ???
      */
-    public static void setup(FontInfo fontInfo, List embedList) {
+    public static void setup(FontInfo fontInfo, List embedList, FOUserAgent ua) {
 
         fontInfo.addMetrics("F1", new Helvetica());
         fontInfo.addMetrics("F2", new HelveticaOblique());
@@ -160,7 +162,7 @@ public class FontSetup {
                                    "normal", Font.NORMAL);
 
         /* Add configured fonts */
-        addConfiguredFonts(fontInfo, embedList, 15);
+        addConfiguredFonts(fontInfo, embedList, 15, ua);
     }
 
     /**
@@ -169,7 +171,8 @@ public class FontSetup {
      * @param fontInfoList
      * @param num starting index for internal font numbering
      */
-    public static void addConfiguredFonts(FontInfo fontInfo, List fontInfoList, int num) {
+    public static void addConfiguredFonts(FontInfo fontInfo, List fontInfoList
+                                        , int num, FOUserAgent userAgent) {
         if (fontInfoList == null) {
             return; //No fonts to process
         }
@@ -192,7 +195,8 @@ public class FontSetup {
                 */
                 LazyFont font = new LazyFont(configFontInfo.getEmbedFile(),
                                              metricsFile,
-                                             configFontInfo.getKerning());
+                                             configFontInfo.getKerning(), 
+                                             userAgent);
                 fontInfo.addMetrics(internalName, font);
 
                 List triplets = configFontInfo.getFontTriplets();
index cffe19aa75f4b97db5d6e305330f4222e3b03660..1ba35a59009f0e19227fa55f029f12a26cd6e459 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 /* $Id$ */
 
 package org.apache.fop.fonts;
-
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Map;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOUserAgent;
+import org.xml.sax.InputSource;
 
 /**
  * This class is used to defer the loading of a font until it is really used.
@@ -38,16 +45,21 @@ public class LazyFont extends Typeface implements FontDescriptor {
     private Typeface realFont = null;
     private FontDescriptor realFontDescriptor = null;
 
+    private FOUserAgent userAgent = null;
+    
     /**
      * Main constructor
      * @param fontEmbedPath path to embeddable file (may be null)
      * @param metricsFileName path to the metrics XML file
      * @param useKerning True, if kerning should be enabled
+     * @param userAgent the environment for uri resoltuion
      */
-    public LazyFont(String fontEmbedPath, String metricsFileName, boolean useKerning) {
+    public LazyFont(String fontEmbedPath, String metricsFileName
+                    , boolean useKerning, FOUserAgent userAgent) {
         this.metricsFileName = metricsFileName;
         this.fontEmbedPath = fontEmbedPath;
         this.useKerning = useKerning;
+        this.userAgent = userAgent;
     }
 
     private void load() {
@@ -55,18 +67,41 @@ public class LazyFont extends Typeface implements FontDescriptor {
             isMetricsLoaded = true;
             try {
                 /**@todo Possible thread problem here */
-
-                FontReader reader = new FontReader(metricsFileName);
+                FontReader reader = null;
+                if (userAgent != null) {
+                    Source source = userAgent.resolveURI(metricsFileName
+                                                        , userAgent.getFontBaseURL());
+                    if (source == null) {
+                        log.error("Failed to create Source from metrics file " + metricsFileName);
+                        return;
+                    }
+                    InputStream in = null;
+                    if (source instanceof StreamSource) {
+                        in = ((StreamSource) source).getInputStream();
+                    }
+                    if (in == null && source.getSystemId() != null) {
+                        in = new java.net.URL(source.getSystemId()).openStream();
+                    }
+                    if (in == null) {
+                        log.error("Failed to create InputStream from Source for metrics file " 
+                                    + metricsFileName);
+                        return;
+                    }
+                    reader = new FontReader(new InputSource(in));
+                } else {
+                    reader 
+                        = new FontReader(new InputSource(new URL(metricsFileName).openStream()));
+                }
                 reader.setKerningEnabled(useKerning);
                 reader.setFontEmbedPath(fontEmbedPath);
+                reader.setUserAgent(userAgent);
                 realFont = reader.getFont();
                 if (realFont instanceof FontDescriptor) {
                     realFontDescriptor = (FontDescriptor) realFont;
                 }
                 // log.debug("Metrics " + metricsFileName + " loaded.");
             } catch (Exception ex) {
-                log.error("Failed to read font metrics file "
-                                     + metricsFileName, ex);
+                log.error("Failed to read font metrics file " + metricsFileName, ex);
             }
         }
     }
index d7b73c37227c51a48a9ef2509db2357fe99dc3d1..e41ceb8582b789502c5fc2de32869745ce4f4da0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -66,6 +66,8 @@ public final class ImageFactory {
                 "ImageIOImage", "org.apache.fop.image.ImageIOImage");
         ImageProvider gifImage = new ImageProvider("GIFImage", "org.apache.fop.image.GifImage");
         ImageProvider jpegImage = new ImageProvider("JPEGImage", "org.apache.fop.image.JpegImage");
+        ImageProvider jpegImageIOImage = new ImageProvider(
+                "JPEGImage", "org.apache.fop.image.JpegImageIOImage");
         ImageProvider bmpImage = new ImageProvider("BMPImage", "org.apache.fop.image.BmpImage");
         ImageProvider epsImage = new ImageProvider("EPSImage", "org.apache.fop.image.EPSImage");
         ImageProvider pngImage = new ImageProvider("PNGImage", "org.apache.fop.image.PNGImage");
@@ -82,6 +84,7 @@ public final class ImageFactory {
 
         imt = new ImageMimeType("image/jpeg");
         imageMimeTypes.put(imt.getMimeType(), imt);
+        imt.addProvider(jpegImageIOImage);
         imt.addProvider(jpegImage);
 
         imt = new ImageMimeType("image/bmp");
@@ -244,16 +247,14 @@ public final class ImageFactory {
             } catch (Exception e) {
                 log.debug("Error closing the InputStream for the image", e);
             }
-            log.error("No ImageReader for this type of image ("
-                    + href + ")");
+            log.error("No ImageReader for this type of image (" + href + ")");
             return null;
         }
         // Associate mime-type to FopImage class
         String imgMimeType = imgInfo.mimeType;
         Class imageClass = getImageClass(imgMimeType);
         if (imageClass == null) {
-            log.error("Unsupported image type ("
-                    + href + "): " + imgMimeType);
+            log.error("Unsupported image type (" + href + "): " + imgMimeType);
             return null;
         } else {
             if (log.isDebugEnabled()) {
@@ -294,8 +295,7 @@ public final class ImageFactory {
             return null;
         }
         if (!(imageInstance instanceof org.apache.fop.image.FopImage)) {
-            log.error("Error creating FopImage object ("
-                    + href + "): " + "class "
+            log.error("Error creating FopImage object (" + href + "): " + "class "
                     + imageClass.getName()
                     + " doesn't implement org.apache.fop.image.FopImage interface");
             return null;
index 5ef2a72a194164c4f5c7f00346a8e571f36ccfdd..39b172417d371d5c2d4bb840c2c5626385753d07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,10 +20,14 @@ package org.apache.fop.pdf;
 
 // Java
 import java.awt.geom.Rectangle2D;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
 import java.util.List;
 import java.util.Map;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
 
 // Apache libs
 import org.apache.commons.io.IOUtils;
@@ -1120,31 +1124,33 @@ public class PDFFactory {
 
         InputStream in = null;
         try {
-            // Get file first
-            if (font.getEmbedFileName() != null) {
-                try {
-                    in = getDocument().resolveURI(font.getEmbedFileName());
-                } catch (Exception e) {
-                    log.error("Failed to embed fontfile: "
-                                       + font.getEmbedFileName()
-                                       + "(" + e.getMessage() + ")");
-                }
+            Source source = font.getEmbedFileSource();
+            if (source == null && font.getEmbedResourceName() != null) {
+                source = new StreamSource(this.getClass()
+                        .getResourceAsStream(font.getEmbedResourceName()));
             }
-
-            // Get resource
-            if (in == null && font.getEmbedResourceName() != null) {
+            if (source == null) {
+                return null;
+            }
+            if (source instanceof StreamSource) {
+                in = ((StreamSource) source).getInputStream();
+            }
+            if (in == null && source.getSystemId() != null) {
                 try {
-                    in = new java.io.BufferedInputStream(
-                            this.getClass().getResourceAsStream(
-                                font.getEmbedResourceName()));
-                } catch (Exception e) {
-                    log.error(
-                                         "Failed to embed fontresource: "
-                                       + font.getEmbedResourceName()
-                                       + "(" + e.getMessage() + ")");
+                    in = new java.net.URL(source.getSystemId()).openStream();
+                } catch (MalformedURLException e) {
+                    new FileNotFoundException(
+                            "File not found. URL could not be resolved: "
+                                    + e.getMessage());
                 }
             }
-
+            if (in == null) {
+                return null;
+            }
+            //Make sure the InputStream is decorated with a BufferedInputStream
+            if (!(in instanceof java.io.BufferedInputStream)) {
+                in = new java.io.BufferedInputStream(in);
+            }
             if (in == null) {
                 return null;
             } else {
index 7b6b646f7d8a80e1d4b66bebda0a871924543d80..f1e943c56259ec06160733904320b2ff858e50e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public abstract class PrintRenderer extends AbstractRenderer {
      */
     public void setupFontInfo(FontInfo inFontInfo) {
         this.fontInfo = inFontInfo;
-        FontSetup.setup(fontInfo, fontList);
+        FontSetup.setup(fontInfo, fontList, userAgent);
     }
 
     /**
index 2c684d5b9cca5c1bbc65cd7e6498ebbf0f8eb437..33c366a4db78e2782fc44b23392fa1930b852ca0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ public abstract class AbstractPSDocumentGraphics2D extends PSGraphics2D {
 
         if (!textAsShapes) {
             fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, null);
+            FontSetup.setup(fontInfo, null, null);
         }
     }
 
index 08bbc3050eddd8634e757884795b8d5352450bd1..90cf60ce18eeb37c778ea30b9b00f8e0f5b4acf3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ public class PSDocumentGraphics2D extends AbstractPSDocumentGraphics2D {
 
         if (!textAsShapes) {
             fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, null);
+            FontSetup.setup(fontInfo, null, null);
         }
     }
 
index e04f3e2fcdb8b6c5d506511ec1175c98032f54f2..f209eaab029f2e642a1729c6e5ad5c150769c3b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2005 The Apache Software Foundation.
+ * Copyright 2001-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -177,10 +177,7 @@ public class PSFontUtils {
     private static InputStream getInputStreamOnFont(PSGenerator gen, CustomFont font) 
                 throws IOException {
         if (font.isEmbeddable()) {
-            Source source = null;
-            if (font.getEmbedFileName() != null) {
-                source = gen.resolveURI(font.getEmbedFileName());
-            }
+            Source source = font.getEmbedFileSource();
             if (source == null && font.getEmbedResourceName() != null) {
                 source = new StreamSource(PSFontUtils.class
                         .getResourceAsStream(font.getEmbedResourceName()));
index 598700367ebd1990b99dc7b43e1e10ae41d391ca..62104ca26b1793f9390b05a933961366796a4c02 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index d317ffe50d756da932c1046f056ded2fe33959a8..3714ac2ab5e13b0abaf9df89e4b5f3c63c740e61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -130,7 +130,7 @@ public class RTFHandler extends FOEventHandler {
         this.os = os;
         bDefer = true;
 
-        FontSetup.setup(fontInfo, null);
+        FontSetup.setup(fontInfo, null, userAgent);
     }
 
     /**
index ffe99b8f28a2807357084709ce1c8d7000b38550..e4891020ad85f1a3fd2fa97e228b0e2baf5e5e59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -108,7 +108,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         this.pdfContext = new PDFContext();
         if (!textAsShapes) {
             fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, null);
+            FontSetup.setup(fontInfo, null, null);
             //FontState fontState = new FontState("Helvetica", "normal",
             //                          FontInfo.NORMAL, 12, 0);
         }
@@ -166,7 +166,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
     public void initialize() throws Exception {
         if (this.fontInfo == null) {
             fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, this.pdfContext.getFontList());
+            FontSetup.setup(fontInfo, this.pdfContext.getFontList(), null);
             //FontState fontState = new FontState("Helvetica", "normal",
             //                          FontInfo.NORMAL, 12, 0);
         }
index edb538df486248ea786650dac113f3029863ab45..732cd95bda8b19b301c4599d23dcc80198fd74b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1023,7 +1023,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
         preparePainting();
 
         FontInfo fontInfo = new FontInfo();
-        FontSetup.setup(fontInfo, null);
+        FontSetup.setup(fontInfo, null, null);
 
         PDFResources res = pdfDoc.getFactory().makeResources();
         PDFResourceContext context = new PDFResourceContext(res);
index c9ef2a53ebb8631776d4482555955bfc97688bff..0e1b83f6d08b5c102204c3ed95133111f55418c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2005 The Apache Software Foundation.
+ * Copyright 1999-2006 The Apache Software Foundation.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -80,7 +80,7 @@ public class MIFHandler extends FOEventHandler {
     public MIFHandler(FOUserAgent ua, OutputStream os) {
         super(ua);
         outStream = os;
-        FontSetup.setup(fontInfo, null);
+        FontSetup.setup(fontInfo, null, ua);
     }
 
     /**
index 7ef2d56fe8cc54561c86d352a90419d6720860c4..79a098f3f1054f593745a1770b04fe1a39c3a49c 100644 (file)
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="MM" type="add" fixes-bug="36729">
+        Relative URLs for the font configuration attributes metrics-url and embed-url
+        are now supported. A new configuration property font-base has been added. It
+        sets the base URL against which relative font URLs are resolved. If font-base is
+        not set base is used.
+      </action>
       <action context="Code" dev="JM" type="add" fixes-bug="38132" due-to="Richard Wheeldon">
         Added support for RFC2397 "data" URLs.
       </action>