]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Added full URI resolution support for AFP fonts.
authorJeremias Maerki <jeremias@apache.org>
Tue, 10 Mar 2009 15:10:07 +0000 (15:10 +0000)
committerJeremias Maerki <jeremias@apache.org>
Tue, 10 Mar 2009 15:10:07 +0000 (15:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@752133 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/trunk/output.xml
src/java/org/apache/fop/afp/AFPResourceManager.java
src/java/org/apache/fop/afp/fonts/AFPFontCollection.java
src/java/org/apache/fop/afp/fonts/AFPFontReader.java
src/java/org/apache/fop/afp/fonts/CharacterSet.java
src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
src/java/org/apache/fop/render/afp/AFPPainter.java
src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
status.xml

index 393624b6bf405daf2ff50b0df008a0c7894d33f3..c2548b390f6528bfadc17df8cd859381b6b627f3 100644 (file)
@@ -536,8 +536,8 @@ out = proc.getOutputStream();]]></source>
 <source><![CDATA[      <!-- This is an example of mapping actual IBM raster fonts / code pages to a FOP font -->
         <font>
         <!-- The afp-font element defines the IBM code page, the matching Java encoding and the
-             path to the font -->
-        <afp-font type="raster" codepage="T1V10500" encoding="Cp500" path="fonts/ibm">
+             base URI for the font -->
+        <afp-font type="raster" codepage="T1V10500" encoding="Cp500" base-uri="fonts/ibm/">
           <!-- For a raster font a separate element for each font size is required providing
                the font size and the corresponding IBM Character set name -->
           <afp-raster-font size="7" characterset="C0N20070"/>
@@ -563,15 +563,24 @@ out = proc.getOutputStream();]]></source>
       However, the characterset definition is now required within the afp-font element.</p>
 <source><![CDATA[      <font>
           <afp-font type="outline" codepage="T1V10500" encoding="Cp500" characterset="CZH200  "
-             path="fonts/ibm" />
+             base-uri="file:/fonts/ibm" />
           <font-triplet name="sans-serif" style="normal" weight="normal"/>
           <font-triplet name="Helvetica" style="normal" weight="normal"/>
           <font-triplet name="any" style="normal" weight="normal"/>
       </font>
 ]]></source>
+      <p>
+        If "base-uri" is missing or a relative URI, the fonts are resolved relative to
+        the font base URI specified in the configuration (or on the FopFactory).
+      </p>
+      <note>
+        Previously, the location of the font files was given by the "path" attribute. This is still
+        supported for the time being, but you should move to using the more flexible "base-uri"
+        attribute so you can profit from the power of URI resolvers.
+      </note>
       <p>Experimentation has shown that the font metrics for the FOP built-in Base14 fonts are actually
       very similar to some of the IBM outline and raster fonts. In cases were the IBM font files are not
-      available the path attribute in the afp-font element can be replaced by a base14-font attribute 
+      available the base-uri attribute in the afp-font element can be replaced by a base14-font attribute 
       giving the name of the matching Base14 font. In this case the AFP Renderer will take the
       font metrics from the built-in font.</p>
 <source><![CDATA[      <!-- The following are examples of defining outline fonts based on FOP built-in
index 78c06bedf04c20f04dc015c46fc7147eccecb117..c44698a1074cea21af54f99dad8d2c2aa128c8e4 100644 (file)
@@ -37,7 +37,6 @@ import org.apache.fop.afp.modca.Registry;
 import org.apache.fop.afp.modca.ResourceGroup;
 import org.apache.fop.afp.modca.ResourceObject;
 import org.apache.fop.afp.util.ResourceAccessor;
-import org.apache.fop.afp.util.SimpleResourceAccessor;
 
 /**
  * Manages the creation and storage of document resources
@@ -236,11 +235,11 @@ public class AFPResourceManager {
     /**
      * Creates an included resource object by loading the contained object from a file.
      * @param resourceName the name of the resource
-     * @param basePath the base path in which to look for the resource files
+     * @param accessor resource accessor to access the resource with
      * @param resourceObjectType the resource object type ({@link ResourceObject}.*)
      * @throws IOException if an I/O error occurs while loading the resource
      */
-    public void createIncludedResource(String resourceName, String basePath,
+    public void createIncludedResource(String resourceName, ResourceAccessor accessor,
                 byte resourceObjectType) throws IOException {
         AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
         URI uri;
@@ -261,9 +260,6 @@ public class AFPResourceManager {
             if (log.isDebugEnabled()) {
                 log.debug("Adding included resource: " + resourceName);
             }
-            //TODO This works with local filenames only. In the long term, this
-            //should work through FOP's URI resolver.
-            ResourceAccessor accessor = new SimpleResourceAccessor(basePath);
             IncludedResourceObject resourceContent = new IncludedResourceObject(
                         resourceName, accessor, uri);
 
index 670373fbf7896c3af36f702743e2bbbed3a1f96a..66b3f556488090ff8e5a1902bf3c67363b56a239 100644 (file)
@@ -67,18 +67,14 @@ public class AFPFontCollection implements FontCollection {
                     num++;
                 }
             }
-            if (!fontInfo.hasFont("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)) {
-                eventProducer.warnMissingDefaultFont(this, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
-            }
-            if (!fontInfo.hasFont("any", Font.STYLE_ITALIC, Font.WEIGHT_NORMAL)) {
-                eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
-            }
-            if (!fontInfo.hasFont("any", Font.STYLE_NORMAL, Font.WEIGHT_BOLD)) {
-                eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
-            }
-            if (!fontInfo.hasFont("any", Font.STYLE_ITALIC, Font.WEIGHT_BOLD)) {
-                eventProducer.warnMissingDefaultFont(this, Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
-            }
+            checkDefaultFontAvailable(fontInfo, eventProducer,
+                    Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+            checkDefaultFontAvailable(fontInfo, eventProducer,
+                    Font.STYLE_ITALIC, Font.WEIGHT_NORMAL);
+            checkDefaultFontAvailable(fontInfo, eventProducer,
+                    Font.STYLE_NORMAL, Font.WEIGHT_BOLD);
+            checkDefaultFontAvailable(fontInfo, eventProducer,
+                    Font.STYLE_ITALIC, Font.WEIGHT_BOLD);
         } else {
             eventProducer.warnDefaultFontSetup(this);
 
@@ -89,4 +85,11 @@ public class AFPFontCollection implements FontCollection {
         return num;
     }
 
+    private void checkDefaultFontAvailable(FontInfo fontInfo, AFPEventProducer eventProducer,
+            String style, int weight) {
+        if (!fontInfo.hasFont("any", style, weight)) {
+            eventProducer.warnMissingDefaultFont(this, style, weight);
+        }
+    }
+
 }
index d1e8bd8dbea494c6ca3be1c349ddee4993b4621e..4e6a0325995a98ca1e1d85ff203b15d5df39e8a4 100644 (file)
 
 package org.apache.fop.afp.fonts;
 
-import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.afp.AFPConstants;
+import org.apache.fop.afp.util.ResourceAccessor;
 import org.apache.fop.afp.util.StructuredFieldReader;
 
 /**
@@ -58,7 +56,7 @@ public final class AFPFontReader {
     /**
      * Static logging instance
      */
-    protected static final Log log = LogFactory.getLog("org.apache.xmlgraphics.afp.fonts");
+    protected static final Log log = LogFactory.getLog(AFPFontReader.class);
 
     /**
      * Template used to convert lists to arrays.
@@ -96,7 +94,7 @@ public final class AFPFontReader {
     /**
      * The collection of code pages
      */
-    private final Map/*<String, Map<String, String>>*/ codePages
+    private final Map/*<String, Map<String, String>>*/ codePagesCache
         = new java.util.HashMap/*<String, Map<String, String>>*/();
 
     /**
@@ -108,65 +106,16 @@ public final class AFPFontReader {
      *
      * @throws IOException in the event that an I/O exception of some sort has occurred
      */
-    private InputStream openInputStream(String path, String filename) throws IOException {
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        if (classLoader == null) {
-            classLoader = AFPFontReader.class.getClassLoader();
-        }
-
-        URL url = classLoader.getResource(path);
-
-        if (url == null) {
-            try {
-                File file = new File(path);
-                url = file.toURI().toURL();
-                if (url == null) {
-                    String msg = "file not found " + filename + " in classpath: " + path;
-                    log.error(msg);
-                    throw new FileNotFoundException(msg);
-                }
-            } catch (MalformedURLException ex) {
-                String msg = "file not found " + filename + " in classpath: " + path;
-                log.error(msg);
-                throw new FileNotFoundException(msg);
-            }
-        }
-
-        File directory = FileUtils.toFile(url);
-        if (!directory.canRead()) {
-            String msg = "Failed to read directory " + url.getPath();
-            log.error(msg);
-            throw new FileNotFoundException(msg);
-        }
-
-        final String filterpattern = filename.trim();
-        FilenameFilter filter = new FilenameFilter() {
-            public boolean accept(File dir, String name) {
-                return name.startsWith(filterpattern);
-            }
-        };
-
-        File[] files = directory.listFiles(filter);
-
-        if (files.length < 1) {
-            String msg = "file search for " + filename + " located "
-                + files.length + " files";
-            log.error(msg);
-            throw new FileNotFoundException(msg);
-        } else if (files.length > 1) {
-            String msg = "file search for " + filename + " located "
-                + files.length + " files";
-            log.warn(msg);
-        }
-
-        InputStream inputStream = files[0].toURI().toURL().openStream();
-
-        if (inputStream == null) {
-            String msg = "AFPFontReader:: getInputStream():: file not found for " + filename;
-            log.error(msg);
-            throw new FileNotFoundException(msg);
+    private InputStream openInputStream(ResourceAccessor accessor, String filename)
+            throws IOException {
+        URI uri;
+        try {
+            uri = new URI(filename.trim());
+        } catch (URISyntaxException e) {
+            throw new FileNotFoundException("Invalid filename: "
+                    + filename + " (" + e.getMessage() + ")");
         }
-
+        InputStream inputStream = accessor.createInputStream(uri);
         return inputStream;
     }
 
@@ -206,13 +155,14 @@ public final class AFPFontReader {
              * chracter global identifier.
              */
             String codePageId = new String(characterSet.getCodePage());
-            String path = characterSet.getPath();
+            ResourceAccessor accessor = characterSet.getResourceAccessor();
 
-            Map/*<String,String>*/ codePage = (Map/*<String,String>*/)codePages.get(codePageId);
+            Map/*<String,String>*/ codePage
+                = (Map/*<String,String>*/)codePagesCache.get(codePageId);
 
             if (codePage == null) {
-                codePage = loadCodePage(codePageId, characterSet.getEncoding(), path);
-                codePages.put(codePageId, codePage);
+                codePage = loadCodePage(codePageId, characterSet.getEncoding(), accessor);
+                codePagesCache.put(codePageId, codePage);
             }
 
             /**
@@ -222,7 +172,7 @@ public final class AFPFontReader {
              */
             final String characterSetName = characterSet.getName();
 
-            inputStream = openInputStream(path, characterSetName);
+            inputStream = openInputStream(accessor, characterSetName);
 
             StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream);
 
@@ -246,7 +196,8 @@ public final class AFPFontReader {
                 }
 
                 //process D3AC89 Font Position
-                processFontPosition(structuredFieldReader, characterSetOrientations, metricNormalizationFactor);
+                processFontPosition(structuredFieldReader, characterSetOrientations,
+                        metricNormalizationFactor);
 
                 //process D38C89 Font Index (per orientation)
                 for (int i = 0; i < characterSetOrientations.length; i++) {
@@ -274,17 +225,18 @@ public final class AFPFontReader {
      *            the code page identifier
      * @param encoding
      *            the encoding to use for the character decoding
+     * @param accessor the resource accessor
      * @returns a code page mapping
      */
     private Map/*<String,String>*/ loadCodePage(String codePage, String encoding,
-        String path) throws IOException {
+        ResourceAccessor accessor) throws IOException {
 
         // Create the HashMap to store code page information
         Map/*<String,String>*/ codePages = new java.util.HashMap/*<String,String>*/();
 
         InputStream inputStream = null;
         try {
-            inputStream = openInputStream(path, codePage.trim());
+            inputStream = openInputStream(accessor, codePage.trim());
 
             StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream);
             byte[] data = structuredFieldReader.getNext(CHARACTER_TABLE_SF);
index f0b671932a1f6f7c4a5e7e0e6f0ba5cd441f03e8..9573506b34ef62000353c697d8b65c504cd7bcf5 100644 (file)
 
 package org.apache.fop.afp.fonts;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.CharacterCodingException;
@@ -34,6 +36,8 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.afp.AFPConstants;
+import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.SimpleResourceAccessor;
 import org.apache.fop.afp.util.StringUtils;
 
 /**
@@ -80,7 +84,7 @@ public class CharacterSet {
     protected String name;
 
     /** The path to the installed fonts */
-    protected String path;
+    private ResourceAccessor accessor;
 
     /** Indicator as to whether to metrics have been loaded */
     private boolean isMetricsLoaded = false;
@@ -99,8 +103,23 @@ public class CharacterSet {
      * @param encoding the encoding of the font
      * @param name the character set name
      * @param path the path to the installed afp fonts
+     * @deprecated Please use {@link #CharacterSet(String, String, String, URI)} instead.
      */
     public CharacterSet(String codePage, String encoding, String name, String path) {
+        this(codePage, encoding, name,
+                new SimpleResourceAccessor(path != null ? new File(path) : null));
+    }
+
+    /**
+     * Constructor for the CharacterSetMetric object, the character set is used
+     * to load the font information from the actual AFP font.
+     *
+     * @param codePage the code page identifier
+     * @param encoding the encoding of the font
+     * @param name the character set name
+     * @param accessor the resource accessor to load resource with
+     */
+    public CharacterSet(String codePage, String encoding, String name, ResourceAccessor accessor) {
         if (name.length() > MAX_NAME_LEN) {
             String msg = "Character set name '" + name + "' must be a maximum of "
                 + MAX_NAME_LEN + " characters";
@@ -123,7 +142,7 @@ public class CharacterSet {
             //This may happen with "Cp500" on Sun Java 1.4.2
             this.encoder = null;
         }
-        this.path = path;
+        this.accessor = accessor;
 
         this.characterSetOrientations = new java.util.HashMap(4);
     }
@@ -202,12 +221,11 @@ public class CharacterSet {
     }
 
     /**
-     * Returns the path where the font resources are installed
-     *
-     * @return the path where the font resources are installed
+     * Returns the resource accessor to load the font resources with.
+     * @return the resource accessor to load the font resources with
      */
-    public String getPath() {
-        return path;
+    public ResourceAccessor getResourceAccessor() {
+        return this.accessor;
     }
 
     /**
index aec220b407057433eec1a332a97931de8e43c57e..42950dc5bdc2a52c2f9660094351f5da22e8b870 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.apache.fop.afp.fonts;
 
+import org.apache.fop.afp.util.ResourceAccessor;
 import org.apache.fop.fonts.Typeface;
 
 /**
@@ -43,7 +44,7 @@ public class FopCharacterSet extends CharacterSet {
         String name,
         Typeface charSet) {
 
-        super(codePage, encoding, name, null);
+        super(codePage, encoding, name, (ResourceAccessor)null);
         this.charSet = charSet;
     }
 
index 55c8eab7d5992487042089729da9b10ffb05d51e..97646542b020d5d9f848b23569279d496dce6228 100644 (file)
 
 package org.apache.fop.afp.util;
 
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.net.URL;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;
 
+import org.apache.commons.io.IOUtils;
+
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.fonts.FontManager;
 
 /**
  * Default implementation of the {@link ResourceAccessor} interface for use inside FOP.
  */
-public class DefaultFOPResourceAccessor implements ResourceAccessor {
+public class DefaultFOPResourceAccessor extends SimpleResourceAccessor {
 
     private FOUserAgent userAgent;
+    private String categoryBaseURI;
 
     /**
-     * Main constructor.
+     * Constructor for resource to be accessed via the {@link FOUserAgent}. This contructor
+     * can take two base URIs: the category base URI is the one to use when differentiating between
+     * normal resources (ex. images) and font resources. So, if fonts need to be accessed, you can
+     * set the {@link FontManager}'s base URI instead of the one on the {@link FopFactory}.
      * @param userAgent the FO user agent
+     * @param categoryBaseURI the category base URI (may be null)
+     * @param baseURI the custom base URI to resolve relative URIs against (may be null)
      */
-    public DefaultFOPResourceAccessor(FOUserAgent userAgent) {
+    public DefaultFOPResourceAccessor(FOUserAgent userAgent, String categoryBaseURI, URI baseURI) {
+        super(baseURI);
         this.userAgent = userAgent;
+        this.categoryBaseURI = categoryBaseURI;
     }
 
     /** {@inheritDoc} */
     public InputStream createInputStream(URI uri) throws IOException {
-        Source src = userAgent.resolveURI(uri.toASCIIString());
+        //Step 1: resolve against local base URI --> URI
+        URI resolved = resolveAgainstBase(uri);
+
+        //Step 2: resolve against the user agent --> stream
+        Source src;
+        src = userAgent.resolveURI(resolved.toASCIIString(), this.categoryBaseURI);
+
         if (src == null) {
-            return null;
+            throw new FileNotFoundException("Resource not found: " + uri.toASCIIString());
         } else if (src instanceof StreamSource) {
             StreamSource ss = (StreamSource)src;
             InputStream in = ss.getInputStream();
-            return in;
-        } else {
-            return null;
+            if (in != null) {
+                return in;
+            }
+            if (ss.getReader() != null) {
+                //Don't support reader, retry using system ID below
+                IOUtils.closeQuietly(ss.getReader());
+            }
         }
+        URL url = new URL(src.getSystemId());
+        return url.openStream();
     }
 
 }
index 51772c253aedc59ab2c768e8ae95ad308b86184d..7a963928b8de63dfc4f2050c1eed414ea7713bce 100644 (file)
@@ -26,7 +26,8 @@ import java.net.URI;
 import java.net.URL;
 
 /**
- * Simple implementation of the {@link ResourceAccessor} interface for access via files.
+ * Simple implementation of the {@link ResourceAccessor} interface for access relative to a
+ * base URI.
  */
 public class SimpleResourceAccessor implements ResourceAccessor {
 
@@ -34,23 +35,40 @@ public class SimpleResourceAccessor implements ResourceAccessor {
 
     /**
      * Creates a new simple resource accessor.
-     * @param basePath the base path to resolve relative URIs to
+     * @param baseURI the base URI to resolve relative URIs against (may be null)
      */
-    public SimpleResourceAccessor(File basePath) {
-        this.baseURI = basePath.toURI();
+    public SimpleResourceAccessor(URI baseURI) {
+        this.baseURI = baseURI;
     }
 
     /**
      * Creates a new simple resource accessor.
-     * @param basePath the base path to resolve relative URIs to
+     * @param baseDir the base directory to resolve relative filenames against (may be null)
      */
-    public SimpleResourceAccessor(String basePath) {
-        this(new File(basePath));
+    public SimpleResourceAccessor(File baseDir) {
+        this(baseDir != null ? baseDir.toURI() : null);
+    }
+
+    /**
+     * Returns the base URI.
+     * @return the base URI (or null if no base URI was set)
+     */
+    public URI getBaseURI() {
+        return this.baseURI;
+    }
+
+    /**
+     * Resolve the given URI against the baseURI.
+     * @param uri the URI to resolve
+     * @return the resolved URI
+     */
+    protected URI resolveAgainstBase(URI uri) {
+        return (getBaseURI() != null ? getBaseURI().resolve(uri) : uri);
     }
 
     /** {@inheritDoc} */
     public InputStream createInputStream(URI uri) throws IOException {
-        URI resolved = this.baseURI.resolve(uri);
+        URI resolved = resolveAgainstBase(uri);
         URL url = resolved.toURL();
         return url.openStream();
     }
index 0c2501b870c5940e87a2d26ca9dc45b408696d46..a92be9d6e5fcbec2570f76695f3a519ea74769e2 100644 (file)
@@ -49,6 +49,7 @@ import org.apache.fop.afp.modca.PresentationTextObject;
 import org.apache.fop.afp.modca.ResourceObject;
 import org.apache.fop.afp.ptoca.PtocaBuilder;
 import org.apache.fop.afp.ptoca.PtocaProducer;
+import org.apache.fop.afp.util.ResourceAccessor;
 import org.apache.fop.fonts.Font;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
@@ -342,12 +343,13 @@ public class AFPPainter extends AbstractIFPainter {
             try {
                 //Embed fonts (char sets and code pages)
                 //TODO This should be moved to a place where it has less performance impact
-                if (charSet.getPath() != null) {
+                if (charSet.getResourceAccessor() != null) {
+                    ResourceAccessor accessor = charSet.getResourceAccessor();
                     documentHandler.getResourceManager().createIncludedResource(
-                            charSet.getName(), charSet.getPath(),
+                            charSet.getName(), accessor,
                             ResourceObject.TYPE_FONT_CHARACTER_SET);
                     documentHandler.getResourceManager().createIncludedResource(
-                            charSet.getCodePage(), charSet.getPath(),
+                            charSet.getCodePage(), accessor,
                             ResourceObject.TYPE_CODE_PAGE);
                 }
             } catch (IOException ioe) {
index bd6df613679226f625bfc10ddf7cdbe1acdc0778..fcc1140c7c006380fdc3589b07030407c6f1a4c6 100644 (file)
@@ -20,6 +20,8 @@
 package org.apache.fop.render.afp;
 
 import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.List;
 
 import org.apache.avalon.framework.configuration.Configuration;
@@ -33,6 +35,8 @@ import org.apache.fop.afp.fonts.CharacterSet;
 import org.apache.fop.afp.fonts.FopCharacterSet;
 import org.apache.fop.afp.fonts.OutlineFont;
 import org.apache.fop.afp.fonts.RasterFont;
+import org.apache.fop.afp.util.DefaultFOPResourceAccessor;
+import org.apache.fop.afp.util.ResourceAccessor;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fonts.FontCollection;
@@ -85,7 +89,29 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
             log.error("Mandatory font configuration element '<afp-font...' is missing");
             return null;
         }
-        String path = afpFontCfg.getAttribute("path", fontPath);
+
+        URI baseURI = null;
+        String uri = afpFontCfg.getAttribute("base-uri", fontPath);
+        if (uri == null) {
+            //Fallback for old attribute which only supports local filenames
+            String path = afpFontCfg.getAttribute("path", fontPath);
+            if (path != null) {
+                File f = new File(path);
+                baseURI = f.toURI();
+            }
+        } else {
+            try {
+                baseURI = new URI(uri);
+            } catch (URISyntaxException e) {
+                log.error("Invalid URI: " + e.getMessage());
+                return null;
+            }
+        }
+        ResourceAccessor accessor = new DefaultFOPResourceAccessor(
+                this.userAgent,
+                this.userAgent.getFactory().getFontManager().getFontBaseURL(),
+                baseURI);
+
         String type = afpFontCfg.getAttribute("type");
         if (type == null) {
             log.error("Mandatory afp-font configuration attribute 'type=' is missing");
@@ -147,7 +173,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
                     }
                 } else {
                     font.addCharacterSet(size, new CharacterSet(
-                        codepage, encoding, characterset, path));
+                        codepage, encoding, characterset, accessor));
                 }
             }
             return new AFPFontInfo(font, tripletList);
@@ -180,7 +206,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
                     log.error(msg);
                 }
             } else {
-                characterSet = new CharacterSet(codepage, encoding, characterset, path);
+                characterSet = new CharacterSet(codepage, encoding, characterset, accessor);
             }
             // Create a new font object
             OutlineFont font = new OutlineFont(name, characterSet);
index 57b41166d0338fd888e93a6977a9e5043b6822dc..7e60a7342d214bc225189bddf4da32cd171708f0 100644 (file)
@@ -58,6 +58,9 @@
       documents. Example: the fix of marks layering will be such a case when it's done.
     -->
     <release version="FOP Trunk" date="TBD">
+      <action context="Fonts" dev="JM" type="add">
+        AFP Fonts: Added support for full URI resolution on configured AFP fonts. 
+      </action>
       <action context="Renderers" dev="JM" type="add">
         AFP Output: Tag Logical Element (TLE) is now also allowed on fo:page-sequence
         (page group level).