]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #41831:
authorJeremias Maerki <jeremias@apache.org>
Mon, 28 May 2007 14:31:24 +0000 (14:31 +0000)
committerJeremias Maerki <jeremias@apache.org>
Mon, 28 May 2007 14:31:24 +0000 (14:31 +0000)
- Add support font auto-detection (easier font configuration) including a font cache to speed up the auto-detection process.
- Refactoring of the configuration code: All Avalon configuration stuff is extracted into separate "Configurator" classes.
- Refactoring of the FOURIResolver.
Submitted by: Adrian Cumiskey <fop-dev.at.cumiskey.com>

Changes to the patch by jeremias during the review:
- Font cache simplified (Java object serialization instead of XML), functionality fixed and moved to the fonts.package.
- Relocated default cache file location to user directory.
- Fixed the font configuration for PDFDocumentGraphics2D/PDFTranscoder that got lost with the patch.
- Fixed a problem with having a non-file URL as font base URL.
- Simplified RendererContextInfo stuff to make it easier to understand.
- Fixed handling of Type 1 fonts in auto-detection.
- Reduced verbosity of font-related log output.
- Updated Jakarta Commons IO to version 1.3.1 (the patch depends on it)
- Various javadocs improvements

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@542237 13f79535-47bb-0310-9956-ffa450edef68

121 files changed:
fop.bat
fop.cmd
lib/commons-io-1.1.jar [deleted file]
lib/commons-io-1.3.1.jar [new file with mode: 0644]
lib/commons-io.NOTICE.txt
src/documentation/content/xdocs/trunk/configuration.xml
src/documentation/content/xdocs/trunk/fonts.xml
src/java/org/apache/fop/apps/FOURIResolver.java
src/java/org/apache/fop/apps/FOUserAgent.java
src/java/org/apache/fop/apps/FopFactory.java
src/java/org/apache/fop/apps/FopFactoryConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/area/AreaTreeParser.java
src/java/org/apache/fop/cli/CommandLineOptions.java
src/java/org/apache/fop/fonts/CachedFontInfo.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/CustomFont.java
src/java/org/apache/fop/fonts/EmbedFontInfo.java
src/java/org/apache/fop/fonts/Font.java
src/java/org/apache/fop/fonts/FontCache.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/FontInfo.java
src/java/org/apache/fop/fonts/FontLoader.java
src/java/org/apache/fop/fonts/FontSetup.java
src/java/org/apache/fop/fonts/FontUtil.java
src/java/org/apache/fop/fonts/LazyFont.java
src/java/org/apache/fop/fonts/MultiByteFont.java
src/java/org/apache/fop/fonts/apps/TTFReader.java
src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/FontFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java [new file with mode: 0644]
src/java/org/apache/fop/fonts/autodetect/package.html [new file with mode: 0644]
src/java/org/apache/fop/fonts/truetype/TTFFile.java
src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
src/java/org/apache/fop/pdf/PDFFilterList.java
src/java/org/apache/fop/render/AbstractRenderer.java
src/java/org/apache/fop/render/AbstractRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/AbstractRendererMaker.java
src/java/org/apache/fop/render/PrintRenderer.java
src/java/org/apache/fop/render/PrintRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/RendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/RendererContext.java
src/java/org/apache/fop/render/RendererFactory.java
src/java/org/apache/fop/render/XMLHandlerConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/AFPRenderer.java
src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/afp/AFPRendererMaker.java
src/java/org/apache/fop/render/awt/AWTRenderer.java
src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
src/java/org/apache/fop/render/java2d/FontSetup.java
src/java/org/apache/fop/render/java2d/Java2DRenderer.java
src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/pcl/PCLRenderer.java
src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/pcl/PCLRendererMaker.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/pdf/PDFRendererMaker.java
src/java/org/apache/fop/render/print/PrintRendererMaker.java
src/java/org/apache/fop/render/ps/NativeTextHandler.java
src/java/org/apache/fop/render/ps/PSRenderer.java
src/java/org/apache/fop/render/ps/PSRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/ps/PSRendererMaker.java
src/java/org/apache/fop/render/ps/PSTextPainter.java
src/java/org/apache/fop/render/txt/TXTRenderer.java
src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/render/txt/TXTRendererMaker.java
src/java/org/apache/fop/render/xml/XMLRenderer.java
src/java/org/apache/fop/render/xml/XMLRendererMaker.java
src/java/org/apache/fop/svg/PDFContext.java
src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java [new file with mode: 0644]
src/java/org/apache/fop/svg/PDFGraphics2D.java
src/java/org/apache/fop/svg/PDFTextElementBridge.java
src/java/org/apache/fop/svg/PDFTextPainter.java
src/java/org/apache/fop/svg/PDFTranscoder.java
src/java/org/apache/fop/util/LogUtil.java [new file with mode: 0644]
src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
status.xml
test/config/test_embedurl_bad.xconf [deleted file]
test/config/test_embedurl_malformed.xconf [deleted file]
test/config/test_font_attributes_missing.xconf [new file with mode: 0644]
test/config/test_font_embedurl_bad.xconf [new file with mode: 0644]
test/config/test_font_embedurl_malformed.xconf [new file with mode: 0644]
test/config/test_font_metricsurl_bad.xconf [new file with mode: 0644]
test/config/test_font_metricsurl_malformed.xconf [new file with mode: 0644]
test/config/test_font_tripletattribute_missing.xconf [new file with mode: 0644]
test/config/test_fontattributes_missing.xconf [deleted file]
test/config/test_fontbase_bad.xconf
test/config/test_fonts_autodetect.xconf [new file with mode: 0644]
test/config/test_fonts_directory_bad.xconf [new file with mode: 0644]
test/config/test_fonts_directory_recursive.xconf [new file with mode: 0644]
test/config/test_fonttripletattribute_missing.xconf [deleted file]
test/config/test_metricsurl_bad.xconf [deleted file]
test/config/test_metricsurl_malformed.xconf [deleted file]
test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/BaseUserConfigTestCase.java
test/java/org/apache/fop/config/EmbedUrlBadTestCase.java [deleted file]
test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java [deleted file]
test/java/org/apache/fop/config/FontAttributesMissingTestCase.java
test/java/org/apache/fop/config/FontBaseBadTestCase.java
test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java
test/java/org/apache/fop/config/FontsAutoDetectTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java [new file with mode: 0644]
test/java/org/apache/fop/config/MetricsUrlBadTestCase.java [deleted file]
test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java [deleted file]
test/java/org/apache/fop/config/UserConfigTestSuite.java
test/java/org/apache/fop/render/pdf/BasePDFTestCase.java
test/test.xconf
test/xml/bugtests/font-dir.fo [new file with mode: 0644]
test/xml/pdf-encoding/pdf-encoding-test.xconf

diff --git a/fop.bat b/fop.bat
index 9e04348c32eb323b0445378f54594d7a05adf27a..c099257cf5b4985ec7bc81f0d128c47ea5d673bf 100644 (file)
--- a/fop.bat
+++ b/fop.bat
@@ -62,7 +62,7 @@ set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\serializer-2.7.0.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\batik-all-1.6.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\xmlgraphics-commons-1.2svn.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\avalon-framework-4.2.0.jar\r
-set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\commons-io-1.1.jar\r
+set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\commons-io-1.3.1.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\commons-logging-1.0.4.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\jimi-1.0.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\jai_core.jar\r
@@ -70,6 +70,8 @@ set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\jai_codec.jar
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%LIBDIR%\fop-hyph.jar\r
 set LOCALCLASSPATH=%LOCALCLASSPATH%;%FOP_HYPHENATION_PATH%\r
 \r
+set JAVAOPTS=-Denv.windir=%WINDIR%\r
+\r
 if "%JAVA_HOME%" == "" goto noJavaHome\r
 if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome\r
 if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java\r
@@ -80,5 +82,4 @@ if "%JAVACMD%" == "" set JAVACMD=java
 \r
 :runFop\r
 rem ECHO "%JAVACMD%"\r
-"%JAVACMD%" %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
-\r
+"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
diff --git a/fop.cmd b/fop.cmd
index 80b6c23b1cf40e983380fe9ab0137e636bcb95d7..554b8079565b2e31bcdbc13a64f365e8ea3eb8b7 100644 (file)
--- a/fop.cmd
+++ b/fop.cmd
@@ -58,6 +58,8 @@ set LIBDIR=%LOCAL_FOP_HOME%lib
 set LOCALCLASSPATH=%FOP_HYPHENATION_PATH%\r
 for %%l in (%LOCAL_FOP_HOME%build\*.jar %LIBDIR%\*.jar) do set LOCALCLASSPATH=!LOCALCLASSPATH!;%%l\r
 \r
+set JAVAOPTS=-Denv.windir=%WINDIR%\r
+\r
 if "%JAVA_HOME%" == "" goto noJavaHome\r
 if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome\r
 if "%JAVACMD%" == "" set JAVACMD=%JAVA_HOME%\bin\java\r
@@ -68,6 +70,6 @@ if "%JAVACMD%" == "" set JAVACMD=java
 \r
 :runFop\r
 rem echo "%JAVACMD%" %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
-"%JAVACMD%" %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
+"%JAVACMD%" %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%\r
 \r
 ENDLOCAL\r
diff --git a/lib/commons-io-1.1.jar b/lib/commons-io-1.1.jar
deleted file mode 100644 (file)
index 624fc1a..0000000
Binary files a/lib/commons-io-1.1.jar and /dev/null differ
diff --git a/lib/commons-io-1.3.1.jar b/lib/commons-io-1.3.1.jar
new file mode 100644 (file)
index 0000000..7affdef
Binary files /dev/null and b/lib/commons-io-1.3.1.jar differ
index 439eb83b2f4dc494445cc3f7eec190c760b77f4f..ce3b94a0fd273fab5c4813ea1bab9879de107473 100644 (file)
@@ -1,3 +1,6 @@
+Apache Jakarta Commons IO
+Copyright 2001-2007 The Apache Software Foundation
+
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).
 
index 7032379cafcdc1c22bbc470110b530fb17c6038d..b7984e773e6d3e8061bea142e79999c9e93e8b5d 100644 (file)
           default-page-settings element to specify the two values.</td>
         <td>"height" 11 inches, "width" 8.26 inches</td>
       </tr>
+      <tr>
+        <td>use-cache</td>
+        <td>boolean (true, false)</td>
+        <td>All fonts information that has been gathered as a result of "directory"
+        or "auto-detect" font configurations will be cached for future rendering runs.
+        This setting should improve performance on systems where
+        fonts have been configured using the "directory" or "auto-detect" tag mechanisms.
+        By default this option is switched on.</td>
+        <td>true</td>
+      </tr>
+      <tr>
+        <td>cache-file</td>
+        <td>String</td>
+        <td>This options specifies the file/directory path of the fop cache file.
+        This option can also be specified on the command-line using the -cache option.
+        This file is currently only used to cache font triplet information for future reference.</td>
+        <td>${base}/conf/fop.cache</td>
+      </tr>
       <tr>
         <td>renderers</td>
         <td>(see text below)</td>
index ca6209c6d7ca2a5b7fabd7386e86194f5249a7fd..2ee297ba0b8c0aabb907b6f22bccee5775a2c7a1 100644 (file)
@@ -24,6 +24,7 @@
     <authors>
       <person name="Jeremias Märki" email=""/>
       <person name="Tore Engvig" email=""/>
+      <person name="Adrian Cumiskey" email=""/>
     </authors>
   </header>
   <body>
 More information about fonts can be found at:</p>
       <ul>
         <li><a href="http://partners.adobe.com/asn/developer/type/ftypes.html">Adobe font types</a></li>
-        <li><a href="http://partners.adobe.com/asn/developer/technotes/fonts.html">Adobe Font Technote</a>
-</li>
+        <li><a href="http://partners.adobe.com/asn/developer/technotes/fonts.html">Adobe Font Technote</a></li>
       </ul>
       <section id="type1-metrics">
         <title>Type 1 Font Metrics</title>
@@ -236,10 +236,24 @@ It will display all of the font names and exit with an Exception.</p>
       <section id="register">
         <title>Register Fonts with FOP</title>
         <p>You must tell FOP how to find and use the font metrics files by registering them in the <a href="configuration.html">FOP Configuration</a>. Add entries for your custom fonts, regardless of font type, to the configuration file in a manner similar to the following:</p>
-        <source><![CDATA[<font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes"
+        <source><![CDATA[
+<fonts>
+  <!-- register a particular font -->
+  <font metrics-url="file:///C:/myfonts/FTL_____.xml" kerning="yes"
       embed-url="file:///C:/myfonts/FTL_____.pfb">
-  <font-triplet name="FrutigerLight" style="normal" weight="normal"/>
-</font>]]></source>
+     <font-triplet name="FrutigerLight" style="normal" weight="normal"/>
+  </font>
+  
+  <!-- register all the fonts found in a directory -->
+  <directory>C:\MyFonts1</directory>
+  
+  <!-- register all the fonts found in a directory
+       and all of its sub directories (use with care) -->
+  <directory recursive="true">C:\MyFonts2</directory>
+
+  <!-- automatically detect operating system installed fonts -->
+  <auto-detect/>  
+</fonts>]]></source>
         <note>Review the documentation for <a href="configuration.html">FOP Configuration</a> for instructions on making the FOP configuration available to FOP when it runs. Otherwise, FOP has no way of finding your custom font information.</note>
         <ul>
           <li>
@@ -247,8 +261,14 @@ It will display all of the font names and exit with an Exception.</p>
             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.
           </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>
+          <li>Either an "embed-url" or a "metrics-url" must be specified for font tag configurations.</li>
+          <li>The font "kerning" attribute is optional. Kerning is currently not used at all.</li>
+             <li>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>
+          <li>The fonts "directory" tag can be used to register fonts contained within a single or list of directory paths.  The "recursive" attribute can be specified to recursively add fonts from all sub directories.</li>
+          <li>The fonts "auto-detect" tag can be used to automatically register fonts that are found to be installed on the native operating system.</li>
+          <li>Fonts registered with "font" tag configurations override fonts found by means of "directory" tag definitions.</li>
+          <li>Fonts found as a result of a "directory" tag configuration override fonts found as a result of the "auto-detect" tag being specified.</li>
           <li>
             If relative URLs are specified, they are evaluated relative to the value of the 
             "font-base" setting. If there is no "font-base" setting, the fonts are evaluated 
@@ -281,7 +301,7 @@ Characters will be WinAnsi encoded (as specified in the PDF spec), so you lose t
 See <a href="#ttf-encoding">Table of TTF Encoding Options</a> for more details.</p>
       </section>
       <section id="embedding-base14">
-        <title>Explicitely embedding the base 14 fonts</title>
+        <title>Explicitly embedding the base 14 fonts</title>
         <p>
           There are cases where you might want to force the embedding of one or more of the base 14 fonts that
           can normally be considered available on the target platform (viewer, printer). One of these cases is
index e3ffd22cc89abd5b56148112862cefa19e5ced6c..13baeaa56b1666a70650072ad0d7dd1b3fe49725 100644 (file)
@@ -29,6 +29,7 @@ import java.net.URL;
 import java.net.URLConnection;
 
 import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
 import javax.xml.transform.stream.StreamSource;
 
 // commons logging
@@ -47,8 +48,41 @@ import org.apache.xmlgraphics.util.io.Base64EncodeStream;
 public class FOURIResolver
     implements javax.xml.transform.URIResolver {
     
+    // log
     private Log log = LogFactory.getLog("FOP");
+
+    // true if exceptions are to be thrown if the URIs cannot be resolved.
+    private boolean throwExceptions = false;
+
+    /**
+     * Default constructor
+     */
+    public FOURIResolver() {
+        this(false);
+    }
     
+    /**
+     * Additional constructor
+     * @param throwExceptions true if exceptions are to be thrown if the URIs cannot be
+     *              resolved.
+     */
+    public FOURIResolver(boolean throwExceptions) {
+        this.throwExceptions = throwExceptions;
+    }
+    
+    /**
+     * Handles resolve exceptions appropriately.
+     * @param errorStr error string
+     * @param strict strict user config
+     */
+    private void handleException(Exception e, String errorStr, boolean strict)
+    throws TransformerException {
+        if (strict) {
+            throw new TransformerException(errorStr, e);
+        }
+        log.error(e.getMessage());
+    }
+
     /**
      * Called by the processor through {@link FOUserAgent} when it encounters an 
      * uri in an external-graphic element.
@@ -70,31 +104,25 @@ public class FOURIResolver
      * @throws javax.xml.transform.TransformerException Never thrown by this implementation.
      * @see javax.xml.transform.URIResolver#resolve(String, String)
      */
-    public Source resolve(String href, String base)
-        throws javax.xml.transform.TransformerException {
-        
-        //data URLs can be quite long so don't try to build a File (can lead to problems)
+    public Source resolve(String href, String base) throws TransformerException {        
+        // data URLs can be quite long so don't try to build a File (can lead to problems)
         if (href.startsWith("data:")) {
             return parseDataURI(href);
         }
-        
+
         URL absoluteURL = null;
-        File f = new File(href);
-        if (f.exists()) {
+        File file = new File(href);
+        if (file.canRead() && file.isFile()) {
             try {
-                absoluteURL = f.toURL();
+                absoluteURL = file.toURL();
             } catch (MalformedURLException mfue) {
-                log.error("Could not convert filename to URL: " + mfue.getMessage()); 
+                handleException(mfue,
+                        "Could not convert filename '" + href + "' to URL", throwExceptions);
             }
         } else {
-            URL baseURL = null;
-            try {
-                baseURL = toBaseURL(base);
-            } catch (MalformedURLException mfue) {
-                log.error("Error with base URL \"" + base + "\"): " + mfue.getMessage());
-            }
-            if (baseURL == null) {
-                // We don't have a valid baseURL just use the URL as given
+            // no base provided
+            if (base == null) {
+                // We don't have a valid file protocol based URL
                 try {
                     absoluteURL = new URL(href);
                 } catch (MalformedURLException mue) {
@@ -103,64 +131,78 @@ public class FOURIResolver
                         // the href contains only a path then file: is assumed
                         absoluteURL = new URL("file:" + href);
                     } catch (MalformedURLException mfue) {
-                        log.error("Error with URL '" + href + "': " + mue.getMessage());
-                        return null;
+                        handleException(mfue,
+                                "Error with URL '" + href + "'", throwExceptions);
                     }
                 }
+
+            // try and resolve from context of base
             } else {
+                URL baseURL = null;
                 try {
-                    /*
-                        This piece of code is based on the following statement in 
-                        RFC2396 section 5.2:
-
-                        3) If the scheme component is defined, indicating that the reference
-                           starts with a scheme name, then the reference is interpreted as an
-                           absolute URI and we are done.  Otherwise, the reference URI's
-                           scheme is inherited from the base URI's scheme component.
-
-                           Due to a loophole in prior specifications [RFC1630], some parsers
-                           allow the scheme name to be present in a relative URI if it is the
-                           same as the base URI scheme.  Unfortunately, this can conflict
-                           with the correct parsing of non-hierarchical URI.  For backwards
-                           compatibility, an implementation may work around such references
-                           by removing the scheme if it matches that of the base URI and the
-                           scheme is known to always use the <hier_part> syntax.
-
-                        The URL class does not implement this work around, so we do.
-                    */
+                    baseURL = new URL(base);
+                } catch (MalformedURLException mfue) {
+                    handleException(mfue, "Error with base URL '" + base + "'", throwExceptions);
+                }
 
-                    String scheme = baseURL.getProtocol() + ":";
-                    if (href.startsWith(scheme)) {
-                        href = href.substring(scheme.length());
-                        if ("file:".equals(scheme)) {
-                            int colonPos = href.indexOf(':');
-                            int slashPos = href.indexOf('/');
-                            if (slashPos >= 0 && colonPos >= 0 && colonPos < slashPos) {
-                                href = "/" + href; //Absolute file URL doesn't have a leading slash
-                            }
+                /*
+                 * This piece of code is based on the following statement in
+                 * RFC2396 section 5.2:
+                 * 
+                 * 3) If the scheme component is defined, indicating that the
+                 * reference starts with a scheme name, then the reference is
+                 * interpreted as an absolute URI and we are done. Otherwise,
+                 * the reference URI's scheme is inherited from the base URI's
+                 * scheme component.
+                 * 
+                 * Due to a loophole in prior specifications [RFC1630], some
+                 * parsers allow the scheme name to be present in a relative URI
+                 * if it is the same as the base URI scheme. Unfortunately, this
+                 * can conflict with the correct parsing of non-hierarchical
+                 * URI. For backwards compatibility, an implementation may work
+                 * around such references by removing the scheme if it matches
+                 * that of the base URI and the scheme is known to always use
+                 * the <hier_part> syntax.
+                 * 
+                 * The URL class does not implement this work around, so we do.
+                 */
+                String scheme = baseURL.getProtocol() + ":";
+                if (href.startsWith(scheme)) {
+                    href = href.substring(scheme.length());
+                    if ("file:".equals(scheme)) {
+                        int colonPos = href.indexOf(':');
+                        int slashPos = href.indexOf('/');
+                        if (slashPos >= 0 && colonPos >= 0 && colonPos < slashPos) {
+                            href = "/" + href; // Absolute file URL doesn't
+                                                // have a leading slash
                         }
                     }
+                }
+                try {
                     absoluteURL = new URL(baseURL, href);
                 } catch (MalformedURLException mfue) {
-                    log.error("Error with URL '" + href + "': " + mfue.getMessage());
-                    return null;
+                    handleException(mfue,
+                            "Error with URL; base '" + base + "' " + "href '" + href + "'",
+                            throwExceptions);                        
                 }
             }
         }
         
-        String effURL = absoluteURL.toExternalForm();
-        try {
-            URLConnection connection = absoluteURL.openConnection();
-            connection.setAllowUserInteraction(false);
-            connection.setDoInput(true);
-            updateURLConnection(connection, href);
-            connection.connect();
-            return new StreamSource(connection.getInputStream(), effURL);
-        } catch (FileNotFoundException fnfe) {
-            //Note: This is on "debug" level since the caller is supposed to handle this
-            log.debug("File not found: " + effURL);
-        } catch (java.io.IOException ioe) {
-            log.error("Error with opening URL '" + effURL + "': " + ioe.getMessage());
+        if (absoluteURL != null) {
+            String effURL = absoluteURL.toExternalForm();
+            try {
+                URLConnection connection = absoluteURL.openConnection();
+                connection.setAllowUserInteraction(false);
+                connection.setDoInput(true);
+                updateURLConnection(connection, href);
+                connection.connect();
+                return new StreamSource(connection.getInputStream(), effURL);
+            } catch (FileNotFoundException fnfe) {
+                //Note: This is on "debug" level since the caller is supposed to handle this
+                log.debug("File not found: " + effURL);
+            } catch (java.io.IOException ioe) {
+                log.error("Error with opening URL '" + effURL + "': " + ioe.getMessage());
+            }
         }
         return null;
     }
@@ -200,29 +242,6 @@ public class FOURIResolver
         }
     }
     
-    /**
-     * Returns the base URL as a java.net.URL.
-     * If the base URL is not set a default URL pointing to the
-     * current directory is returned.
-     * @param baseURL the base URL
-     * @returns the base URL as java.net.URL
-     */
-    private URL toBaseURL(String base) throws MalformedURLException {
-        if (base == null) {
-            return new java.io.File("").toURL();
-        }
-        if (!base.endsWith("/")) {
-            // The behavior described by RFC 3986 regarding resolution of relative
-            // references may be misleading for normal users:
-            // file://path/to/resources + myResource.res -> file://path/to/myResource.res
-            // file://path/to/resources/ + myResource.res -> file://path/to/resources/myResource.res
-            // We assume that even when the ending slash is missing, users have the second
-            // example in mind
-            base += "/";
-        }
-        return new URL(base);
-    }
-
     /**
      * Parses inline data URIs as generated by MS Word's XML export and FO stylesheet.
      * @see <a href="http://www.ietf.org/rfc/rfc2397">RFC 2397</a>
index f15ddcc31dffac61af9d8a71c004934d6ac8cb1d..24df2f75b0a68d0bf41486d9114f60d3ea99a32d 100644 (file)
@@ -63,19 +63,25 @@ import org.apache.fop.render.pdf.PDFRenderer;
 public class FOUserAgent {
 
     /** Defines the default target resolution (72dpi) for FOP */
-    public static final float DEFAULT_TARGET_RESOLUTION = FopFactory.DEFAULT_TARGET_RESOLUTION;
+    public static final float DEFAULT_TARGET_RESOLUTION = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
 
     private static Log log = LogFactory.getLog("FOP");
 
     private FopFactory factory;
     
-    /** The base URL for all URL resolutions, especially for external-graphics */
-    private String baseURL;
-    
+    /**
+     *  The base URL for all URL resolutions, especially for
+     *  external-graphics.
+     */
+    private String base = null;
+
+    /** The base URL for all font URL resolutions. */
+    private String fontBase = null;
+
     /** A user settable URI Resolver */
     private URIResolver uriResolver = null;
     
-    private float targetResolution = DEFAULT_TARGET_RESOLUTION;
+    private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
     private Map rendererOptions = new java.util.HashMap();
     private File outputFile = null;
     private Renderer rendererOverride = null;
@@ -105,7 +111,6 @@ public class FOUserAgent {
     
     /**
      * Default constructor
-     * @throws FOPException 
      * @see org.apache.fop.apps.FopFactory
      * @deprecated Provided for compatibility only. Please use the methods from 
      *             FopFactory to construct FOUserAgent instances!
@@ -126,6 +131,7 @@ public class FOUserAgent {
         }
         this.factory = factory;
         setBaseURL(factory.getBaseURL());
+        setFontBaseURL(factory.getFontBaseURL());
         setTargetResolution(factory.getTargetResolution());
     }
     
@@ -277,10 +283,18 @@ public class FOUserAgent {
     
     /**
      * Sets the base URL.
-     * @param baseURL base URL
+     * @param baseUrl base URL
      */
-    public void setBaseURL(String baseURL) {
-        this.baseURL = baseURL;
+    public void setBaseURL(String baseUrl) {
+        this.base = baseUrl;
+    }
+
+    /**
+     * sets font base URL
+     * @param fontBaseUrl font base URL
+     */
+    public void setFontBaseURL(String fontBaseUrl) {
+        this.fontBase = fontBaseUrl;
     }
 
     /**
@@ -288,7 +302,7 @@ public class FOUserAgent {
      * @return the base URL
      */
     public String getBaseURL() {
-        return this.baseURL;
+        return this.base;
     }
 
     /**
@@ -410,8 +424,10 @@ public class FOUserAgent {
      */
     public void setTargetResolution(float dpi) {
         this.targetResolution = dpi;
-        log.info("target-resolution set to: " + targetResolution 
-                + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
+        if (log.isDebugEnabled()) {
+            log.debug("target-resolution set to: " + targetResolution 
+                    + "dpi (px2mm=" + getTargetPixelUnitToMillimeter() + ")");
+        }
     }
 
     /**
@@ -429,8 +445,7 @@ public class FOUserAgent {
 
     /** @return the font base URL */
     public String getFontBaseURL() {
-        String fontBaseURL = getFactory().getFontBaseURL(); 
-        return fontBaseURL != null ? fontBaseURL : getBaseURL();
+        return fontBase != null ? fontBase : getBaseURL();
     }
 
     /**
index f7a3bd251348606ec05dbde016d53886cc4edc1e..1e7ab2a62ca14cfce3657e51b9a3d26c6500d0f3 100644 (file)
@@ -26,6 +26,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
@@ -39,14 +40,13 @@ import javax.xml.transform.stream.StreamSource;
 import org.xml.sax.SAXException;
 
 import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.apache.fop.fo.ElementMapping;
 import org.apache.fop.fo.ElementMappingRegistry;
+import org.apache.fop.fonts.FontCache;
 import org.apache.fop.hyphenation.HyphenationTreeResolver;
 import org.apache.fop.image.ImageFactory;
 import org.apache.fop.layoutmgr.LayoutManagerMaker;
@@ -62,27 +62,6 @@ import org.apache.fop.util.ContentHandlerFactoryRegistry;
  */
 public class FopFactory {
     
-    /** Defines the default target resolution (72dpi) for FOP */
-    public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi
-
-    /** Defines the default source resolution (72dpi) for FOP */
-    private static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi
-
-    /** Defines the default page-height */
-    private static final String DEFAULT_PAGE_HEIGHT = "11in";
-    
-    /** Defines the default page-width */
-    private static final String DEFAULT_PAGE_WIDTH = "8.26in";
-    
-    /** Defines if FOP should use strict validation for FO and user config */
-    private static final boolean DEFAULT_STRICT_FO_VALIDATION = true;
-
-    /** Defines if FOP should validate the user config strictly */
-    private static final boolean DEFAULT_STRICT_USERCONFIG_VALIDATION = true;
-    
-    /** Defines if FOP should use an alternative rule to determine text indents */
-    private static final boolean DEFAULT_BREAK_INDENT_INHERITANCE = false;
-
     /** logger instance */
     private static Log log = LogFactory.getLog(FopFactory.class);
     
@@ -100,7 +79,7 @@ public class FopFactory {
                 = new ContentHandlerFactoryRegistry();
     
     /** Our default resolver if none is set */
-    private URIResolver foURIResolver = new FOURIResolver();
+    private URIResolver foURIResolver = null;
     
     /** A user settable URI Resolver */
     private URIResolver uriResolver = null;
@@ -108,22 +87,23 @@ public class FopFactory {
     /** The resolver for user-supplied hyphenation patterns */
     private HyphenationTreeResolver hyphResolver;
     
+    /** Image factory for creating fop image objects */
     private ImageFactory imageFactory = new ImageFactory();
 
-    /** user configuration */
-    private Configuration userConfig = null;
-
+    /** Configuration layer used to configure fop */
+    private FopFactoryConfigurator config = null;
+        
     /**
      *  The base URL for all URL resolutions, especially for
      *  external-graphics.
      */
-    private String baseURL;
+    private String base = null;
 
     /** The base URL for all font URL resolutions. */
-    private String fontBaseURL;
+    private String fontBase = null;
 
     /** The base URL for all hyphen URL resolutions. */
-    private String hyphenBaseURL;
+    private String hyphenBase = null;
 
     /**
      * FOP has the ability, for some FO's, to continue processing even if the
@@ -131,32 +111,36 @@ public class FopFactory {
      * behavior for FOP.  However, this flag, if set, provides the user the
      * ability for FOP to halt on all content model violations if desired.
      */ 
-    private boolean strictFOValidation = DEFAULT_STRICT_FO_VALIDATION;
+    private boolean strictFOValidation = FopFactoryConfigurator.DEFAULT_STRICT_FO_VALIDATION;
 
     /**
      * FOP will validate the contents of the user configuration strictly
      * (e.g. base-urls and font urls/paths).
      */
-    private boolean strictUserConfigValidation = DEFAULT_STRICT_USERCONFIG_VALIDATION;
-    
+    private boolean strictUserConfigValidation
+        = FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION;
+
+    /** Font cache to speed up auto-font configuration (null if disabled) */
+    private FontCache fontCache = null;
+
     /** Allows enabling kerning on the base 14 fonts, default is false */
     private boolean enableBase14Kerning = false;
     
     /** Source resolution in dpi */
-    private float sourceResolution = DEFAULT_SOURCE_RESOLUTION;
+    private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION;
 
     /** Target resolution in dpi */
-    private float targetResolution = DEFAULT_TARGET_RESOLUTION;
+    private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
 
     /** Page height */
-    private String pageHeight = DEFAULT_PAGE_HEIGHT;
+    private String pageHeight = FopFactoryConfigurator.DEFAULT_PAGE_HEIGHT;
     
     /** Page width */
-    private String pageWidth = DEFAULT_PAGE_WIDTH;
+    private String pageWidth = FopFactoryConfigurator.DEFAULT_PAGE_WIDTH;
 
     /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
     private boolean breakIndentInheritanceOnReferenceAreaBoundary
-        = DEFAULT_BREAK_INDENT_INHERITANCE;
+        = FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE;
 
     /** Optional overriding LayoutManagerMaker */
     private LayoutManagerMaker lmMakerOverride = null;
@@ -165,14 +149,17 @@ public class FopFactory {
     
     /** Map with cached ICC based ColorSpace objects. */
     private Map colorSpaceMap = null;
-    
+        
     /**
      * Main constructor.
      */
     protected FopFactory() {
+        this.config = new FopFactoryConfigurator(this);
         this.elementMappingRegistry = new ElementMappingRegistry(this);
+        this.foURIResolver = new FOURIResolver(validateUserConfigStrictly());
         // Use a synchronized Map - I am not really sure this is needed, but better safe than sorry.
         this.colorSpaceMap = Collections.synchronizedMap(new java.util.HashMap());
+        setUseCache(FopFactoryConfigurator.DEFAULT_USE_CACHE);
     }
     
     /**
@@ -335,12 +322,43 @@ public class FopFactory {
         return this.lmMakerOverride;
     }
 
+    /**
+     * cleans the base url
+     * @param base
+     * @return
+     * @throws MalformedURLException
+     * @throws URISyntaxException 
+     */
+    private String checkBaseURL(String base) throws MalformedURLException {
+        if (!base.endsWith("/")) {
+            // The behavior described by RFC 3986 regarding resolution of relative
+            // references may be misleading for normal users:
+            // file://path/to/resources + myResource.res -> file://path/to/myResource.res
+            // file://path/to/resources/ + myResource.res -> file://path/to/resources/myResource.res
+            // We assume that even when the ending slash is missing, users have the second
+            // example in mind
+            base += "/";
+        }
+        File dir = new File(base);
+        try {
+            base = (dir.isDirectory() ? dir.toURL() : new URL(base)).toExternalForm(); 
+        } catch (MalformedURLException mfue) {
+            if (strictUserConfigValidation) {
+                throw mfue;
+            }
+            log.error(mfue.getMessage());
+        }
+        return base;
+    }
+    
     /**
      * Sets the base URL.
-     * @param baseURL base URL
+     * @param base base URL
+     * @throws MalformedURLException 
+     * @throws URISyntaxException 
      */
-    void setBaseURL(String baseURL) {
-        this.baseURL = baseURL;
+    public void setBaseURL(String base) throws MalformedURLException {
+        this.base = checkBaseURL(base);
     }
 
     /**
@@ -348,42 +366,46 @@ public class FopFactory {
      * @return the base URL
      */
     public String getBaseURL() {
-        return this.baseURL;
+        return this.base;
     }
-
+    
     /**
      * Sets the font base URL.
-     * @param fontBaseURL font base URL
+     * @param fontBase font base URL
+     * @throws MalformedURLException 
+     * @throws URISyntaxException 
      */
-    public void setFontBaseURL(String fontBaseURL) {
-        this.fontBaseURL = fontBaseURL;
+    public void setFontBaseURL(String fontBase) throws MalformedURLException {
+        this.fontBase = checkBaseURL(fontBase);
     }
 
     /** @return the font base URL */
     public String getFontBaseURL() {
-        return this.fontBaseURL;
+        return this.fontBase;
     }
 
     /** @return the hyphen base URL */
     public String getHyphenBaseURL() {
-        return hyphenBaseURL;
+        return this.hyphenBase;
     }
 
     /**
      * Sets the hyphen base URL.
-     * @param hyphenBaseURL hythen base URL
-     */
-    public void setHyphenBaseURL(final String hyphenBaseURL) {
-        if (hyphenBaseURL != null) {
+     * @param hyphenBase hythen base URL
+     * @throws MalformedURLException 
+     * @throws URISyntaxException 
+     * */
+    public void setHyphenBaseURL(final String hyphenBase) throws MalformedURLException {
+        if (hyphenBase != null) {
             this.hyphResolver = new HyphenationTreeResolver() {
                 public Source resolve(String href) {
-                    return resolveURI(href, hyphenBaseURL);
+                    return resolveURI(href, hyphenBase);
                 }
             };
         }
-        this.hyphenBaseURL = hyphenBaseURL;
+        this.hyphenBase = checkBaseURL(hyphenBase);
     }
-
+    
     /**
      * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation
      * patterns and as backup for URI resolution performed during a rendering run. 
@@ -483,8 +505,10 @@ public class FopFactory {
      */
     public void setSourceResolution(float dpi) {
         this.sourceResolution = dpi;
-        log.info("source-resolution set to: " + sourceResolution 
-                + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
+        if (log.isDebugEnabled()) {
+            log.debug("source-resolution set to: " + sourceResolution 
+                    + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
+        }
     }
 
     /** @return the resolution for resolution-dependant output */
@@ -538,7 +562,9 @@ public class FopFactory {
      */
     public void setPageHeight(String pageHeight) {
         this.pageHeight = pageHeight;
-        log.info("Default page-height set to: " + pageHeight);
+        if (log.isDebugEnabled()) {
+            log.debug("Default page-height set to: " + pageHeight);
+        }
     }
     
     /**
@@ -559,7 +585,9 @@ public class FopFactory {
      */
     public void setPageWidth(String pageWidth) {
         this.pageWidth = pageWidth;
-        log.info("Default page-width set to: " + pageWidth);
+        if (log.isDebugEnabled()) {
+            log.debug("Default page-width set to: " + pageWidth);
+        }
     }
     
     /**
@@ -595,7 +623,7 @@ public class FopFactory {
     public Set getIgnoredNamespace() {
         return Collections.unmodifiableSet(this.ignoredNamespaces);
     }
-    
+
     //------------------------------------------- Configuration stuff
     
     /**
@@ -605,14 +633,9 @@ public class FopFactory {
      * @throws SAXException if a parsing error occurs
      */
     public void setUserConfig(File userConfigFile) throws SAXException, IOException {
-        try {
-            DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
-            setUserConfig(cfgBuilder.buildFromFile(userConfigFile));
-        } catch (ConfigurationException e) {
-            throw new FOPException(e);
-        }
+        config.setUserConfig(userConfigFile);
     }
-    
+
     /**
      * Set the user configuration from an URI.
      * @param uri the URI to the configuration file
@@ -620,12 +643,7 @@ public class FopFactory {
      * @throws SAXException if a parsing error occurs
      */
     public void setUserConfig(String uri) throws SAXException, IOException {
-        try {
-            DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
-            setUserConfig(cfgBuilder.build(uri));
-        } catch (ConfigurationException e) {
-            throw new FOPException(e);
-        }
+        config.setUserConfig(uri);
     }
     
     /**
@@ -634,12 +652,7 @@ public class FopFactory {
      * @throws FOPException if a configuration problem occurs 
      */
     public void setUserConfig(Configuration userConfig) throws FOPException {
-        this.userConfig = userConfig;
-        try {
-            configure(userConfig);
-        } catch (ConfigurationException e) {            
-            throw new FOPException(e);
-        }
+        config.setUserConfig(userConfig);
     }
 
     /**
@@ -647,162 +660,54 @@ public class FopFactory {
      * @return the user configuration
      */
     public Configuration getUserConfig() {
-        return userConfig;
+        return config.getUserConfig();
     }
 
     /**
-     * Returns the configuration subtree for a specific renderer.
-     * @param mimeType MIME type of the renderer
-     * @return the requested configuration subtree, null if there's no configuration
+     * Is the user configuration to be validated?
+     * @param strictUserConfigValidation strict user config validation
      */
-    public Configuration getUserRendererConfig(String mimeType) {
-        if (userConfig == null || mimeType == null) {
-            return null;
-        }
-        
-        Configuration userRendererConfig = null;
-
-        Configuration[] cfgs
-            = userConfig.getChild("renderers").getChildren("renderer");
-        for (int i = 0; i < cfgs.length; ++i) {
-            Configuration child = cfgs[i];
-            try {
-                if (child.getAttribute("mime").equals(mimeType)) {
-                    userRendererConfig = child;
-                    break;
-                }
-            } catch (ConfigurationException e) {
-                // silently pass over configurations without mime type
-            }
-        }
-        log.debug((userRendererConfig == null ? "No u" : "U")
-                  + "ser configuration found for MIME type " + mimeType);
-        return userRendererConfig;
+    public void setStrictUserConfigValidation(boolean strictUserConfigValidation) {
+        this.strictUserConfigValidation = strictUserConfigValidation;
     }
 
     /**
-     * Initializes user agent settings from the user configuration
-     * file, if present: baseURL, resolution, default page size,...
-     * 
-     * @throws ConfigurationException when there is an entry that 
-     *          misses the required attribute
-     * Configures the FopFactory.
-     * @param cfg Avalon Configuration Object
-     * @see org.apache.avalon.framework.configuration.Configurable
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {        
-        log.info("Initializing FopFactory Configuration");        
-        
-        if (cfg.getChild("strict-configuration", false) != null) {
-            this.strictUserConfigValidation
-                    = cfg.getChild("strict-configuration").getValueAsBoolean();
-        }
-        if (cfg.getChild("strict-validation", false) != null) {
-            this.strictFOValidation = cfg.getChild("strict-validation").getValueAsBoolean();
-        }
-        if (cfg.getChild("base", false) != null) {
-            try {
-                setBaseURL(getBaseURLfromConfig(cfg, "base"));
-            } catch (ConfigurationException e) {
-                if (strictUserConfigValidation) {
-                    throw e;
-                }
-                log.error(e.getMessage());
-            }
-        }
-        if (cfg.getChild("font-base", false) != null) {
-            try {
-                setFontBaseURL(getBaseURLfromConfig(cfg, "font-base"));
-            } catch (ConfigurationException e) {
-                if (strictUserConfigValidation) {
-                    throw e;
-                }
-                log.error(e.getMessage());
-            }
-        }
-        if (cfg.getChild("hyphenation-base", false) != null) {
-            try {
-                setHyphenBaseURL(getBaseURLfromConfig(cfg, "hyphenation-base"));
-            } catch (ConfigurationException e) {
-                if (strictUserConfigValidation) {
-                    throw e;
-                }
-                log.error(e.getMessage());
-            }
-        }
-        if (cfg.getChild("source-resolution", false) != null) {
-            setSourceResolution(
-                    cfg.getChild("source-resolution").getValueAsFloat(DEFAULT_SOURCE_RESOLUTION));
-        }
-        if (cfg.getChild("target-resolution", false) != null) {
-            setTargetResolution(
-                    cfg.getChild("target-resolution").getValueAsFloat(DEFAULT_TARGET_RESOLUTION));
-        }
-        if (cfg.getChild("break-indent-inheritance", false) != null) {
-            setBreakIndentInheritanceOnReferenceAreaBoundary(
-                    cfg.getChild("break-indent-inheritance").getValueAsBoolean());
-        }        
-        Configuration pageConfig = cfg.getChild("default-page-settings");
-        if (pageConfig.getAttribute("height", null) != null) {
-            setPageHeight(pageConfig.getAttribute("height", DEFAULT_PAGE_HEIGHT));
-        }
-        if (pageConfig.getAttribute("width", null) != null) {
-            setPageWidth(pageConfig.getAttribute("width", DEFAULT_PAGE_WIDTH));
-        }
+     * Is the user configuration to be validated?
+     * @return if the user configuration should be validated
+     */
+    public boolean validateUserConfigStrictly() {
+        return this.strictUserConfigValidation;
     }
 
+    //------------------------------------------- Cache related stuff
+
     /**
-     * Retrieves and verifies a base URL.
-     * @param cfg The Configuration object to retrieve the base URL from
-     * @param name the element name for the base URL
-     * @return the requested base URL or null if not available
-     * @throws ConfigurationException 
-     */    
-    public static String getBaseURLfromConfig(Configuration cfg, String name)
-    throws ConfigurationException {
-        if (cfg.getChild(name, false) != null) {
-            try {
-                String cfgBasePath = cfg.getChild(name).getValue(null);
-                if (cfgBasePath != null) {
-                    // Is the path a dirname?
-                    File dir = new File(cfgBasePath);
-//                    if (!dir.exists()) {
-//                        throw new ConfigurationException("Base URL '" + name
-//                                + "' references non-existent resource '"
-//                                + cfgBasePath + "'");
-//                    } else if (dir.isDirectory()) {
-                    if (dir.isDirectory()) {
-                        // Yes, convert it into a URL
-                        cfgBasePath = dir.toURL().toExternalForm(); 
-                    }
-                    // Otherwise, this is already a URL
-                }
-                log.info(name + " set to: " + cfgBasePath);
-                return cfgBasePath;
-            } catch (MalformedURLException mue) {
-                throw new ConfigurationException("Base URL '" + name
-                        + "' in user config is malformed!");
+     * Whether or not to cache results of font triplet detection/auto-config
+     * @param useCache use cache or not
+     */
+    public void setUseCache(boolean useCache) {
+        if (useCache) {
+            this.fontCache = FontCache.load();
+            if (this.fontCache == null) {
+                this.fontCache = new FontCache();
             }
+        } else {
+            this.fontCache = null;
         }
-        return null;
     }
 
     /**
-     * Is the user configuration to be validated?
-     * @param strictUserConfigValidation strict user config validation
+     * Cache results of font triplet detection/auto-config?
+     * @return whether this factory is uses the cache
      */
-    public void setStrictUserConfigValidation(boolean strictUserConfigValidation) {
-        this.strictUserConfigValidation = strictUserConfigValidation;
+    public boolean useCache() {
+        return (this.fontCache != null);
     }
 
-    /**
-     * Is the user configuration to be validated?
-     * @return if the user configuration should be validated
-     */
-    public boolean validateUserConfigStrictly() {
-        return this.strictUserConfigValidation;
+    public FontCache getFontCache() {
+        return this.fontCache;
     }
-
+    
     //------------------------------------------- URI resolution
 
     /**
@@ -810,26 +715,29 @@ public class FopFactory {
      * Will use the configured resolver and if not successful fall back
      * to the default resolver.
      * @param uri URI to access
-     * @param base the base URI to resolve against
+     * @param baseUri the base URI 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 base) {
+    public Source resolveURI(String uri, String baseUri) {
         Source source = null;
         //RFC 2397 data URLs don't need to be resolved, just decode them.
         boolean bypassURIResolution = uri.startsWith("data:");
         if (!bypassURIResolution && uriResolver != null) {
             try {
-                source = uriResolver.resolve(uri, base);
+                source = uriResolver.resolve(uri, baseUri);
             } catch (TransformerException te) {
                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
+                if (validateUserConfigStrictly()) {
+                    return null;
+                }
             }
         }
         if (source == null) {
             // URI Resolver not configured or returned null, use default resolver
             try {
-                source = foURIResolver.resolve(uri, base);
+                source = foURIResolver.resolve(uri, baseUri);
             } catch (TransformerException te) {
                 log.error("Attempt to resolve URI '" + uri + "' failed: ", te);
             }
@@ -846,18 +754,18 @@ public class FopFactory {
      * The FOP URI resolver is used to try and locate the ICC file. 
      * If that fails null is returned.
      * 
-     * @param base a base URI to resolve relative URIs
+     * @param baseUri a base URI to resolve relative URIs
      * @param iccProfileSrc ICC Profile source to return a ColorSpace for
      * @return ICC ColorSpace object or null if ColorSpace could not be created 
      */
-    public ColorSpace getColorSpace(String base, String iccProfileSrc) {
+    public ColorSpace getColorSpace(String baseUri, String iccProfileSrc) {
         ColorSpace colorSpace = null;
-        if (!this.colorSpaceMap.containsKey(base + iccProfileSrc)) {
+        if (!this.colorSpaceMap.containsKey(baseUri + iccProfileSrc)) {
             try {
                 ICC_Profile iccProfile = null;
                 // First attempt to use the FOP URI resolver to locate the ICC
                 // profile
-                Source src = this.resolveURI(iccProfileSrc, base);
+                Source src = this.resolveURI(iccProfileSrc, baseUri);
                 if (src != null && src instanceof StreamSource) {
                     // FOP URI resolver found ICC profile - create ICC profile
                     // from the Source
@@ -882,16 +790,16 @@ public class FopFactory {
 
             if (colorSpace != null) {
                 // Put in cache (not when VM resolved it as we can't control
-                this.colorSpaceMap.put(base + iccProfileSrc, colorSpace);
+                this.colorSpaceMap.put(baseUri + iccProfileSrc, colorSpace);
             } else {
                 // TODO To avoid an excessive amount of warnings perhaps
                 // register a null ColorMap in the colorSpaceMap
                 log.warn("Color profile '" + iccProfileSrc + "' not found.");
             }
         } else {
-            colorSpace = (ColorSpace) this.colorSpaceMap.get(base
+            colorSpace = (ColorSpace) this.colorSpaceMap.get(baseUri
                     + iccProfileSrc);
         }
         return colorSpace;
-    }
+    }    
 }
diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java
new file mode 100644 (file)
index 0000000..d708cd9
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apps;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.util.LogUtil;
+import org.xml.sax.SAXException;
+
+/**
+ * FopFactory configurator
+ */
+public class FopFactoryConfigurator {
+
+    /** Defines if FOP should use an alternative rule to determine text indents */
+    public static final boolean DEFAULT_BREAK_INDENT_INHERITANCE = false;
+    
+    /** Defines if FOP should validate the user config strictly */
+    public static final boolean DEFAULT_STRICT_USERCONFIG_VALIDATION = true;
+    
+    /** Defines if FOP should use strict validation for FO and user config */
+    public static final boolean DEFAULT_STRICT_FO_VALIDATION = true;
+    
+    /** Defines the default page-width */
+    public static final String DEFAULT_PAGE_WIDTH = "8.26in";
+    
+    /** Defines the default page-height */
+    public static final String DEFAULT_PAGE_HEIGHT = "11in";
+    
+    /** Defines the default source resolution (72dpi) for FOP */
+    public static final float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi
+    
+    /** Defines the default target resolution (72dpi) for FOP */
+    public static final float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi
+    
+    /** Use cache (record previously detected font triplet info) */
+    public static final boolean DEFAULT_USE_CACHE = true;
+
+    /** logger instance */
+    private final Log log = LogFactory.getLog(FopFactoryConfigurator.class);
+
+    /** Fop factory */
+    private FopFactory factory = null;
+
+    /** Fop factory configuration */
+    private Configuration cfg = null;
+
+    /**
+     * Default constructor
+     * @param factory fop factory
+     */
+    public FopFactoryConfigurator(FopFactory factory) {
+        super();
+        this.factory = factory;
+    }
+    
+    /**
+     * Initializes user agent settings from the user configuration
+     * file, if present: baseURL, resolution, default page size,...
+     * @param factory fop factory
+     * @throws FOPException fop exception
+     */
+    public void configure(FopFactory factory) throws FOPException {
+        if (log.isDebugEnabled()) {
+            log.debug("Initializing FopFactory Configuration");        
+        }
+
+        // strict configuration
+        if (cfg.getChild("strict-configuration", false) != null) {
+            try {
+                factory.setStrictUserConfigValidation(
+                        cfg.getChild("strict-configuration").getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, false);
+            }
+        }        
+        boolean strict = factory.validateUserConfigStrictly();
+        
+        // strict fo validation
+        if (cfg.getChild("strict-validation", false) != null) {
+            try {
+                factory.setStrictValidation(
+                        cfg.getChild("strict-validation").getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, strict);
+            }
+        }
+
+        // base definitions for relative path resolution
+        if (cfg.getChild("base", false) != null) {
+            try {
+                factory.setBaseURL(
+                        cfg.getChild("base").getValue(null));
+            } catch (MalformedURLException mfue) {
+                LogUtil.handleException(log, mfue, strict);
+            }
+        }
+        if (cfg.getChild("font-base", false) != null) {
+            try {
+                factory.setFontBaseURL(
+                        cfg.getChild("font-base").getValue(null));
+            } catch (MalformedURLException mfue) {
+                LogUtil.handleException(log, mfue, strict);
+            }
+        }
+        if (cfg.getChild("hyphenation-base", false) != null) {
+            try {
+                factory.setHyphenBaseURL(
+                        cfg.getChild("hyphenation-base").getValue(null));
+            } catch (MalformedURLException mfue) {
+                LogUtil.handleException(log, mfue, strict);
+            }
+        }
+        
+        // renderer options
+        if (cfg.getChild("source-resolution", false) != null) {
+            factory.setSourceResolution(
+                    cfg.getChild("source-resolution").getValueAsFloat(
+                            FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION));
+            if (log.isDebugEnabled()) {
+                log.debug("source-resolution set to: " + factory.getSourceResolution() 
+                    + "dpi (px2mm=" + factory.getSourcePixelUnitToMillimeter() + ")");
+            }
+        }
+        if (cfg.getChild("target-resolution", false) != null) {
+            factory.setTargetResolution(
+                    cfg.getChild("target-resolution").getValueAsFloat(
+                            FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION));
+            if (log.isDebugEnabled()) {
+                log.debug("target-resolution set to: " + factory.getTargetResolution() 
+                        + "dpi (px2mm=" + factory.getTargetPixelUnitToMillimeter()
+                        + ")");                
+            }
+        }
+        if (cfg.getChild("break-indent-inheritance", false) != null) {
+            try {
+                factory.setBreakIndentInheritanceOnReferenceAreaBoundary(
+                        cfg.getChild("break-indent-inheritance").getValueAsBoolean());
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, strict);
+            }
+        }     
+        Configuration pageConfig = cfg.getChild("default-page-settings");
+        if (pageConfig.getAttribute("height", null) != null) {
+            factory.setPageHeight(
+                    pageConfig.getAttribute("height", FopFactoryConfigurator.DEFAULT_PAGE_HEIGHT));
+            if (log.isInfoEnabled()) {
+                log.info("Default page-height set to: " + factory.getPageHeight());        
+            }
+        }
+        if (pageConfig.getAttribute("width", null) != null) {
+            factory.setPageWidth(
+                    pageConfig.getAttribute("width", FopFactoryConfigurator.DEFAULT_PAGE_WIDTH));
+            if (log.isInfoEnabled()) {
+                log.info("Default page-width set to: " + factory.getPageWidth());
+            }
+        }
+
+        // caching (fonts)
+        if (cfg.getChild("use-cache", false) != null) {
+            try {
+                factory.setUseCache(
+                        cfg.getChild("use-cache").getValueAsBoolean());
+            } catch (ConfigurationException mfue) {
+                LogUtil.handleException(log, mfue, strict);
+            }
+        }
+    }
+    
+    /**
+     * Set the user configuration.
+     * @param userConfigFile the configuration file
+     * @throws IOException if an I/O error occurs
+     * @throws SAXException if a parsing error occurs
+     */
+    public void setUserConfig(File userConfigFile) throws SAXException, IOException {
+        try {
+            DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
+            setUserConfig(cfgBuilder.buildFromFile(userConfigFile));
+        } catch (ConfigurationException e) {
+            throw new FOPException(e);
+        }
+    }
+    
+    /**
+     * Set the user configuration from an URI.
+     * @param uri the URI to the configuration file
+     * @throws IOException if an I/O error occurs
+     * @throws SAXException if a parsing error occurs
+     */
+    public void setUserConfig(String uri) throws SAXException, IOException {
+        try {
+            DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
+            setUserConfig(cfgBuilder.build(uri));
+        } catch (ConfigurationException e) {
+            throw new FOPException(e);
+        }
+    }
+    
+    /**
+     * Set the user configuration.
+     * @param cfg avalon configuration
+     * @throws FOPException if a configuration problem occurs 
+     */
+    public void setUserConfig(Configuration cfg) throws FOPException {
+        this.cfg = cfg;
+        configure(this.factory);
+    }
+    
+    /**
+     * Get the avalon user configuration.
+     * @return the user configuration
+     */
+    public Configuration getUserConfig() {
+        return this.cfg;
+    }    
+}
index 9e293afaceb169557b310d3e3901fab49953a78b..ba819621e6ed4c8820111228008bdfba9c5e5965 100644 (file)
@@ -1060,7 +1060,7 @@ public class AreaTreeParser {
                         if (fontName != null) {
                             String fontStyle = attributes.getValue("font-style");
                             int fontWeight = getAttributeAsInteger(
-                                    attributes, "font-weight", Font.NORMAL);
+                                    attributes, "font-weight", Font.WEIGHT_NORMAL);
                             area.addTrait(trait,
                                     FontInfo.createFontKey(fontName, fontStyle, fontWeight));
                         }
index ce6aa64b877a6fe2195f2e38fb0204ded60445ef..63a817071f12b6acdadbf238df7790852aaecaca 100644 (file)
@@ -143,7 +143,7 @@ public class CommandLineOptions {
                     dumpConfiguration();
                 }
                 checkSettings();
-                createUserConfig();
+                setUserConfig();
                 
                 //Factory config is set up, now we can create the user agent
                 foUserAgent = factory.newFOUserAgent();
@@ -772,11 +772,11 @@ public class CommandLineOptions {
     }    // end checkSettings
 
     /**
-     * Create the user configuration.
+     * Sets the user configuration.
      * @throws FOPException if creating the user configuration fails
      * @throws IOException
      */
-    private void createUserConfig() throws FOPException, IOException {
+    private void setUserConfig() throws FOPException, IOException {
         if (userConfigFile == null) {
             return;
         }
diff --git a/src/java/org/apache/fop/fonts/CachedFontInfo.java b/src/java/org/apache/fop/fonts/CachedFontInfo.java
new file mode 100644 (file)
index 0000000..2812891
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.xml.utils.URI;
+import org.apache.xml.utils.URI.MalformedURIException;
+
+/**
+ * Font info stored in the cache 
+ */
+public class CachedFontInfo extends EmbedFontInfo {
+
+    /** Serialization Version UID */
+    private static final long serialVersionUID = 240028291961081894L;
+    
+    /** file modify date (if available) */
+    private long lastModified = -1;
+
+    /**
+     * Returns a file given a list of urls
+     * @param urls array of possible font urls
+     * @return file font file 
+     */
+    public static File getFileFromUrls(String[] urls) {
+        for (int i = 0; i < urls.length; i++) {
+            String urlStr = urls[i]; 
+            if (urlStr != null) {
+                if (urlStr.startsWith("file:")) {
+                    URI uri;
+                    try {
+                        uri = new URI(urlStr);
+                        urlStr = uri.getPath();
+                    } catch (MalformedURIException e) {
+                        // do nothing
+                    }
+                }
+                File fontFile = new File(urlStr);
+                if (fontFile.exists() && fontFile.canRead()) {
+                    return fontFile;
+                }
+            }
+        } 
+        return null;
+    }
+
+    /**
+     * Default constructor
+     * @param metricsFile metrics file
+     * @param kerning kerning
+     * @param fontTriplets font triplets
+     * @param embedFile embed file
+     * @param lastModified timestamp that this font was last modified 
+     */
+    public CachedFontInfo(String metricsFile, boolean kerning, List fontTriplets,
+            String embedFile, long lastModified) {
+        super(metricsFile, kerning, fontTriplets, embedFile);
+        this.lastModified = lastModified;
+    }
+
+    /**
+     * Constructor
+     * @param fontInfo an existing embed font info
+     */
+    public CachedFontInfo(EmbedFontInfo fontInfo) {
+        super(fontInfo.metricsFile, fontInfo.kerning, fontInfo.fontTriplets, fontInfo.embedFile);
+        // try and determine modified date
+        File fontFile = getFileFromUrls(new String[] {embedFile, metricsFile});
+        if (fontFile != null ) {
+            this.lastModified = fontFile.lastModified();
+        }
+    }
+
+    /**
+     * Gets the modified timestamp for font file (not always available)
+     * @return modified timestamp
+     */
+    public long lastModified() {
+        return this.lastModified;
+    }
+
+    /**
+     * Gets the modified timestamp for font file
+     * (used for the purposes of font info caching) 
+     * @param lastModified modified font file timestamp
+     */
+    public void setLastModified(long lastModified) {
+        this.lastModified = lastModified;
+    }
+    
+    /**
+     * @return string representation of this object 
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return super.toString() + ", lastModified=" + lastModified;
+    }
+}
index 5d7221c13dc7d37e78ed7135d9ca979470fe9b05..1455319e6b666a2aa40e70a6bf8bec0118f8be0e 100644 (file)
@@ -30,8 +30,9 @@ public abstract class CustomFont extends Typeface
             implements FontDescriptor, MutableFont {
 
     private String fontName = null;
+    private String fontSubName = null;
     private String embedFileName = null;
-    protected String embedResourceName = null;
+    private String embedResourceName = null;
     private FontResolver resolver = null;
     
     private int capHeight = 0;
@@ -51,7 +52,6 @@ public abstract class CustomFont extends Typeface
 
     private boolean useKerning = true;
 
-
     /**
      * @see org.apache.fop.fonts.FontMetrics#getFontName()
      */
@@ -59,6 +59,21 @@ public abstract class CustomFont extends Typeface
         return fontName;
     }
 
+    /**
+     * @see org.apache.fop.fonts.FontMetrics#getStrippedFontName()
+     */
+    public String getStrippedFontName() {
+        return FontUtil.stripWhiteSpace(fontName);
+    }
+
+    /**
+     * Returns font's subfamily name.
+     * @return the font's subfamily name
+     */
+    public String getFontSubName() {
+        return fontSubName;
+    }
+
     /**
      * Returns an URI representing an embeddable font file. The URI will often
      * be a filename or an URL.
@@ -238,6 +253,14 @@ public abstract class CustomFont extends Typeface
         this.fontName = name;
     }
 
+    /**
+     * Sets the font's subfamily name.
+     * @param subFamilyName the subfamily name of the font
+     */
+    public void setFontSubFamilyName(String subFamilyName) {
+        this.fontSubName = subFamilyName;        
+    }
+    
     /**
      * @see org.apache.fop.fonts.MutableFont#setEmbedFileName(String)
      */
index 45f9bb6e42a6b924713db25bd4fc8859483d266d..ad8915d9d6256a49e29bd60d14bf73f9212cfa80 100644 (file)
  
 package org.apache.fop.fonts;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
  * FontInfo contains meta information on fonts (where is the metrics file etc.)
  */
-public class EmbedFontInfo {
+public class EmbedFontInfo implements Serializable {
     
-    private String metricsFile, embedFile;
-    private boolean kerning;
-    private List fontTriplets;
-
+    /** Serialization Version UID */
+    private static final long serialVersionUID = -9075848379822693399L;
+    
+    /** filename of the metrics file */
+    protected String metricsFile;
+    /** filename of the main font file */
+    protected String embedFile;
+    /** false, to disable kerning */
+    protected boolean kerning;
+    /** the list of associated font triplets */
+    protected List fontTriplets;
+      
     /**
      * Main constructor
      * @param metricsFile Path to the xml file containing font metrics
@@ -44,7 +53,7 @@ public class EmbedFontInfo {
         this.kerning = kerning;
         this.fontTriplets = fontTriplets;
     }
-
+        
     /**
      * Returns the path to the metrics file
      * @return the metrics file path
@@ -76,6 +85,10 @@ public class EmbedFontInfo {
     public List getFontTriplets() {
         return fontTriplets;
     }
-
+    
+    /** @see java.lang.Object#toString() */
+    public String toString() {
+        return "metrics-url=" + metricsFile + ",embed-url=" + embedFile
+            + ", kerning=" + kerning + ", font-triplet=" + fontTriplets; 
+    }
 }
-
index a6b6d52d42e70f7a8bc974c3fdfdbb1c400b8873..de83072c6ed4e0ff941cd09a2913c2287b9c1bc2 100644 (file)
@@ -27,12 +27,22 @@ import java.util.Map;
  */
 public class Font {
 
-    /** Default fallback key */
-    public static final FontTriplet DEFAULT_FONT = new FontTriplet("any", "normal", 400);
-    /** Normal font weight */
-    public static final int NORMAL = 400;
     /** Bold font weight */
-    public static final int BOLD = 700;
+    public static final int WEIGHT_BOLD = 700;
+
+    /** Normal font weight */
+    public static final int WEIGHT_NORMAL = 400;
+
+    /** Normal font style */
+    public static final String STYLE_NORMAL = "normal";
+
+    /** Italic font style */
+    public static final String STYLE_ITALIC = "italic";
+
+    /** Default fallback key */
+    public static final FontTriplet DEFAULT_FONT = new FontTriplet(
+                    "any", STYLE_NORMAL, WEIGHT_NORMAL);
+
 
     private String fontName;
     private FontTriplet triplet;
diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java
new file mode 100644 (file)
index 0000000..036ec72
--- /dev/null
@@ -0,0 +1,330 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * Fop cache (currently only used for font info caching)
+ */
+public final class FontCache implements Serializable {
+    
+    /** Serialization Version UID */
+    private static final long serialVersionUID = 605232520271754717L;
+
+    /** logging instance */
+    private static Log log = LogFactory.getLog(FontCache.class);
+
+    /** FOP's user directory name */
+    private static final String FOP_USER_DIR = ".fop";
+
+    /** font cache file path */
+    private static final String DEFAULT_CACHE_FILENAME = "fop-fonts.cache";
+
+    /** has this cache been changed since it was last read? */
+    private transient boolean changed = false;
+    
+    /** change lock */
+    private transient Object changeLock = new Object();
+    
+    /** master mapping of font url -> font info */
+    private Map fontMap = new java.util.HashMap();
+
+    /** mapping of font url -> file modified date */
+    private Map failedFontMap = new java.util.HashMap();
+
+    /**
+     * Default constructor
+     */
+    public FontCache() {
+        //nop
+    }
+
+    private void readObject(java.io.ObjectInputStream in)
+            throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        this.changeLock = new Object(); //Initialize transient field
+    }
+
+    private static File getUserHome() {
+        String s = System.getProperty("user.home");
+        if (s != null) {
+            File userDir = new File(s);
+            if (userDir.exists()) {
+                return userDir;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Returns the default font cache file.
+     * @param forWriting true if the user directory should be created
+     * @return the default font cache file
+     */
+    public static File getDefaultCacheFile(boolean forWriting) {
+        File userHome = getUserHome();
+        if (userHome != null) {
+            File fopUserDir = new File(userHome, FOP_USER_DIR);
+            if (forWriting) {
+                fopUserDir.mkdir();
+            }
+            return new File(fopUserDir, DEFAULT_CACHE_FILENAME);
+        }
+        return new File(FOP_USER_DIR);
+    }
+    
+    /**
+     * Reads the default font cache file and returns its contents.
+     * @return the font cache deserialized from the file (or null if no cache file exists or if
+     *         it could not be read)
+     */
+    public static FontCache load() {
+        return loadFrom(getDefaultCacheFile(false));
+    }
+    
+    /**
+     * Reads a font cache file and returns its contents.
+     * @param cacheFile the cache file
+     * @return the font cache deserialized from the file (or null if no cache file exists or if
+     *         it could not be read)
+     */
+    public static FontCache loadFrom(File cacheFile) {
+        if (cacheFile.exists()) {
+            try {
+                if (log.isTraceEnabled()) {
+                    log.trace("Loading font cache from " + cacheFile.getCanonicalPath());
+                }
+                InputStream in = new java.io.FileInputStream(cacheFile);
+                in = new java.io.BufferedInputStream(in);
+                ObjectInputStream oin = new ObjectInputStream(in);
+                try {
+                    return (FontCache)oin.readObject();
+                } finally {
+                    IOUtils.closeQuietly(oin);
+                }
+            } catch (ClassNotFoundException e) {
+                //We don't really care about the exception since it's just a cache file
+                log.warn("Could not read font cache. Discarding font cache file. Reason: " 
+                        + e.getMessage());
+            } catch (IOException ioe) {
+                //We don't really care about the exception since it's just a cache file
+                log.warn("I/O exception while reading font cache (" + ioe.getMessage() 
+                        + "). Discarding font cache file.");
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Writes the font cache to disk.
+     * @throws FOPException fop exception
+     */
+    public void save() throws FOPException {
+        saveTo(getDefaultCacheFile(true));
+    }
+    
+    /**
+     * Writes the font cache to disk.
+     * @param cacheFile the file to write to 
+     * @throws FOPException fop exception
+     */
+    public void saveTo(File cacheFile) throws FOPException {
+        synchronized (changeLock) {
+            if (changed) {
+                try {
+                    if (log.isTraceEnabled()) {
+                        log.trace("Writing font cache to " + cacheFile.getCanonicalPath());
+                    }
+                    OutputStream out = new java.io.FileOutputStream(cacheFile);
+                    out = new java.io.BufferedOutputStream(out);
+                    ObjectOutputStream oout = new ObjectOutputStream(out);
+                    try {
+                        oout.writeObject(this);
+                    } finally {
+                        IOUtils.closeQuietly(oout);
+                    }
+                } catch (IOException ioe) {
+                    LogUtil.handleException(log, ioe, true);
+                }
+                changed = false;
+                log.trace("Cache file written.");
+            }
+        }
+    }
+
+    /**
+     * creates a key given a font info for the font mapping
+     * @param fontInfo font info
+     * @return font cache key
+     */
+    protected static String getCacheKey(EmbedFontInfo fontInfo) {
+        if (fontInfo != null) {
+            String embedFile = fontInfo.getEmbedFile();
+            String metricsFile = fontInfo.getMetricsFile();
+            return (embedFile != null) ? embedFile : metricsFile;
+        }
+        return null;
+    }
+
+    /**
+     * cache has been updated since it was read
+     * @return if this cache has changed
+     */
+    public boolean hasChanged() {
+        return this.changed;
+    }
+    
+    /**
+     * is this font in the cache?
+     * @param embedUrl font info
+     * @return boolean
+     */
+    public boolean containsFont(String embedUrl) {
+        if (embedUrl != null) {
+            return fontMap.containsKey(embedUrl);
+        }
+        return false;
+    }
+
+    /**
+     * is this font info in the cache?
+     * @param fontInfo font info
+     * @return font
+     */
+    public boolean containsFont(EmbedFontInfo fontInfo) {
+        if (fontInfo != null) {
+            return fontMap.containsKey(getCacheKey(fontInfo));
+        }
+        return false;
+    }
+
+    /**
+     * adds a font info to cache
+     * @param fontInfo font info
+     */
+    public void addFont(EmbedFontInfo fontInfo) {
+        String cacheKey = getCacheKey(fontInfo);
+        synchronized (changeLock) {
+            if (!containsFont(cacheKey)) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Font added to cache: " + cacheKey);
+                }
+                if (fontInfo instanceof CachedFontInfo) {
+                    fontMap.put(cacheKey, fontInfo);
+                } else {
+                    fontMap.put(cacheKey, new CachedFontInfo(fontInfo));
+                }
+                changed = true;
+            }
+        }
+    }
+
+    /**
+     * returns a font from the cache
+     * @param embedUrl font info
+     * @return boolean
+     */
+    public CachedFontInfo getFont(String embedUrl) {
+        if (containsFont(embedUrl)) {
+            return (CachedFontInfo)fontMap.get(embedUrl);
+        }
+        return null;
+    }
+    
+    /**
+     * removes font from cache
+     * @param embedUrl embed url
+     */
+    public void removeFont(String embedUrl) {
+        synchronized (changeLock) {
+            if (containsFont(embedUrl)) {
+                if (log.isTraceEnabled()) {
+                    log.trace("Font removed from cache: " + embedUrl);
+                }
+                fontMap.remove(embedUrl);
+                changed = true;
+            }
+        }
+    }
+    
+    /**
+     * has this font previously failed to load?
+     * @param embedUrl embed url
+     * @param lastModified last modified
+     * @return whether this is a failed font
+     */
+    public boolean isFailedFont(String embedUrl, long lastModified) {
+        if (failedFontMap.containsKey(embedUrl)) {
+            synchronized (changeLock) {
+                long failedLastModified = ((Long)failedFontMap.get(embedUrl)).longValue();
+                if (lastModified != failedLastModified) {
+                    // this font has been changed so lets remove it
+                    // from failed font map for now
+                    failedFontMap.remove(embedUrl);
+                    changed = true;
+                }                
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * registers a failed font with the cache
+     * @param embedUrl embed url
+     * @param lastModified time last modified
+     */
+    public void registerFailedFont(String embedUrl, long lastModified) {
+        synchronized (changeLock) {
+            if (!failedFontMap.containsKey(embedUrl)) {
+                failedFontMap.put(embedUrl, new Long(lastModified));
+                changed = true;
+            }
+        }
+    }
+
+    /**
+     * Clears font cache
+     */
+    public void clear() {
+        synchronized (changeLock) {
+            if (log.isTraceEnabled()) {
+                log.trace("Font cache cleared.");
+            }
+            fontMap.clear();
+            failedFontMap.clear();
+            changed = true;
+        }
+    }
+}
index 987bb94b797197f5b1bbbe812465e8eceafcb674..995d59bf8e84a9d3ae73817cd68c34ce17b23a78 100644 (file)
@@ -130,6 +130,9 @@ public class FontInfo {
      */
     private FontTriplet fontLookup(String family, String style,
                              int weight, boolean substFont) {
+        if (log.isTraceEnabled()) {
+            log.trace("Font lookup: " + family + " " + style + " " + weight);
+        }
         FontTriplet startKey = createFontKey(family, style, weight); 
         FontTriplet key = startKey;
         // first try given parameters
@@ -146,13 +149,13 @@ public class FontInfo {
             // only if the font may be substituted
             // fallback 1: try the same font-family and weight with default style
             if (f == null) {
-                key = createFontKey(family, "normal", weight);
+                key = createFontKey(family, Font.STYLE_NORMAL, weight);
                 f = getInternalFontKey(key);
             }
             
             // fallback 2: try the same font-family with default style and weight
             if (f == null) {
-                key = createFontKey(family, "normal", 400);
+                key = createFontKey(family, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
                 f = getInternalFontKey(key);
             }
             
@@ -426,8 +429,4 @@ public class FontInfo {
             return 0;
         }
     }
-    
 }
-
-
-
index 4377f9fabe8a0b56ab67fe41f51cf147f6829cac..c48e36453b27e84ff974999d6f52cc2f13cd2756 100644 (file)
@@ -19,6 +19,7 @@
 \r
 package org.apache.fop.fonts;\r
 \r
+import java.io.File;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
 import java.net.MalformedURLException;\r
@@ -28,6 +29,8 @@ import javax.xml.transform.Source;
 import javax.xml.transform.stream.StreamSource;\r
 \r
 import org.apache.commons.io.IOUtils;\r
+import org.apache.commons.logging.Log;\r
+import org.apache.commons.logging.LogFactory;\r
 import org.apache.fop.fonts.truetype.TTFFontLoader;\r
 import org.apache.fop.fonts.type1.Type1FontLoader;\r
 \r
@@ -36,6 +39,51 @@ import org.apache.fop.fonts.type1.Type1FontLoader;
  */\r
 public abstract class FontLoader {\r
 \r
+    /**\r
+     * logging instance\r
+     */\r
+    protected static Log log = LogFactory.getLog(FontLoader.class);\r
+\r
+    /** URI representing the font file */\r
+    protected String fontFileURI = null;\r
+    /** the InputStream to load the font from */\r
+    protected InputStream in = null;\r
+    /** the FontResolver to use for font URI resolution */\r
+    protected FontResolver resolver = null;\r
+    /** the loaded font */\r
+    protected CustomFont returnFont = null;\r
+\r
+    /** true if the font has been loaded */\r
+    protected boolean loaded = false;\r
+\r
+    /**\r
+     * Default constructor.\r
+     * @param fontFileURI the URI to the PFB file of a Type 1 font\r
+     * @param in the InputStream reading the PFM file of a Type 1 font\r
+     * @param resolver the font resolver used to resolve URIs\r
+     */\r
+    public FontLoader(String fontFileURI, InputStream in, FontResolver resolver) {\r
+        this.fontFileURI = fontFileURI;\r
+        this.in = in;\r
+        this.resolver = resolver;\r
+    }\r
+\r
+    private static boolean isType1(String fontURI) {\r
+        return fontURI.toLowerCase().endsWith(".pfb");\r
+    }\r
+\r
+    /**\r
+     * Loads a custom font from a File. In the case of Type 1 fonts, the PFB file must be specified.\r
+     * @param fontFile the File representation of the font\r
+     * @param resolver the font resolver to use when resolving URIs\r
+     * @return the newly loaded font\r
+     * @throws IOException In case of an I/O error\r
+     */\r
+    public static CustomFont loadFont(File fontFile, FontResolver resolver)\r
+                throws IOException {\r
+        return loadFont(fontFile.getAbsolutePath(), resolver);\r
+    }\r
+        \r
     /**\r
      * Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.\r
      * @param fontFileURI the URI to the font\r
@@ -45,21 +93,38 @@ public abstract class FontLoader {
      */\r
     public static CustomFont loadFont(String fontFileURI, FontResolver resolver)\r
                 throws IOException {\r
-        FontLoader loader;\r
         fontFileURI = fontFileURI.trim();\r
         String name = fontFileURI.toLowerCase();\r
         String effURI;\r
-        boolean type1 = false;\r
-        if (name.endsWith(".pfb")) {\r
-            type1 = true;\r
+        boolean type1 = isType1(fontFileURI);\r
+        if (type1) {\r
             effURI = name.substring(0, fontFileURI.length() - 4) + ".pfm";\r
         } else {\r
             effURI = fontFileURI;\r
         }\r
-        \r
+        if (log.isDebugEnabled()) {\r
+            log.debug("opening " + effURI);\r
+        }\r
         InputStream in = openFontFile(resolver, effURI);\r
+        return loadFontFromInputStream(fontFileURI, resolver, type1, in);\r
+    }\r
+\r
+    /**\r
+     * Loads and returns a font given an input stream.\r
+     * @param fontFileURI font file uri\r
+     * @param resolver font resolver\r
+     * @param isType1 is it a type1 font?\r
+     * @param in input stream\r
+     * @return the loaded font.\r
+     * @throws IOException In case of an I/O error\r
+     */\r
+    protected static CustomFont loadFontFromInputStream(\r
+            String fontFileURI, FontResolver resolver, boolean isType1,\r
+            InputStream in)\r
+                throws IOException {\r
+        FontLoader loader;\r
         try {\r
-            if (type1) {\r
+            if (isType1) {\r
                 loader = new Type1FontLoader(fontFileURI, in, resolver);\r
             } else {\r
                 loader = new TTFFontLoader(fontFileURI, in, resolver);\r
@@ -70,6 +135,14 @@ public abstract class FontLoader {
         }\r
     }\r
 \r
+    /**\r
+     * Opens a font file and returns an input stream.\r
+     * @param resolver the FontResolver to use for font URI resolution\r
+     * @param uri the URI representing the font\r
+     * @return the InputStream to read the font from.\r
+     * @throws IOException In case of an I/O error\r
+     * @throws MalformedURLException If an invalid URL is built\r
+     */\r
     private static InputStream openFontFile(FontResolver resolver, String uri) \r
                     throws IOException, MalformedURLException {\r
         InputStream in = null;\r
@@ -96,11 +169,18 @@ public abstract class FontLoader {
         }\r
         return in;\r
     }\r
-    \r
+        \r
     /**\r
-     * @return the font loaded by this loader\r
+     * Reads/parses the font data.\r
+     * @throws IOException In case of an I/O error\r
      */\r
-    public abstract CustomFont getFont();\r
+    protected abstract void read() throws IOException;\r
 \r
-    \r
+    /** @see org.apache.fop.fonts.FontLoader#getFont() */\r
+    public CustomFont getFont() throws IOException {\r
+        if (!loaded) {\r
+            read();\r
+        }\r
+        return this.returnFont;\r
+    }\r
 }\r
index 9659398baeb318bbb0486ed01bd9904cfb16f996..0028f328149fc65f88244e8500b8f31b4565999c 100644 (file)
@@ -34,16 +34,11 @@ import org.apache.fop.fonts.base14.CourierOblique;
 import org.apache.fop.fonts.base14.CourierBoldOblique;
 import org.apache.fop.fonts.base14.Symbol;
 import org.apache.fop.fonts.base14.ZapfDingbats;
-import org.apache.fop.render.PrintRenderer;
 
 // commons logging
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-// Avalon
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-
 // Java
 import java.util.List;
 
@@ -62,8 +57,8 @@ public class FontSetup {
     /**
      * logging instance
      */
-    protected static Log log = LogFactory.getLog("org.apache.fop.fonts");
-    
+    protected static Log log = LogFactory.getLog(FontSetup.class);
+
     /**
      * Sets up the font info object.
      *
@@ -113,52 +108,52 @@ public class FontSetup {
         // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic());
 
         /* any is treated as serif */
-        fontInfo.addFontProperties("F5", "any", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "any", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "any", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "any", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "any", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F8", "any", "oblique", Font.BOLD);
-
-        fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "serif", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "serif", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "serif", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "serif", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "serif", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "serif", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F9", "monospace", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "monospace", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "monospace", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F11", "monospace", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F12", "monospace", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F12", "monospace", "italic", Font.BOLD);
-
-        fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "Times", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F9", "Courier", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "Courier", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "Courier", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F11", "Courier", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F12", "Courier", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F12", "Courier", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F13", "Symbol", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.NORMAL);
+        fontInfo.addFontProperties("F5", "any", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "any", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "any", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "any", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "any", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "any", "oblique", Font.WEIGHT_BOLD);
+
+        fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "serif", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "serif", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "serif", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "serif", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "serif", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "serif", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F9", "monospace", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "monospace", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "monospace", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F11", "monospace", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "monospace", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "monospace", "italic", Font.WEIGHT_BOLD);
+
+        fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "Times", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F9", "Courier", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "Courier", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "Courier", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F11", "Courier", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "Courier", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "Courier", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F13", "Symbol", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.WEIGHT_NORMAL);
 
         // Custom type 1 fonts step 2/2
         // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL);
@@ -166,20 +161,20 @@ public class FontSetup {
         // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD);
 
         /* for compatibility with PassiveTex */
-        fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.BOLD);
+        fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.WEIGHT_BOLD);
         fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
-                                   "normal", Font.NORMAL);
+                                   "normal", Font.WEIGHT_NORMAL);
 
         /* Add configured fonts */
         addConfiguredFonts(fontInfo, embedList, 15, resolver);
@@ -218,10 +213,7 @@ public class FontSetup {
             reader.setFontEmbedPath(configFontInfo.getEmbedFile());
             fontInfo.addMetrics(internalName, reader.getFont());
             */
-            LazyFont font = new LazyFont(configFontInfo.getEmbedFile(),
-                                         metricsFile,
-                                         configFontInfo.getKerning(), 
-                                         resolver);
+            LazyFont font = new LazyFont(configFontInfo, resolver);
             fontInfo.addMetrics(internalName, font);
 
             List triplets = configFontInfo.getFontTriplets();
@@ -237,7 +229,7 @@ public class FontSetup {
     }
 
     /** @return a new FontResolver to be used by the font subsystem */
-    private static FontResolver createMinimalFontResolver() {
+    public static FontResolver createMinimalFontResolver() {
         return new FontResolver() {
 
             /** @see org.apache.fop.fonts.FontResolver#resolve(java.lang.String) */
@@ -245,135 +237,6 @@ public class FontSetup {
                 //Minimal functionality here
                 return new StreamSource(href);
             }
-            
         };
-    }
-   
-    /**
-     * Builds a list of EmbedFontInfo objects for use with the setup() method.
-     * 
-     * @param cfg Configuration object
-     * @param renderer calling Renderer object
-     * @return List the newly created list of fonts
-     * @throws ConfigurationException if something's wrong with the config data
-     */
-    public static List buildFontListFromConfiguration(Configuration cfg, PrintRenderer renderer)
-            throws ConfigurationException {
-        List fontList = new java.util.ArrayList();
-               
-        FontResolver fontResolver = (renderer != null ? renderer.getFontResolver() : null);
-        if (fontResolver == null) {
-            //Ensure that we have minimal font resolution capabilities
-            fontResolver = FontSetup.createMinimalFontResolver();
-        }
-       
-        boolean strict = false;
-        if (renderer != null) {
-            strict = renderer.getUserAgent().getFactory().validateUserConfigStrictly();
-        }
-        
-        Configuration[] fonts = cfg.getChildren("fonts");
-        for (int f = 0; f < fonts.length; f++) {
-                
-            Configuration[] font = fonts[f].getChildren("font");
-            for (int i = 0; i < font.length; i++) {
-    
-                String metricsUrl = font[i].getAttribute("metrics-url", null);
-                String embedUrl = font[i].getAttribute("embed-url", null);
-    
-                if (metricsUrl == null && embedUrl == null) {
-                    if (strict) {
-                        throw new ConfigurationException(
-                                "Font configuration without metric-url or embed-url");
-                    }
-                    log.error("Font configuration without metric-url or embed-url");
-                    continue;
-                }
-                
-                if (metricsUrl != null && fontResolver.resolve(metricsUrl) == null) {
-                    if (strict) {
-                        throw new ConfigurationException("Failed to resolve font metric-url '"
-                            + metricsUrl + "'");                    
-                    }
-                    log.error("Failed to resolve font metric-url '" + metricsUrl + "'");
-                    continue;
-                }
-                
-                if (embedUrl != null && fontResolver.resolve(embedUrl) == null) {
-                    if (strict) {
-                        throw new ConfigurationException("Failed to resolve font with embed-url '"
-                                + embedUrl + "'");
-                    }
-                    log.error("Failed to resolve font with embed-url '" + embedUrl + "'");
-                    continue;
-                }
-            
-                boolean useKerning = font[i].getAttributeAsBoolean("kerning", false);
-    
-                Configuration[] triple = font[i].getChildren("font-triplet");
-                List tripleList = new java.util.ArrayList();
-                for (int j = 0; j < triple.length; j++) {
-                    String name = triple[j].getAttribute("name");
-                    if (name == null) {
-                        if (strict) {
-                            throw new ConfigurationException("font-triplet without name");
-                        }
-                        log.error("font-triplet without name");
-                        continue;
-                    }
-                    
-                    String weightStr = triple[j].getAttribute("weight");
-                    if (weightStr == null) {
-                        if (strict) {
-                            throw new ConfigurationException("font-triplet without weight");
-                        }
-                        log.error("font-triplet without weight");
-                        continue;
-                    }
-                    int weight = FontUtil.parseCSS2FontWeight(weightStr);
-    
-                    String style = triple[j].getAttribute("style");
-                    if (style == null) {
-                        if (strict) {
-                            throw new ConfigurationException("font-triplet without style");
-                        }
-                        log.error("font-triplet without style");
-                        continue;
-                    }
-                    
-                    tripleList.add(FontInfo.createFontKey(name,
-                            style, weight));
-                }
-    
-                EmbedFontInfo configFontInfo = new EmbedFontInfo(metricsUrl, 
-                        useKerning, tripleList, embedUrl);
-                
-                if (log.isDebugEnabled()) {
-                    log.debug("Adding font " + configFontInfo.getEmbedFile()
-                            + ", metric file " + configFontInfo.getMetricsFile());
-                    for (int j = 0; j < tripleList.size(); ++j) {
-                        FontTriplet triplet = (FontTriplet) tripleList.get(j);
-                        log.debug("Font triplet "
-                                    + triplet.getName() + ", "
-                                    + triplet.getStyle() + ", "
-                                    + triplet.getWeight());
-                    }
-                }
-                fontList.add(configFontInfo);
-            }
-        }
-        return fontList;
-    }    
-
-    /**
-     * Builds a list of EmbedFontInfo objects for use with the setup() method.
-     * 
-     * @param cfg Configuration object
-     * @return List the newly created list of fonts
-     * @throws ConfigurationException if something's wrong with the config data
-     */
-    public static List buildFontListFromConfiguration(Configuration cfg)
-    throws ConfigurationException {
-        return buildFontListFromConfiguration(cfg, null);
-    }
+    }       
 }
index e08ba3815fad068b585a074b97219a6b25f5fb62..7ca2a03717213b6f06805a900fde8899bfb505bb 100644 (file)
@@ -57,4 +57,24 @@ public class FontUtil {
         return weight;
     }
 
+    /**
+     * Removes all white space from a string (used primarily for font names)
+     * @param s the string
+     * @return the processed result
+     */
+    public static String stripWhiteSpace(String s) {
+        StringBuffer sb = new StringBuffer(s.length());
+        for (int i = 0, c = s.length(); i < c; i++) {
+            final char ch = s.charAt(i);
+            if (ch != ' ' 
+                    && ch != '\r' 
+                    && ch != '\n'
+                    && ch != '\t') {
+                sb.append(ch);
+            }
+        }
+        return sb.toString();
+    }
+
+    
 }
index 658c0cf1e837c318da0e3d4484cca8495e55c3ac..9fff44e10df50ec8b6490704aa7348a6daf950c5 100644 (file)
@@ -54,14 +54,21 @@ public class LazyFont extends Typeface implements FontDescriptor {
      * @param useKerning True, if kerning should be enabled
      * @param resolver the font resolver to handle font URIs
      */
-    public LazyFont(String fontEmbedPath, String metricsFileName
-                    , boolean useKerning, FontResolver resolver) {
-        this.metricsFileName = metricsFileName;
-        this.fontEmbedPath = fontEmbedPath;
-        this.useKerning = useKerning;
+    public LazyFont(EmbedFontInfo fontInfo, FontResolver resolver) {
+        
+        this.metricsFileName = fontInfo.getMetricsFile();
+        this.fontEmbedPath = fontInfo.getEmbedFile();
+        this.useKerning = fontInfo.getKerning();
         this.resolver = resolver;
     }
 
+    /**
+     * String representation of LazyFont
+     */
+    public String toString() {
+        return ( "metrics-url=" + metricsFileName + ", embed-url=" + fontEmbedPath + ", kerning=" + useKerning );
+    }
+        
     private void load(boolean fail) {
         if (!isMetricsLoaded) {
             try {
@@ -327,6 +334,5 @@ public class LazyFont extends Typeface implements FontDescriptor {
         load(true);
         return realFontDescriptor.isEmbeddable();
     }
-
 }
 
index 1b9263d177192a80718a9b8fb55c6fcdb56e5b23..e326140b52d80b0f4ccce9515ad80fead1a79646 100644 (file)
@@ -108,28 +108,9 @@ public class MultiByteFont extends CIDFont {
     public void setCIDType(CIDFontType cidType) {
         this.cidType = cidType;
     }
-
-    /**
-     * Removes all white space from a string (used primarily for font names)
-     * @param s the string
-     * @return the processed result
-     */
-    public static String stripWhiteSpace(String s) {
-        StringBuffer sb = new StringBuffer(s.length());
-        for (int i = 0, c = s.length(); i < c; i++) {
-            final char ch = s.charAt(i);
-            if (ch != ' ' 
-                    && ch != '\r' 
-                    && ch != '\n'
-                    && ch != '\t') {
-                sb.append(ch);
-            }
-        }
-        return sb.toString();
-    }
     
     private String getPrefixedFontName() {
-        return namePrefix + stripWhiteSpace(super.getFontName());
+        return namePrefix + FontUtil.stripWhiteSpace(super.getFontName());
     }
     
     /**
@@ -147,7 +128,7 @@ public class MultiByteFont extends CIDFont {
      * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable()
      */
     public boolean isEmbeddable() {
-        return !(getEmbedFileName() == null && embedResourceName == null);
+        return !(getEmbedFileName() == null && getEmbedResourceName() == null);
     }
 
     /**
index 93388c34fb23e79ccb4da7507714c3a3baa275e3..4d5cc394280b642d4108cfc79ff4babf37959d85 100644 (file)
@@ -27,6 +27,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.Version;
+import org.apache.fop.fonts.FontUtil;
 import org.apache.fop.fonts.truetype.FontFileReader;
 import org.apache.fop.fonts.truetype.TTFCmapEntry;
 import org.apache.fop.fonts.truetype.TTFFile;
@@ -258,10 +259,10 @@ public class TTFReader extends AbstractFontReader {
         // "Perpetua-Bold", but the TrueType spec says that in the ttf file
         // it should be "Perpetua,Bold".
 
-        String s = stripWhiteSpace(ttf.getPostScriptName());
+        String s = FontUtil.stripWhiteSpace(ttf.getPostScriptName());
 
         if (fontName != null) {
-            el.appendChild(doc.createTextNode(stripWhiteSpace(fontName)));
+            el.appendChild(doc.createTextNode(FontUtil.stripWhiteSpace(fontName)));
         } else {
             el.appendChild(doc.createTextNode(s));
         }
@@ -450,22 +451,6 @@ public class TTFReader extends AbstractFontReader {
     }
 
 
-    private String stripWhiteSpace(String s) {
-        char[] ch = new char[s.length()];
-        s.getChars(0, s.length(), ch, 0);
-        StringBuffer stb = new StringBuffer();
-        for (int i = 0; i < ch.length; i++) {
-            if (ch[i] != ' ' 
-                    && ch[i] != '\r' 
-                    && ch[i] != '\n'
-                    && ch[i] != '\t') {
-                stb.append(ch[i]);
-            }
-        }
-
-        return stb.toString();
-    }
-    
     /** 
      * Bugzilla 40739, check that attr has a metrics-version attribute 
      * compatible with ours.
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
new file mode 100644 (file)
index 0000000..a19ab5a
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.io.DirectoryWalker;
+import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.io.filefilter.IOFileFilter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Helps to autodetect/locate available operating system fonts.
+ */
+public class FontFileFinder extends DirectoryWalker implements FontFinder {
+
+    /** logging instance */
+    private final Log log = LogFactory.getLog(FontFileFinder.class);
+
+    /** default depth limit of recursion when searching for font files **/
+    public static final int DEFAULT_DEPTH_LIMIT = -1;
+    
+    /**
+     * Default constructor 
+     */
+    public FontFileFinder() {
+        super(getDirectoryFilter(), getFileFilter(), DEFAULT_DEPTH_LIMIT);
+    }
+
+    /**
+     * Constructor 
+     * @param depthLimit recursion depth limit
+     */
+    public FontFileFinder(int depthLimit) {
+        super(getDirectoryFilter(), getFileFilter(), depthLimit);
+    }
+    
+    /**
+     * Font directory filter.  Currently ignores hidden directories.
+     * @return IOFileFilter font directory filter
+     */
+    protected static IOFileFilter getDirectoryFilter() {
+        return FileFilterUtils.andFileFilter(
+                FileFilterUtils.directoryFileFilter(),
+                FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter("."))
+        );
+    }
+    
+    /**
+     * Font file filter.  Currently searches for files with .ttf and .pfb extensions.
+     * @return IOFileFilter font file filter
+     */
+    protected static IOFileFilter getFileFilter() {
+        return FileFilterUtils.andFileFilter(
+                FileFilterUtils.fileFileFilter(), 
+                FileFilterUtils.orFileFilter(
+                        FileFilterUtils.suffixFileFilter(".ttf"),
+                        FileFilterUtils.suffixFileFilter(".pfb")
+                )
+        );
+    }
+    
+    /**
+     * @param directory directory to handle
+     * @param depth recursion depth
+     * @param results collection
+     * @return whether directory should be handled
+     * @see org.apache.commons.io.DirectoryWalker#handleDirectory(File, int, Collection)
+     */
+    protected boolean handleDirectory(File directory, int depth, Collection results) {
+        return true;
+    }
+
+    /**
+     * @param file file to handle
+     * @param depth recursion depth
+     * @param results collection
+     * @see org.apache.commons.io.DirectoryWalker#handleFile(File, int, Collection)
+     */
+    protected void handleFile(File file, int depth, Collection results) {
+        results.add(file);
+    }
+      
+    /**
+     * @param directory the directory being processed
+     * @param depth the current directory level
+     * @param results the colleciton of results objects
+     * @see org.apache.commons.io.DirectoryWalker.handleDirectoryEnd
+     */
+    protected void handleDirectoryEnd(File directory, int depth, Collection results) {
+        if (log.isDebugEnabled()) {
+            log.debug(directory + ": found " + results.size() + " font"
+                    + ((results.size() == 1) ? "" : "s"));        
+        }
+    }    
+    
+    /**
+     * Automagically finds a list of font files on local system
+     * 
+     * @return list of font files
+     * @throws IOException io exception
+     * @see org.apache.fop.fonts.autodetect.FontFinder#find()
+     */
+    public List find() throws IOException {
+        final FontFinder fontDirFinder;
+        final String osName = System.getProperty("os.name");
+        if (osName.startsWith("Windows")) {
+            fontDirFinder = new WindowsFontDirFinder();
+        } else {
+            if (osName.startsWith("Mac")) {
+                fontDirFinder = new MacFontDirFinder();
+            } else {
+                fontDirFinder = new UnixFontDirFinder();
+            }
+        }
+        List fontDirs = fontDirFinder.find();
+        List results = new java.util.ArrayList();
+        for (Iterator iter = fontDirs.iterator(); iter.hasNext();) {
+            super.walk((File)iter.next(), results);
+        }
+        return results;
+    }
+
+    /**
+     * Searches a given directory for font files
+     * 
+     * @param dir directory to search
+     * @return list of font files
+     * @throws IOException io exception
+     */
+    public List find(String dir) throws IOException {
+        List results = new java.util.ArrayList();
+        super.walk(new File(dir), results);
+        return results;
+    }    
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFinder.java
new file mode 100644 (file)
index 0000000..2bcdc9a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Implementers provide find method for searching native operating system
+ * for available fonts.
+ */
+public interface FontFinder {
+    
+    /**
+     * Finds a list of font files.
+     * @return list of font files
+     * @throws IOException In case of an I/O problem
+     */
+    List find() throws IOException;
+    
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
new file mode 100644 (file)
index 0000000..910b5dd
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.fonts.CachedFontInfo;
+import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.EmbedFontInfo;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontCache;
+import org.apache.fop.fonts.FontLoader;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.FontTriplet;
+
+/**
+ * Attempts to determine correct FontInfo
+ */
+public class FontInfoFinder {
+    
+    /** logging instance */
+    private Log log = LogFactory.getLog(FontInfoFinder.class);
+
+    /** font constituent names which identify a font as being of "italic" style */
+    private static final String[] ITALIC_WORDS = {"italic", "oblique"};
+
+    /** font constituent names which identify a font as being of "bold" weight */
+    private static final String[] BOLD_WORDS = {"bold", "black", "heavy", "ultra", "super"};
+
+    /**
+     * Attempts to determine FontTriplet from a given CustomFont.
+     * It seems to be fairly accurate but will probably require some tweaking over time
+     * 
+     * @param customFont CustomFont
+     * @return newly created font triplet
+     */
+    private FontTriplet tripletFromFont(CustomFont customFont) {
+        // default style and weight triplet vales (fallback)
+        String name = customFont.getStrippedFontName();
+        String subName = customFont.getFontSubName();
+        String searchName = name.toLowerCase();
+        if (subName != null) {
+            searchName += subName.toLowerCase();
+        }
+        
+        // style
+        String style = Font.STYLE_NORMAL;
+        if (customFont.getItalicAngle() > 0) {
+            style = Font.STYLE_ITALIC;  
+        } else {
+            for (int i = 0; i < ITALIC_WORDS.length; i++) {
+                if (searchName.indexOf(ITALIC_WORDS[i]) != -1) {
+                    style = Font.STYLE_ITALIC;          
+                    break;
+                }
+            }
+        }
+        
+        // weight
+        int weight = Font.WEIGHT_NORMAL;
+        for (int i = 0; i < BOLD_WORDS.length; i++) {
+            if (searchName.indexOf(BOLD_WORDS[i]) != -1) {
+                weight = Font.WEIGHT_BOLD;
+                break;
+            }            
+        }
+        return new FontTriplet(name, style, weight);
+    }
+    
+    /**
+     * Attempts to determine FontInfo from a given custom font
+     * @param fontFile the font file
+     * @param customFont the custom font
+     * @param fontCache font cache (may be null)
+     * @return
+     */
+    private EmbedFontInfo fontInfoFromCustomFont(
+            File fontFile, CustomFont customFont, FontCache fontCache) {
+        FontTriplet fontTriplet = tripletFromFont(customFont);
+        List fontTripletList = new java.util.ArrayList();
+        fontTripletList.add(fontTriplet);
+        String embedUrl;
+        try {
+            embedUrl = fontFile.toURL().toExternalForm();
+        } catch (MalformedURLException e) {
+            embedUrl = fontFile.getAbsolutePath();
+        }
+        EmbedFontInfo fontInfo = new EmbedFontInfo(null, customFont.isKerningEnabled(),
+                fontTripletList, embedUrl);
+        if (fontCache != null) {
+            fontCache.addFont(fontInfo);
+        }
+        return fontInfo;
+    }
+        
+    /**
+     * Attempts to determine EmbedFontInfo from a given font file.
+     * 
+     * @param fontFile font file
+     * @param resolver font resolver used to resolve font
+     * @param fontCache font cache (may be null)
+     * @return newly created embed font info
+     */
+    public EmbedFontInfo find(File fontFile, FontResolver resolver, FontCache fontCache) {
+        String embedUrl = null;
+        try {
+            embedUrl = fontFile.toURL().toExternalForm();
+        } catch (MalformedURLException mfue) {
+            // should never happen
+            log.error("Failed to convert '" + fontFile + "' to URL: " + mfue.getMessage() );
+        }
+        
+        long fileLastModified = -1;
+        if (fontCache != null) {
+            fileLastModified = fontFile.lastModified();
+            // firstly try and fetch it from cache before loading/parsing the font file
+            if (fontCache.containsFont(embedUrl)) {
+                CachedFontInfo fontInfo = fontCache.getFont(embedUrl);
+                if (fontInfo.lastModified() == fileLastModified) {
+                    return fontInfo;
+                } else {
+                    // out of date cache item
+                    fontCache.removeFont(embedUrl);
+                }
+            // is this a previously failed parsed font?
+            } else if (fontCache.isFailedFont(embedUrl, fileLastModified)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Skipping font file that failed to load previously: " + embedUrl);
+                }
+                return null;
+            }
+        }
+        
+        // try to determine triplet information from font file
+        CustomFont customFont = null;
+        try {
+            customFont = FontLoader.loadFont(fontFile, resolver);
+        } catch (Exception e) {
+            //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
+            if (log.isErrorEnabled()) {
+                log.error("Unable to load font file: " + embedUrl + ". Reason: " + e.getMessage());
+            }
+            if (fontCache != null) {
+                fontCache.registerFailedFont(embedUrl, fileLastModified);
+            }
+            return null;
+        }
+        return fontInfoFromCustomFont(fontFile, customFont, fontCache);     
+    }
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java
new file mode 100644 (file)
index 0000000..60d3fd7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+/**
+ * Mac font directory finder
+ */
+public class MacFontDirFinder extends NativeFontDirFinder {
+
+    /**
+     * Some guesses at possible unix font directory locations
+     * @return a array of possible font directory locations
+     */
+    protected String[] getSearchableDirectories() {
+        return new String[] {
+           System.getProperty("user.home") + "/Library/Fonts/", // user
+           "/Library/Fonts/", // local
+           "/System/Library/Fonts/", // system
+           "/Network/Library/Fonts/" // network
+        };
+    }    
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java
new file mode 100644 (file)
index 0000000..e9bfe94
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Native font finder base class
+ */
+public abstract class NativeFontDirFinder implements FontFinder {
+    
+    /**
+     * Generic method used by Mac and Unix font finders.
+     * @return list of natively existing font directories
+     * @see FontFinder#find()
+     */
+    public List find() {
+        List fontDirList = new java.util.ArrayList();
+        String[] searchableDirectories = getSearchableDirectories();
+        if (searchableDirectories != null) {
+            for (int i = 0; i < searchableDirectories.length; i++) {
+                File fontDir = new File(searchableDirectories[i]);
+                if (fontDir.exists() && fontDir.canRead()) {
+                    fontDirList.add(fontDir);
+                }
+            }
+        }
+        return fontDirList;
+    }
+    
+    /**
+     * Returns an array of directories to search for fonts in. 
+     * @return an array of directories
+     */
+    protected abstract String[] getSearchableDirectories();
+    
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java
new file mode 100644 (file)
index 0000000..0d02c6d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+/**
+ * Unix font directory finder
+ */
+public class UnixFontDirFinder extends NativeFontDirFinder {
+
+    /**
+     * Some guesses at possible unix font directory locations
+     * @return a list of possible font locations
+     */
+    protected String[] getSearchableDirectories() {
+        return new String[] {
+            System.getProperty("user.home") + "/.fonts", // user
+            "/usr/local/fonts", // local
+            "/usr/share/fonts", // system
+            "/usr/X11R6/lib/X11/fonts" // X
+        };
+    }    
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java b/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java
new file mode 100644 (file)
index 0000000..19901dc
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.fonts.autodetect;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+
+/**
+ * FontFinder for native Windows platforms
+ */
+public class WindowsFontDirFinder implements FontFinder {
+        
+    /**
+     * Attempts to read windir environment variable on windows
+     * (disclaimer: This is a bit dirty but seems to work nicely) 
+     */
+    private String getWinDir(String osName) throws IOException {
+        Process process = null;
+        Runtime runtime = Runtime.getRuntime();
+        if (osName.startsWith("Windows 9")) {
+            process = runtime.exec("command.com /c echo %windir%");
+        } else {
+            process = runtime.exec("cmd.exe /c echo %windir%");
+        }
+        BufferedReader bufferedReader = new BufferedReader(
+                new InputStreamReader(process.getInputStream()));
+        return bufferedReader.readLine();
+    }
+
+    /**
+     * @see FontFinder#find()
+     * @return a list of detected font files
+     */
+    public List find() {
+        List fontDirList = new java.util.ArrayList();
+        String windir = null;
+        try {
+            windir = System.getProperty("env.windir");
+        } catch (SecurityException e) {
+            // should continue if this fails
+        }
+        String osName = System.getProperty("os.name");
+        if (windir == null) {
+            try {
+                windir = getWinDir(osName);
+            } catch (IOException e) {
+                // should continue if this fails
+            }
+        }
+        File osFontsDir = null, psFontsDir = null;
+        if (windir != null) {
+            // remove any trailing '/'
+            if (windir.endsWith("/")) {
+                windir = windir.substring(0, windir.length() - 1);
+            }
+            osFontsDir = new File(windir + File.separator + "FONTS");
+            if (osFontsDir.exists() && osFontsDir.canRead()) {
+                fontDirList.add(osFontsDir);
+            }
+            psFontsDir = new File(windir.substring(0, 2) + File.separator + "PSFONTS");
+            if (psFontsDir.exists() && psFontsDir.canRead()) {
+                fontDirList.add(psFontsDir);
+            }
+        } else {
+            String windowsDirName = osName.endsWith("NT") ? "WINNT" : "WINDOWS";                
+            // look for true type font folder
+            for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++) {
+                osFontsDir = new File(
+                        driveLetter + ":"
+                        + File.separator + windowsDirName
+                        + File.separator + "FONTS");
+                if (osFontsDir.exists() && osFontsDir.canRead()) {
+                    fontDirList.add(osFontsDir);
+                    break;
+                }
+            }
+            // look for type 1 font folder
+            for (char driveLetter = 'C'; driveLetter <= 'E'; driveLetter++) {
+                psFontsDir = new File(driveLetter + ":" + File.separator + "PSFONTS");
+                if (psFontsDir.exists() && psFontsDir.canRead()) {
+                    fontDirList.add(psFontsDir);
+                    break;
+                }
+            }
+        }
+        return fontDirList;
+    }
+}
diff --git a/src/java/org/apache/fop/fonts/autodetect/package.html b/src/java/org/apache/fop/fonts/autodetect/package.html
new file mode 100644 (file)
index 0000000..0a29acb
--- /dev/null
@@ -0,0 +1,23 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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: $ -->
+<HTML>
+<TITLE>org.apache.fop.fonts.autodetect Package</TITLE>
+<BODY>
+<P>A collection of classes that aid in the autodetection of installed system fonts.</P>
+</BODY>
+</HTML>
index 319a208d7a1730c0d3607e1d121704aa61c25e11..7653d8df19c92acb086bdfa1a319e45164701653 100644 (file)
@@ -566,6 +566,14 @@ public class TTFFile {
         return familyName;
     }
 
+    /**
+     * Returns the font sub family name of the font.
+     * @return String The sub family name
+     */
+    public String getSubFamilyName() {
+        return subFamilyName;
+    }
+
     /**
      * Returns the name of the character set used.
      * @return String The caracter set
index 81810874d25c1c5b19363b91fc8297fc43428a8c..f5a0447b44a8689370ec8c38ca59283ce78eb678 100644 (file)
@@ -27,7 +27,6 @@ import java.util.Map;
 \r
 import org.apache.fop.fonts.BFEntry;\r
 import org.apache.fop.fonts.CIDFontType;\r
-import org.apache.fop.fonts.CustomFont;\r
 import org.apache.fop.fonts.FontLoader;\r
 import org.apache.fop.fonts.FontResolver;\r
 import org.apache.fop.fonts.MultiByteFont;\r
@@ -37,18 +36,23 @@ import org.apache.fop.fonts.MultiByteFont;
  */\r
 public class TTFFontLoader extends FontLoader {\r
 \r
-    private String fontFileURI;\r
-    private TTFFile ttf;\r
     private MultiByteFont multiFont;\r
-    private CustomFont returnFont;\r
-    private FontResolver resolver;\r
     \r
-    public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver) \r
-                throws IOException {\r
-        this.fontFileURI = fontFileURI;\r
-        this.resolver = resolver;\r
-\r
-        this.ttf = new TTFFile();\r
+    /**\r
+     * Default constructor\r
+     * @param fontFileURI the URI representing the font file\r
+     * @param in the InputStream to load the font from\r
+     * @param resolver the FontResolver for font URI resolution\r
+     */\r
+    public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver) {\r
+        super(fontFileURI, in, resolver);\r
+    }\r
+    \r
+    /**\r
+     * @see FontLoader#read()\r
+     */\r
+    protected void read() throws IOException {\r
+        TTFFile ttf = new TTFFile();\r
         FontFileReader reader = new FontFileReader(in);\r
         boolean supported = ttf.readFont(reader, null);\r
         if (!supported) {\r
@@ -61,11 +65,9 @@ public class TTFFontLoader extends FontLoader {
         multiFont = new MultiByteFont();\r
         multiFont.setResolver(this.resolver);\r
         returnFont = multiFont;\r
-        read();        \r
-    }\r
-    \r
-    private void read() throws IOException {\r
+\r
         returnFont.setFontName(ttf.getFamilyName());\r
+        returnFont.setFontSubFamilyName(ttf.getSubFamilyName());\r
         //multiFont.setTTCName(ttcName)\r
         returnFont.setCapHeight(ttf.getCapHeight());\r
         returnFont.setXHeight(ttf.getXHeight());\r
@@ -77,6 +79,7 @@ public class TTFFontLoader extends FontLoader {
         returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF\r
         returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));\r
         returnFont.setMissingWidth(0);\r
+        \r
         multiFont.setCIDType(CIDFontType.CIDTYPE2);\r
         int[] wx = ttf.getWidths();\r
         multiFont.setWidthArray(wx);\r
@@ -93,9 +96,12 @@ public class TTFFontLoader extends FontLoader {
         multiFont.setBFEntries(bfentries);\r
         copyKerning(ttf, true);\r
         multiFont.setEmbedFileName(this.fontFileURI);\r
-        \r
+        loaded = true;\r
     }\r
     \r
+    /**\r
+     * Copy kerning information.\r
+     */\r
     private void copyKerning(TTFFile ttf, boolean isCid) {\r
         \r
         // Get kerning\r
@@ -115,15 +121,7 @@ public class TTFFontLoader extends FontLoader {
             } else {\r
                 h2 = (Map)ttf.getAnsiKerning().get(kpx1);\r
             }\r
-\r
             returnFont.putKerningEntry(kpx1, h2);\r
         }\r
-    }\r
-    \r
-    \r
-    /** @see org.apache.fop.fonts.FontLoader#getFont() */\r
-    public CustomFont getFont() {\r
-        return this.returnFont;\r
-    }\r
-    \r
+    }    \r
 }\r
index ef0d457673ac65a05b3e04d936b86f3f6adb346b..3db4a6d2dbde772f62d89788af34f9a6f935f906 100644 (file)
@@ -22,7 +22,6 @@ package org.apache.fop.fonts.type1;
 import java.io.IOException;\r
 import java.io.InputStream;\r
 \r
-import org.apache.fop.fonts.CustomFont;\r
 import org.apache.fop.fonts.FontLoader;\r
 import org.apache.fop.fonts.FontResolver;\r
 import org.apache.fop.fonts.FontType;\r
@@ -33,11 +32,8 @@ import org.apache.fop.fonts.SingleByteFont;
  */\r
 public class Type1FontLoader extends FontLoader {\r
 \r
-    private String fontFileURI;\r
     private PFMFile pfm;\r
     private SingleByteFont singleFont;\r
-    private CustomFont returnFont;\r
-    private FontResolver resolver;\r
     \r
     /**\r
      * Constructs a new Type 1 font loader.\r
@@ -48,19 +44,19 @@ public class Type1FontLoader extends FontLoader {
      */\r
     public Type1FontLoader(String fontFileURI, InputStream in, FontResolver resolver) \r
                 throws IOException {\r
-        this.fontFileURI = fontFileURI;\r
-        this.resolver = resolver;\r
+        super(fontFileURI, in, resolver);\r
+    }\r
 \r
+    /**\r
+     * @see FontLoader#read()\r
+     */\r
+    protected void read() throws IOException {\r
         pfm = new PFMFile();\r
         pfm.load(in);\r
         singleFont = new SingleByteFont();\r
         singleFont.setFontType(FontType.TYPE1);\r
         singleFont.setResolver(this.resolver);\r
         returnFont = singleFont;\r
-        read();        \r
-    }\r
-    \r
-    private void read() throws IOException {\r
         returnFont.setFontName(pfm.getPostscriptName());\r
         returnFont.setCapHeight(pfm.getCapHeight());\r
         returnFont.setXHeight(pfm.getXHeight());\r
@@ -77,12 +73,5 @@ public class Type1FontLoader extends FontLoader {
             singleFont.setWidth(i, pfm.getCharWidth(i));\r
         }\r
         singleFont.setEmbedFileName(this.fontFileURI);\r
-        \r
-    }\r
-    \r
-    /** @see org.apache.fop.fonts.FontLoader#getFont() */\r
-    public CustomFont getFont() {\r
-        return this.returnFont;\r
     }\r
-    \r
 }\r
index 3ab0b8419179e74fafcdb7b3b13992ef754f14a0..e0ee7eb4ba57bacbc51eacc518170df5b4bf53fb 100644 (file)
@@ -24,14 +24,6 @@ import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
 
-// commons logging
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-// Avalon
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-
 /**
  * This class represents a list of PDF filters to be applied when serializing 
  * the output of a PDF object.
@@ -56,12 +48,7 @@ public class PDFFilterList {
     private List filters = new java.util.ArrayList();
 
     private boolean ignoreASCIIFilters = false;
-    
-    /**
-     * logging instance
-     */
-    protected static Log logger = LogFactory.getLog("org.apache.fop.render");
-    
+        
     /**
      * Default constructor.
      * <p>
@@ -290,53 +277,4 @@ public class PDFFilterList {
         }
         return out;
     }
-
-    /**
-     * Builds a filter map from an Avalon Configuration object.
-     * @param cfg the Configuration object
-     * @return Map the newly built filter map
-     * @throws ConfigurationException if a filter list is defined twice
-     */
-    public static Map buildFilterMapFromConfiguration(Configuration cfg) 
-                throws ConfigurationException {
-        Map filterMap = new java.util.HashMap();
-        Configuration[] filterLists = cfg.getChildren("filterList");
-        for (int i = 0; i < filterLists.length; i++) {
-            Configuration filters = filterLists[i];
-            String type = filters.getAttribute("type", null);
-            Configuration[] filt = filters.getChildren("value");
-            List filterList = new java.util.ArrayList();
-            for (int j = 0; j < filt.length; j++) {
-                String name = filt[j].getValue();
-                filterList.add(name);
-            }
-            
-            if (type == null) {
-                type = PDFFilterList.DEFAULT_FILTER;
-            }
-
-            if (!filterList.isEmpty() && logger.isDebugEnabled()) {
-                StringBuffer debug = new StringBuffer("Adding PDF filter");
-                if (filterList.size() != 1) {
-                    debug.append("s");
-                }
-                debug.append(" for type ").append(type).append(": ");
-                for (int j = 0; j < filterList.size(); j++) {
-                    if (j != 0) {
-                        debug.append(", ");
-                    }
-                    debug.append(filterList.get(j));
-                }
-                logger.debug(debug.toString());
-            }
-            
-            if (filterMap.get(type) != null) {
-                throw new ConfigurationException("A filterList of type '" 
-                    + type + "' has already been defined");
-            }
-            filterMap.put(type, filterList);
-        }
-        return filterMap;                
-    }
-
 }
index 50c314f156103f4532ae2aeef91951567fb04180..e2d314885a79ff8fadf8dc32b1f3a10d48705422 100644 (file)
@@ -69,18 +69,13 @@ import org.apache.fop.fonts.FontInfo;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-// Avalon
-import org.apache.avalon.framework.configuration.Configurable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-
 /**
  * Abstract base class for all renderers. The Abstract renderer does all the
  * top level processing of the area tree and adds some abstract methods to
  * handle viewports. This keeps track of the current block and inline position.
  */
 public abstract class AbstractRenderer 
-         implements Renderer, Configurable, Constants {
+         implements Renderer, Constants {
 
     /** logging instance */
     protected static Log log = LogFactory.getLog("org.apache.fop.render");
@@ -117,12 +112,6 @@ public abstract class AbstractRenderer
     
     private Set warnedXMLHandlers;
     
-    /**
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration conf) throws ConfigurationException {
-    }
-
     /**
      *  @see org.apache.fop.render.Renderer#setupFontInfo(FontInfo)
      */
@@ -804,39 +793,6 @@ public abstract class AbstractRenderer
         // Some renderers (ex. Text) don't support foreign objects.
     }
 
-    /**
-     * Returns the configuration subtree for a specific renderer.
-     * @param cfg the renderer configuration
-     * @param namespace the namespace (i.e. the XMLHandler) for which the configuration should
-     *                  be returned
-     * @return the requested configuration subtree, null if there's no configuration
-     */
-    public static Configuration getHandlerConfig(Configuration cfg, String namespace) {
-
-        if (cfg == null || namespace == null) {
-            return null;
-        }
-
-        Configuration handlerConfig = null;
-
-        Configuration[] children = cfg.getChildren("xml-handler");
-        for (int i = 0; i < children.length; ++i) {
-            try {
-                if (children[i].getAttribute("namespace").equals(namespace)) {
-                    handlerConfig = children[i];
-                    break;
-                }
-            } catch (ConfigurationException e) {
-                // silently pass over configurations without namespace
-            }
-        }
-        if (log.isDebugEnabled()) {
-            log.debug((handlerConfig == null ? "No" : "")
-                    + "XML handler configuration found for namespace " + namespace);
-        }
-        return handlerConfig;
-    }
-
     /**
      * Render the xml document with the given xml namespace.
      * The Render Context is by the handle to render into the current
@@ -851,15 +807,9 @@ public abstract class AbstractRenderer
                 this, namespace);
         if (handler != null) {
             try {
-                //Optional XML handler configuration
-                Configuration cfg = userAgent.getFactory().getUserRendererConfig(getMimeType());
-                if (cfg != null) {
-                    cfg = getHandlerConfig(cfg, namespace);
-                    if (cfg != null) {
-                        ctx.setProperty(RendererContextConstants.HANDLER_CONFIGURATION, cfg);
-                    }
-                }
-                
+                XMLHandlerConfigurator configurator
+                    = new XMLHandlerConfigurator(userAgent);
+                configurator.configure(ctx, namespace);
                 handler.handleXML(ctx, doc, namespace);
             } catch (Throwable t) {
                 // could not handle document
@@ -887,6 +837,4 @@ public abstract class AbstractRenderer
     public String getMimeType() {
         return null;
     }
-
 }
-
diff --git a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
new file mode 100644 (file)
index 0000000..1e48573
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Abstract base classes for renderer-related configurator classes. This class basically just
+ * provides an accessor to the specific renderer configuration object.
+ */
+public abstract class AbstractRendererConfigurator {
+
+    /** logger instance */
+    protected static Log log = LogFactory.getLog(AbstractRendererConfigurator.class);
+
+    /** fop factory configuration */
+    protected FOUserAgent userAgent = null;
+   
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public AbstractRendererConfigurator(FOUserAgent userAgent) {
+        super();
+        this.userAgent = userAgent;
+    }
+
+    
+    /**
+     * Returns the configuration subtree for a specific renderer.
+     * @param renderer the renderer
+     * @return the requested configuration subtree, null if there's no configuration
+     */
+    protected Configuration getRendererConfig(Renderer renderer) {
+        Configuration cfg = userAgent.getFactory().getUserConfig();
+        if (cfg == null) {
+            if (log.isDebugEnabled()) {
+                log.debug("userconfig is null");
+            }
+            return null;            
+        }
+    
+        String mimeType = renderer.getMimeType();
+        if (mimeType == null) {
+            if (log.isInfoEnabled()) {
+                log.info("renderer mimeType is null");
+            }
+            return null;
+        }
+        
+        Configuration userRendererConfig = null;
+    
+        Configuration[] cfgs
+            = cfg.getChild("renderers").getChildren("renderer");
+        for (int i = 0; i < cfgs.length; ++i) {
+            Configuration child = cfgs[i];
+            try {
+                if (child.getAttribute("mime").equals(mimeType)) {
+                    userRendererConfig = child;
+                    break;
+                }
+            } catch (ConfigurationException e) {
+                // silently pass over configurations without mime type
+            }
+        }
+        log.debug((userRendererConfig == null ? "No u" : "U")
+                  + "ser configuration found for MIME type " + mimeType);
+        return userRendererConfig;
+    }
+}
index 0c6bea6311aa751aba9556df51b42e199b02f162..ab1ddb3383bd6663dce0069bf6e578bbfe81fb1b 100644 (file)
@@ -29,10 +29,10 @@ public abstract class AbstractRendererMaker {
     \r
     /**\r
      * Instantiates a new renderer.\r
-     * @param ua the user agent\r
+     * @param userAgent the user agent\r
      * @return the newly instantiated renderer\r
      */\r
-    public abstract Renderer makeRenderer(FOUserAgent ua);\r
+    public abstract Renderer makeRenderer(FOUserAgent userAgent);\r
 \r
     /**\r
      * @return Indicates whether this renderer requires an OutputStream to work with.\r
@@ -44,6 +44,16 @@ public abstract class AbstractRendererMaker {
      */\r
     public abstract String[] getSupportedMimeTypes();\r
 \r
+    /**\r
+     * Returns a renderer config object that can be used to\r
+     * configure the renderer.\r
+     * @param userAgent user agent\r
+     * @return a config object that can be used to configure the renderer\r
+     */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return null;\r
+    }\r
+\r
     /**\r
      * Indicates whether a specific MIME type is supported by this renderer.\r
      * @param mimeType the MIME type (ex. "application/pdf")\r
@@ -58,5 +68,4 @@ public abstract class AbstractRendererMaker {
         }\r
         return false;\r
     }\r
-    \r
 }\r
index 6a3cdf2c68d773cd559c9ff7213c1b2e3bcf82fa..f725bd7117d512a0d509a3d1defd66089f17b9ca 100644 (file)
@@ -46,7 +46,26 @@ public abstract class PrintRenderer extends AbstractRenderer {
 
     /** list of fonts */
     protected List fontList = null;
+   
+    /**
+     * adds a font list to current list of fonts
+     * @param fontInfoList font list
+     */
+    public void addFontList(List fontInfoList) {
+        if (this.fontList == null) {
+            setFontList(fontInfoList);
+        } else {
+            this.fontList.addAll(fontInfoList);
+        }
+    }
     
+    /**
+     * @param fontList list of available fonts
+     */
+    public void setFontList(List fontList) {
+        this.fontList = fontList;
+    }
+
     /**
      * Set up the font info
      *
diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
new file mode 100644 (file)
index 0000000..d9b9229
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.fonts.CachedFontInfo;
+import org.apache.fop.fonts.EmbedFontInfo;
+import org.apache.fop.fonts.FontCache;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.autodetect.FontFileFinder;
+import org.apache.fop.fonts.autodetect.FontInfoFinder;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * Base Print renderer configurator (mostly handles font configuration)
+ */
+public class PrintRendererConfigurator extends AbstractRendererConfigurator 
+            implements RendererConfigurator {
+
+    /** have we already autodetected system fonts? */
+    private static boolean autodetectedFonts = false;
+
+    /** logger instance */
+    protected static Log log = LogFactory.getLog(PrintRendererConfigurator.class);
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public PrintRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Builds a list of EmbedFontInfo objects for use with the setup() method.
+     * 
+     * @param renderer print renderer
+     * @throws FOPException if something's wrong with the config data
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = getRendererConfig(renderer);
+        if (cfg == null) {
+            return;
+        }
+
+        PrintRenderer printRenderer = (PrintRenderer)renderer;
+        FontResolver fontResolver = printRenderer.getFontResolver();
+        if (fontResolver == null) {
+            //Ensure that we have minimal font resolution capabilities
+            fontResolver = FontSetup.createMinimalFontResolver();
+        }
+
+        FopFactory factory = userAgent.getFactory();
+        boolean strict = factory.validateUserConfigStrictly();
+        FontCache fontCache = factory.getFontCache();
+
+        List fontInfoList = buildFontListFromConfiguration(cfg, 
+                userAgent.getFontBaseURL(), fontResolver, strict, 
+                fontCache);
+        
+        if (fontCache != null && fontCache.hasChanged()) {
+            fontCache.save();
+        }
+        printRenderer.addFontList(fontInfoList);
+    }
+
+    /**
+     * Builds a list of EmbedFontInfo objects for use with the setup() method.
+     * 
+     * @param cfg Configuration object
+     * @param fontBaseURL the base URL to resolve relative font URLs with
+     * @param fontResolver the FontResolver to use
+     * @param strict true if an Exception should be thrown if an error is found.
+     * @param fontCache the font cache (or null if it is disabled)
+     * @return a List of EmbedFontInfo objects.
+     * @throws FOPException If an error occurs while processing the configuration
+     */
+    public static List buildFontListFromConfiguration(Configuration cfg, 
+            String fontBaseURL, FontResolver fontResolver, 
+            boolean strict, FontCache fontCache) throws FOPException {
+        List fontInfoList = new java.util.ArrayList();
+
+        Configuration fonts = cfg.getChild("fonts");
+        if (fonts != null) {
+            long start = 0;
+            if (log.isDebugEnabled()) {
+                log.debug("Starting font configuration...");
+                start = System.currentTimeMillis();
+            }
+            
+            // native o/s search (autodetect) configuration
+            boolean autodetectFonts = (fonts.getChild("auto-detect", false) != null);
+            if (!autodetectedFonts && autodetectFonts) {
+                // search in font base if it is defined and
+                // is a directory but don't recurse
+                FontFileFinder fontFileFinder = new FontFileFinder();
+                if (fontBaseURL != null) {
+                    try {
+                        File fontBase = FileUtils.toFile(new URL(fontBaseURL));
+                        if (fontBase != null) {
+                            //Can only use the font base URL if it's a file URL
+                            addFontInfoListFromFileList(
+                                    fontFileFinder.find(fontBase.getAbsolutePath()),
+                                    fontInfoList,
+                                    fontResolver,
+                                    fontCache
+                            );
+                        }
+                    } catch (IOException e) {
+                        LogUtil.handleException(log, e, strict);
+                    }
+                }
+
+                // native o/s font directory finder
+                try {
+                    addFontInfoListFromFileList(
+                            fontFileFinder.find(),
+                            fontInfoList,
+                            fontResolver,
+                            fontCache
+                    );
+                } catch (IOException e) {
+                    LogUtil.handleException(log, e, strict);
+                }
+                autodetectedFonts = true;
+            }
+
+            // directory (multiple font) configuration
+            Configuration[] directories = fonts.getChildren("directory");
+            for (int i = 0; i < directories.length; i++) {
+                boolean recursive = directories[i].getAttributeAsBoolean("recursive", false);
+                String directory = null;
+                try {
+                    directory = directories[i].getValue();
+                } catch (ConfigurationException e) {
+                    LogUtil.handleException(log, e, strict);
+                    continue;
+                }
+                if (directory == null) {
+                    LogUtil.handleException(log,
+                            new FOPException("directory defined without value"), strict);
+                    continue;
+                }
+                FontFileFinder fontFileFinder = new FontFileFinder(recursive ? -1 : 1);
+                try {
+                    addFontInfoListFromFileList(
+                            fontFileFinder.find(directory),
+                            fontInfoList,
+                            fontResolver,
+                            fontCache
+                    );
+                } catch (IOException e) {
+                    LogUtil.handleException(log, e, strict);
+                }
+            }
+            
+            // font file (singular) configuration
+            Configuration[] font = fonts.getChildren("font");
+            for (int i = 0; i < font.length; i++) {
+                EmbedFontInfo fontInfo = getFontInfoFromConfiguration(
+                        font[i], fontResolver, strict, fontCache);
+                if (fontInfo != null) {
+                    fontInfoList.add(fontInfo);
+                }
+            }
+            if (log.isDebugEnabled()) {
+                log.debug("Finished font configuration in " 
+                        + (System.currentTimeMillis() - start) + "ms");
+            }
+        }
+        return fontInfoList;
+    }
+
+    /**
+     * Iterates over font file list adding font info to list
+     * @param fontFileList font file list
+     * @param fontInfoList font info list
+     * @param resolver font resolver
+     */
+    private static void addFontInfoListFromFileList(
+            List fontFileList, List fontInfoList, FontResolver resolver, FontCache fontCache) {
+        for (Iterator iter = fontFileList.iterator(); iter.hasNext();) {
+            File fontFile = (File)iter.next();
+            // parse font to ascertain font info
+            FontInfoFinder finder = new FontInfoFinder();
+            EmbedFontInfo fontInfo = finder.find(fontFile, resolver, fontCache);
+            if (fontInfo != null) {
+                fontInfoList.add(fontInfo);                
+            }
+        }
+    }
+        
+    /**
+     * Returns a font info from a font node Configuration definition
+     * 
+     * @param fontCfg Configuration object (font node)
+     * @param fontResolver font resolver used to resolve font
+     * @param strict validate configuration strictly
+     * @param fontCache the font cache (or null if it is disabled)
+     * @return font info
+     * @throws FOPException if something's wrong with the config data
+     */
+    public static EmbedFontInfo getFontInfoFromConfiguration(
+            Configuration fontCfg, FontResolver fontResolver, boolean strict, FontCache fontCache)
+    throws FOPException {
+        String metricsUrl = fontCfg.getAttribute("metrics-url", null);
+        String embedUrl = fontCfg.getAttribute("embed-url", null);
+
+        if (metricsUrl == null && embedUrl == null) {
+            LogUtil.handleError(log, "Font configuration without metric-url or embed-url", strict);
+            return null;
+        }
+        if (embedUrl != null) {
+            StreamSource source = (StreamSource)fontResolver.resolve(embedUrl);
+            if (source == null) {
+                LogUtil.handleError(log,
+                        "Failed to resolve font with embed-url '" + embedUrl + "'", strict);
+                return null;
+            }
+            embedUrl = source.getSystemId(); // absolute path/url
+        }
+        if (metricsUrl != null) {
+            StreamSource source = (StreamSource)fontResolver.resolve(metricsUrl);
+            if (source == null) {
+                LogUtil.handleError(log,
+                        "Failed to resolve font with metric-url '" + metricsUrl + "'", strict);
+                return null;
+            }
+            metricsUrl = source.getSystemId(); // absolute path/url
+        }
+        boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true);
+                        
+        EmbedFontInfo fontInfo = null;
+        Configuration[] tripletCfg = fontCfg.getChildren("font-triplet");
+        // no font triplet info
+        if (tripletCfg.length == 0) {
+            LogUtil.handleError(log, "font without font-triplet", strict);
+
+            // if not strict try to determine font info from the embed/metrics url
+            File fontFile = CachedFontInfo.getFileFromUrls(new String[] {embedUrl, metricsUrl});
+            if (fontFile != null) {
+                FontInfoFinder finder = new FontInfoFinder();
+                return finder.find(fontFile, fontResolver, fontCache);
+            } else {
+                return null;
+            }
+        } else {
+            List tripleList = new java.util.ArrayList();
+            for (int j = 0; j < tripletCfg.length; j++) {
+                try {
+                    String name = tripletCfg[j].getAttribute("name");
+                    if (name == null) {
+                        LogUtil.handleError(log, "font-triplet without name", strict);
+                        continue;
+                    }
+                    String weightStr = tripletCfg[j].getAttribute("weight");
+                    if (weightStr == null) {
+                        LogUtil.handleError(log, "font-triplet without weight", strict);
+                        continue;
+                    }
+                    int weight = FontUtil.parseCSS2FontWeight(weightStr);
+                    String style = tripletCfg[j].getAttribute("style");
+                    if (style == null) {
+                        LogUtil.handleError(log, "font-triplet without style", strict);
+                        continue;
+                    }
+                    tripleList.add(FontInfo.createFontKey(name, style, weight));
+                } catch (ConfigurationException e) {
+                    LogUtil.handleException(log, e, strict);
+                }
+            }
+            
+            fontInfo = new EmbedFontInfo(metricsUrl, useKerning, tripleList, embedUrl);
+            
+            if (fontCache != null) {
+                if (!fontCache.containsFont(fontInfo)) {
+                    fontCache.addFont(fontInfo);                    
+                }
+            }
+
+            if (log.isDebugEnabled()) {
+                log.debug("Adding font " + fontInfo.getEmbedFile()
+                        + ", metric file " + fontInfo.getMetricsFile());
+                for (int j = 0; j < tripleList.size(); ++j) {
+                    FontTriplet triplet = (FontTriplet) tripleList.get(j);
+                    log.debug("  Font triplet "
+                            + triplet.getName() + ", "
+                            + triplet.getStyle() + ", "
+                            + triplet.getWeight());
+                }
+            }            
+        }
+        return fontInfo;
+    }
+    
+}
diff --git a/src/java/org/apache/fop/render/RendererConfigurator.java b/src/java/org/apache/fop/render/RendererConfigurator.java
new file mode 100644 (file)
index 0000000..566daf0
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render;
+
+import org.apache.fop.apps.FOPException;
+
+/**
+ * Renderer configurator interface
+ */
+public interface RendererConfigurator {
+    /**
+     * Configures a renderer
+     * @param renderer renderer
+     * @throws FOPException fop exception
+     */
+    void configure(Renderer renderer) throws FOPException;
+}
index 49f53b327ac4c10d5bdfe1f6a56339acb0503bfe..feffc05edba30cc08cffb3a037987d27921307e3 100644 (file)
@@ -23,7 +23,6 @@ package org.apache.fop.render;
 import java.util.Map;
 
 //FOP
-import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.fop.apps.FOUserAgent;
 
 /**
@@ -156,17 +155,10 @@ public class RendererContext {
             return ((Integer)context.getProperty(RendererContextConstants.HEIGHT)).intValue();
         }
 
-        /** @return the handler configuration */
-        public Configuration getHandlerConfiguration() {
-            return (Configuration)context.getProperty(
-                    RendererContextConstants.HANDLER_CONFIGURATION);
-        }
-
         /** @return the foreign attributes */
         public Map getForeignAttributes() {
             return (Map)context.getProperty(RendererContextConstants.FOREIGN_ATTRIBUTES);
-        }
-        
+        }        
     }    
 }
 
index 4d3f3a12cb8e758d7630701313262e10309fa1db..d81f900e036367468241f68272ec9d3861c8eb7b 100644 (file)
@@ -25,9 +25,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -185,18 +182,9 @@ public class RendererFactory {
             }
             Renderer rend = maker.makeRenderer(userAgent);
             rend.setUserAgent(userAgent);
-            String mimeType = rend.getMimeType(); //Always use main MIME type for this
-            Configuration userRendererConfig = null;
-            if (mimeType != null) {
-                userRendererConfig
-                    = userAgent.getFactory().getUserRendererConfig(mimeType);
-            }
-            if (userRendererConfig != null) {
-                try {
-                    ContainerUtil.configure(rend, userRendererConfig);
-                } catch (ConfigurationException e) {
-                    throw new FOPException(e);
-                }
+            RendererConfigurator configurator = maker.getConfigurator(userAgent);
+            if (configurator != null) {
+                configurator.configure(rend);
             }
             return rend;
         }
diff --git a/src/java/org/apache/fop/render/XMLHandlerConfigurator.java b/src/java/org/apache/fop/render/XMLHandlerConfigurator.java
new file mode 100644 (file)
index 0000000..bf63329
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+
+/**
+ * Configurator for XMLHandler objects. 
+ */
+public class XMLHandlerConfigurator extends AbstractRendererConfigurator {
+
+    /** logger instance */
+    protected static Log log = LogFactory.getLog(XMLHandlerConfigurator.class);
+    
+    /**
+     * Default constructor
+     * @param userAgent the user agent
+     */
+    public XMLHandlerConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Returns the configuration subtree for a specific renderer.
+     * @param cfg the renderer configuration
+     * @param namespace the namespace (i.e. the XMLHandler) for which the configuration should
+     *                  be returned
+     * @return the requested configuration subtree, null if there's no configuration
+     */
+    private Configuration getHandlerConfig(Configuration cfg, String namespace) {
+        if (cfg == null || namespace == null) {
+            return null;
+        }
+        Configuration handlerConfig = null;
+
+        Configuration[] children = cfg.getChildren("xml-handler");
+        for (int i = 0; i < children.length; ++i) {
+            try {
+                if (children[i].getAttribute("namespace").equals(namespace)) {
+                    handlerConfig = children[i];
+                    break;
+                }
+            } catch (ConfigurationException e) {
+                // silently pass over configurations without namespace
+            }
+        }
+        if (log.isDebugEnabled()) {
+            log.debug((handlerConfig == null ? "No" : "")
+                    + "XML handler configuration found for namespace " + namespace);
+        }
+        return handlerConfig;
+    }
+
+    /**
+     * Configures renderer context by setting the handler configuration on it.
+     * @param context the RendererContext (contains the user agent)
+     * @param ns the Namespace of the foreign object
+     * @throws FOPException if configuring the target objects fails
+     */
+    public void configure(RendererContext context, String ns) throws FOPException {
+        //Optional XML handler configuration
+        Configuration cfg = getRendererConfig(context.getRenderer());
+        if (cfg != null) {
+            cfg = getHandlerConfig(cfg, ns);
+            if (cfg != null) {
+                context.setProperty(RendererContextConstants.HANDLER_CONFIGURATION, cfg);
+            }
+        }
+    }
+}
index 78d8b7d0afa42c5b02f41d237c863c57f8936e66..ea1087893b05c8554e597baaaa2cf27c0b25a72e 100644 (file)
@@ -33,8 +33,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
@@ -57,8 +55,6 @@ import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontMetrics;
 import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.FontUtil;
-import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.base14.Courier;
 import org.apache.fop.fonts.base14.Helvetica;
 import org.apache.fop.fonts.base14.TimesRoman;
@@ -76,7 +72,6 @@ import org.apache.fop.render.afp.fonts.AFPFont;
 import org.apache.fop.render.afp.fonts.CharacterSet;
 import org.apache.fop.render.afp.fonts.FopCharacterSet;
 import org.apache.fop.render.afp.fonts.OutlineFont;
-import org.apache.fop.render.afp.fonts.RasterFont;
 import org.apache.fop.render.afp.modca.AFPConstants;
 import org.apache.fop.render.afp.modca.AFPDataStream;
 import org.apache.fop.render.afp.modca.ImageObject;
@@ -302,195 +297,6 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
         }
     }
 
-    /**
-     */
-    private AFPFontInfo buildFont(Configuration fontCfg, String _path)
-        throws ConfigurationException {
-
-        Configuration[] triple = fontCfg.getChildren("font-triplet");
-        List tripleList = new java.util.ArrayList();
-        if (triple.length == 0) {
-            log.error("Mandatory font configuration element '<font-triplet...' is missing");
-            return null;
-        }
-        for (int j = 0; j < triple.length; j++) {
-            int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
-            tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
-                                           triple[j].getAttribute("style"),
-                                           weight));
-        }
-
-        //build the fonts
-        Configuration afpFontCfg = fontCfg.getChild("afp-font");
-        if (afpFontCfg == null) {
-            log.error("Mandatory font configuration element '<afp-font...' is missing");
-            return null;
-        }
-        String path = afpFontCfg.getAttribute("path", _path);
-        String type = afpFontCfg.getAttribute("type");
-        if (type == null) {
-            log.error("Mandatory afp-font configuration attribute 'type=' is missing");
-            return null;
-        }
-        String codepage = afpFontCfg.getAttribute("codepage");
-        if (codepage == null) {
-            log.error("Mandatory afp-font configuration attribute 'code=' is missing");
-            return null;
-        }
-        String encoding = afpFontCfg.getAttribute("encoding");
-        if (encoding == null) {
-            log.error("Mandatory afp-font configuration attribute 'encoding=' is missing");
-            return null;
-        }
-
-        if ("raster".equalsIgnoreCase(type)) {
-
-            String name = afpFontCfg.getAttribute("name", "Unknown");
-
-            // Create a new font object
-            RasterFont font = new RasterFont(name);
-
-            Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font");
-            if (rasters.length == 0) {
-                log.error("Mandatory font configuration elements '<afp-raster-font...' are missing");
-                return null;
-            }
-            for (int j = 0; j < rasters.length; j++) {
-                Configuration rasterCfg = rasters[j];
-
-                String characterset = rasterCfg.getAttribute("characterset");
-                if (characterset == null) {
-                    log.error("Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
-                    return null;
-                }
-                int size = rasterCfg.getAttributeAsInteger("size");
-                String base14 = rasterCfg.getAttribute("base14-font", null);
-
-                if (base14 != null) {
-                    try {
-                        Class clazz = Class.forName("org.apache.fop.fonts.base14."
-                            + base14);
-                        try {
-                            Typeface tf = (Typeface)clazz.newInstance();
-                            font.addCharacterSet(size, new FopCharacterSet(
-                                codepage, encoding, characterset, size, tf));
-                        } catch (Exception ie) {
-                            String msg = "The base 14 font class " + clazz.getName()
-                                + " could not be instantiated";
-                            log.error(msg);
-                        }
-                    } catch (ClassNotFoundException cnfe) {
-                        String msg = "The base 14 font class for " + characterset
-                            + " could not be found";
-                        log.error(msg);
-                    }
-                } else {
-                    font.addCharacterSet(size, new CharacterSet(
-                        codepage, encoding, characterset, path));
-                }
-            }
-            return new AFPFontInfo(font, tripleList);
-
-        } else if ("outline".equalsIgnoreCase(type)) {
-
-            String characterset = afpFontCfg.getAttribute("characterset");
-            if (characterset == null) {
-                log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
-                return null;
-            }
-            String name = afpFontCfg.getAttribute("name", characterset);
-
-            CharacterSet characterSet = null;
-
-            String base14 = afpFontCfg.getAttribute("base14-font", null);
-
-            if (base14 != null) {
-                try {
-                    Class clazz = Class.forName("org.apache.fop.fonts.base14."
-                        + base14);
-                    try {
-                        Typeface tf = (Typeface)clazz.newInstance();
-                        characterSet = new FopCharacterSet(
-                                codepage, encoding, characterset, 1, tf);
-                    } catch (Exception ie) {
-                        String msg = "The base 14 font class " + clazz.getName()
-                            + " could not be instantiated";
-                        log.error(msg);
-                    }
-                } catch (ClassNotFoundException cnfe) {
-                    String msg = "The base 14 font class for " + characterset
-                        + " could not be found";
-                    log.error(msg);
-                }
-            } else {
-                characterSet = new CharacterSet(codepage, encoding, characterset, path);
-            }
-            // Create a new font object
-            OutlineFont font = new OutlineFont(name, characterSet);
-            return new AFPFontInfo(font, tripleList);
-        } else {
-            log.error("No or incorrect type attribute");
-        }
-        return null;
-    }
-
-    /**
-     * Builds a list of AFPFontInfo objects for use with the setup() method.
-     * @param cfg Configuration object
-     * @return List the newly created list of fonts
-     * @throws ConfigurationException if something's wrong with the config data
-     */
-    public List buildFontListFromConfiguration(Configuration cfg)
-            throws ConfigurationException {
-        List fontList = new java.util.ArrayList();
-        Configuration[] font = cfg.getChild("fonts").getChildren("font");
-        for (int i = 0; i < font.length; i++) {
-            AFPFontInfo afi = buildFont(font[i], null);
-            if (afi != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Adding font " + afi.getAFPFont().getFontName());
-                    for (int j = 0; j < afi.getFontTriplets().size(); ++j) {
-                        FontTriplet triplet = (FontTriplet) afi.getFontTriplets().get(j);
-                        log.debug("Font triplet "
-                                  + triplet.getName() + ", "
-                                  + triplet.getStyle() + ", "
-                                  + triplet.getWeight());
-                    }
-                }
-
-                fontList.add(afi);
-            }
-        }
-        return fontList;
-    }
-
-    /**
-     * Configure the AFP renderer.
-     * Get the configuration to be used for fonts etc.
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        //Font configuration
-        this.fontList = buildFontListFromConfiguration(cfg);
-        Configuration images = cfg.getChild("images");
-        if (!"color".equalsIgnoreCase(images.getAttribute("mode", "b+w"))) {
-            bitsPerPixel = images.getAttributeAsInteger("bits-per-pixel", 8);
-            switch (bitsPerPixel) {
-                case 1:
-                case 4:
-                case 8:
-                    break;
-                default:
-                    log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
-                    bitsPerPixel = 8;
-                    break;
-            }
-        } else {
-            colorImages = true;
-        }
-
-    }
-
     /**
      * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
      */
@@ -1765,5 +1571,22 @@ public class AFPRenderer extends AbstractPathOrientedRenderer {
         }
     }
 
+    public void setBitsPerPixel(int bitsPerPixel) {
+        this.bitsPerPixel = bitsPerPixel;
+        switch (bitsPerPixel) {
+            case 1:
+            case 4:
+            case 8:
+            break;
+        default:
+            log.warn("Invalid bits_per_pixel value, must be 1, 4 or 8.");
+            bitsPerPixel = 8;
+            break;
+        }
+    }
+
+    public void setColorImages(boolean colorImages) {
+        this.colorImages = colorImages;
+    }
 }
 
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
new file mode 100644 (file)
index 0000000..aebabd9
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.afp;
+
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.render.afp.fonts.AFPFontInfo;
+import org.apache.fop.render.afp.fonts.CharacterSet;
+import org.apache.fop.render.afp.fonts.FopCharacterSet;
+import org.apache.fop.render.afp.fonts.OutlineFont;
+import org.apache.fop.render.afp.fonts.RasterFont;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * AFP Renderer configurator 
+ */
+public class AFPRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public AFPRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    private AFPFontInfo buildFont(Configuration fontCfg, String fontPath)
+        throws ConfigurationException {
+
+        Configuration[] triple = fontCfg.getChildren("font-triplet");
+        List tripleList = new java.util.ArrayList();
+        if (triple.length == 0) {
+            log.error("Mandatory font configuration element '<font-triplet...' is missing");
+            return null;
+        }
+        for (int j = 0; j < triple.length; j++) {
+            int weight = FontUtil.parseCSS2FontWeight(triple[j].getAttribute("weight"));
+            tripleList.add(new FontTriplet(triple[j].getAttribute("name"),
+                                           triple[j].getAttribute("style"),
+                                           weight));
+        }
+
+        //build the fonts
+        Configuration afpFontCfg = fontCfg.getChild("afp-font");
+        if (afpFontCfg == null) {
+            log.error("Mandatory font configuration element '<afp-font...' is missing");
+            return null;
+        }
+        String path = afpFontCfg.getAttribute("path", fontPath);
+        String type = afpFontCfg.getAttribute("type");
+        if (type == null) {
+            log.error("Mandatory afp-font configuration attribute 'type=' is missing");
+            return null;
+        }
+        String codepage = afpFontCfg.getAttribute("codepage");
+        if (codepage == null) {
+            log.error("Mandatory afp-font configuration attribute 'code=' is missing");
+            return null;
+        }
+        String encoding = afpFontCfg.getAttribute("encoding");
+        if (encoding == null) {
+            log.error("Mandatory afp-font configuration attribute 'encoding=' is missing");
+            return null;
+        }
+
+        if ("raster".equalsIgnoreCase(type)) {
+
+            String name = afpFontCfg.getAttribute("name", "Unknown");
+
+            // Create a new font object
+            RasterFont font = new RasterFont(name);
+
+            Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font");
+            if (rasters.length == 0) {
+                log.error(
+                        "Mandatory font configuration elements '<afp-raster-font...' are missing");
+                return null;
+            }
+            for (int j = 0; j < rasters.length; j++) {
+                Configuration rasterCfg = rasters[j];
+
+                String characterset = rasterCfg.getAttribute("characterset");
+                if (characterset == null) {
+                    log.error(
+                    "Mandatory afp-raster-font configuration attribute 'characterset=' is missing");
+                    return null;
+                }
+                int size = rasterCfg.getAttributeAsInteger("size");
+                String base14 = rasterCfg.getAttribute("base14-font", null);
+
+                if (base14 != null) {
+                    try {
+                        Class clazz = Class.forName("org.apache.fop.fonts.base14."
+                            + base14);
+                        try {
+                            Typeface tf = (Typeface)clazz.newInstance();
+                            font.addCharacterSet(size, new FopCharacterSet(
+                                codepage, encoding, characterset, size, tf));
+                        } catch (Exception ie) {
+                            String msg = "The base 14 font class " + clazz.getName()
+                                + " could not be instantiated";
+                            log.error(msg);
+                        }
+                    } catch (ClassNotFoundException cnfe) {
+                        String msg = "The base 14 font class for " + characterset
+                            + " could not be found";
+                        log.error(msg);
+                    }
+                } else {
+                    font.addCharacterSet(size, new CharacterSet(
+                        codepage, encoding, characterset, path));
+                }
+            }
+            return new AFPFontInfo(font, tripleList);
+
+        } else if ("outline".equalsIgnoreCase(type)) {
+
+            String characterset = afpFontCfg.getAttribute("characterset");
+            if (characterset == null) {
+                log.error("Mandatory afp-font configuration attribute 'characterset=' is missing");
+                return null;
+            }
+            String name = afpFontCfg.getAttribute("name", characterset);
+
+            CharacterSet characterSet = null;
+
+            String base14 = afpFontCfg.getAttribute("base14-font", null);
+
+            if (base14 != null) {
+                try {
+                    Class clazz = Class.forName("org.apache.fop.fonts.base14."
+                        + base14);
+                    try {
+                        Typeface tf = (Typeface)clazz.newInstance();
+                        characterSet = new FopCharacterSet(
+                                codepage, encoding, characterset, 1, tf);
+                    } catch (Exception ie) {
+                        String msg = "The base 14 font class " + clazz.getName()
+                            + " could not be instantiated";
+                        log.error(msg);
+                    }
+                } catch (ClassNotFoundException cnfe) {
+                    String msg = "The base 14 font class for " + characterset
+                        + " could not be found";
+                    log.error(msg);
+                }
+            } else {
+                characterSet = new CharacterSet(codepage, encoding, characterset, path);
+            }
+            // Create a new font object
+            OutlineFont font = new OutlineFont(name, characterSet);
+            return new AFPFontInfo(font, tripleList);
+        } else {
+            log.error("No or incorrect type attribute");
+        }
+        return null;
+    }
+    
+    /**
+     * Builds a list of AFPFontInfo objects for use with the setup() method.
+     * @param cfg Configuration object
+     * @return List the newly created list of fonts
+     * @throws ConfigurationException if something's wrong with the config data
+     */
+    private List buildFontListFromConfiguration(Configuration cfg)
+            throws ConfigurationException {
+        List fontList = new java.util.ArrayList();
+        Configuration[] font = cfg.getChild("fonts").getChildren("font");
+        for (int i = 0; i < font.length; i++) {
+            AFPFontInfo afi = buildFont(font[i], null);
+            if (afi != null) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Adding font " + afi.getAFPFont().getFontName());
+                    for (int j = 0; j < afi.getFontTriplets().size(); ++j) {
+                        FontTriplet triplet = (FontTriplet) afi.getFontTriplets().get(j);
+                        log.debug("  Font triplet "
+                                  + triplet.getName() + ", "
+                                  + triplet.getStyle() + ", "
+                                  + triplet.getWeight());
+                    }
+                }
+
+                fontList.add(afi);
+            }
+        }
+        return fontList;
+    }
+
+    /**
+     * Configure the AFP renderer.
+     * @param renderer AFP renderer
+     * @throws FOPException fop exception
+     * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer)
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            AFPRenderer afpRenderer = (AFPRenderer)renderer;
+            try {
+                List fontList = buildFontListFromConfiguration(cfg);
+                afpRenderer.setFontList(fontList);
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e,
+                        userAgent.getFactory().validateUserConfigStrictly());
+            }
+            
+            Configuration images = cfg.getChild("images");
+            if (!"color".equalsIgnoreCase(images.getAttribute("mode", "b+w"))) {
+                afpRenderer.setBitsPerPixel(images.getAttributeAsInteger("bits-per-pixel", 8));
+            } else {
+                afpRenderer.setColorImages(true);
+            }
+        }
+    }
+}
index 2d6d5711dcb0b0e0f075003886dc8750a3ad8892..70bbe907612ff00054590c1806b2481277cf4017 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;
 import org.apache.fop.render.AbstractRendererMaker;
 import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfigurator;
 
 /**
  * RendererMaker for the AFP Renderer.
@@ -35,10 +36,15 @@ public class AFPRendererMaker extends AbstractRendererMaker {
 
 
     /**@see org.apache.fop.render.AbstractRendererMaker */
-    public Renderer makeRenderer(FOUserAgent ua) {
+    public Renderer makeRenderer(FOUserAgent userAgent) {
         return new AFPRenderer();
     }
 
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+        return new AFPRendererConfigurator(userAgent);
+    }
+
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
     public boolean needsOutputStream() {
         return true;
index 6a50c02946509dae41ea7140187fe8d89e32861d..e83d8d22060b02c292b00272a0eb29a7237e280b 100644 (file)
@@ -38,6 +38,7 @@ import java.io.IOException;
 
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactoryConfigurator;
 import org.apache.fop.apps.MimeConstants;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.PageViewport;
@@ -149,10 +150,10 @@ public class AWTRenderer extends Java2DRenderer implements Pageable {
         pageWidth = (int) Math.round(bounds.getWidth() / 1000f);
         pageHeight = (int) Math.round(bounds.getHeight() / 1000f);
         double scaleX = scaleFactor 
-                * (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION)
+                * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
                 / userAgent.getTargetPixelUnitToMillimeter();
         double scaleY = scaleFactor 
-                * (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION)
+                * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
                 / userAgent.getTargetPixelUnitToMillimeter();
         int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5);
         int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5);
index c96c82259e24706a2bec4b70afc4857ab223ba3a..5c22c8f34e7f56ec8347228e5f178400fe0505af 100644 (file)
@@ -32,9 +32,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Iterator;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-
 import org.apache.commons.logging.Log;
 
 import org.apache.xmlgraphics.image.GraphicsUtil;
@@ -77,12 +74,12 @@ public class TIFFRenderer extends Java2DRenderer {
 
     //private static final String COMPRESSION_NONE = "NONE";
     //private static final String COMPRESSION_JPEG = "JPEG";
-    private static final String COMPRESSION_PACKBITS = "PackBits";
+    public static final String COMPRESSION_PACKBITS = "PackBits";
     //private static final String COMPRESSION_DEFLATE = "Deflate";
     //private static final String COMPRESSION_LZW = "LZW";
     //private static final String COMPRESSION_ZLIB = "ZLib";
-    private static final String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
-    private static final String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
+    public static final String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
+    public static final String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
     
     /** ImageWriter parameters */
     private ImageWriterParams writerParams;
@@ -115,30 +112,6 @@ public class TIFFRenderer extends Java2DRenderer {
         writerParams.setResolution(dpi);
     }
 
-    /**
-     * Configure the TIFF renderer. Get the configuration to be used for
-     * compression
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        super.configure(cfg);
-
-        //set compression
-        String name = cfg.getChild("compression").getValue(COMPRESSION_PACKBITS);
-        //Some compression formats need a special image format:
-        if (name.equalsIgnoreCase(COMPRESSION_CCITT_T6)) {
-            bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
-        } else if (name.equalsIgnoreCase(COMPRESSION_CCITT_T4)) {
-            bufferedImageType = BufferedImage.TYPE_BYTE_BINARY;
-        } else {
-            bufferedImageType = BufferedImage.TYPE_INT_ARGB;
-        }
-        if (!"NONE".equalsIgnoreCase(name)) {
-            writerParams.setCompressionMethod(name);
-        }
-        log.info("TIFF compression set to " + name);
-    }
-
     /** @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream) */
     public void startRenderer(OutputStream outputStream) throws IOException {
         this.outputStream = outputStream;
@@ -253,4 +226,12 @@ public class TIFFRenderer extends Java2DRenderer {
                     "Method 'remove' is not supported.");
         }
     }
+
+    public void setBufferedImageType(int bufferedImageType) {
+        this.bufferedImageType = bufferedImageType;
+    }
+
+    public ImageWriterParams getWriterParams() {
+        return writerParams;
+    }
 }
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java
new file mode 100644 (file)
index 0000000..2e4e296
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.bitmap;
+
+import java.awt.image.BufferedImage;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+
+/**
+ * TIFF Renderer configurator 
+ */
+public class TIFFRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public TIFFRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the TIFF renderer. Get the configuration to be used for
+     * compression
+     * @param renderer tiff renderer
+     * @throws FOPException fop exception
+     * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer)
+     */
+    public void configure(Renderer renderer) throws FOPException {        
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            TIFFRenderer tiffRenderer = (TIFFRenderer)renderer;
+            //set compression
+            String name = cfg.getChild("compression").getValue(TIFFRenderer.COMPRESSION_PACKBITS);
+            //Some compression formats need a special image format:
+            if (name.equalsIgnoreCase(TIFFRenderer.COMPRESSION_CCITT_T6)) {
+                tiffRenderer.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
+            } else if (name.equalsIgnoreCase(TIFFRenderer.COMPRESSION_CCITT_T4)) {
+                tiffRenderer.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
+            } else {
+                tiffRenderer.setBufferedImageType(BufferedImage.TYPE_INT_ARGB);
+            }
+            if (!"NONE".equalsIgnoreCase(name)) {
+                tiffRenderer.getWriterParams().setCompressionMethod(name);
+            }
+            if (log.isInfoEnabled()) {
+                log.info("TIFF compression set to " + name);
+            }
+        }
+    }
+}
index ee2ba75fd1cc4f57f0543bd66c58aaffdfe9d8d2..5e9f18261361cd9b0e667046ee07b3e67b8b74b7 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the TIFF Renderer.\r
@@ -31,12 +32,16 @@ public class TIFFRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_TIFF};\r
     \r
-    \r
-    /** @see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new TIFFRenderer();\r
     }\r
 \r
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new TIFFRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
index ceda8f16c9f8db910c7be15733e6152128fb9634..e1dffd0e7a1a4f316a6e11ceced01febb8bc2e68 100644 (file)
@@ -139,52 +139,52 @@ public class FontSetup {
         // fontInfo.addMetrics("F17", new BauerBodoniBoldItalic());
 
         /* any is treated as serif */
-        fontInfo.addFontProperties("F5", "any", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "any", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "any", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "any", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "any", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F8", "any", "oblique", Font.BOLD);
+        fontInfo.addFontProperties("F5", "any", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "any", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "any", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "any", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "any", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "any", "oblique", Font.WEIGHT_BOLD);
 
-        fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "serif", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "serif", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "serif", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "serif", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "serif", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "serif", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F9", "monospace", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "monospace", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "monospace", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F11", "monospace", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F12", "monospace", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F12", "monospace", "italic", Font.BOLD);
+        fontInfo.addFontProperties("F1", "sans-serif", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "sans-serif", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "sans-serif", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F3", "sans-serif", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "sans-serif", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "sans-serif", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "serif", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "serif", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "serif", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "serif", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "serif", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "serif", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F9", "monospace", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "monospace", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "monospace", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F11", "monospace", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "monospace", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "monospace", "italic", Font.WEIGHT_BOLD);
 
-        fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "Times", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F9", "Courier", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "Courier", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F10", "Courier", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F11", "Courier", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F12", "Courier", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F12", "Courier", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F13", "Symbol", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.NORMAL);
+        fontInfo.addFontProperties("F1", "Helvetica", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "Helvetica", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F2", "Helvetica", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F3", "Helvetica", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "Helvetica", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F4", "Helvetica", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "Times", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F9", "Courier", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "Courier", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F10", "Courier", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F11", "Courier", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "Courier", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F12", "Courier", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F13", "Symbol", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F14", "ZapfDingbats", "normal", Font.WEIGHT_NORMAL);
 
         // Custom type 1 fonts step 2/2
         // fontInfo.addFontProperties("F15", "OMEP", "normal", FontInfo.NORMAL);
@@ -192,20 +192,20 @@ public class FontSetup {
         // fontInfo.addFontProperties("F17", "BauerBodoni", "italic", FontInfo.BOLD);
 
         /* for compatibility with PassiveTex */
-        fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.BOLD);
-        fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.NORMAL);
-        fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.NORMAL);
-        fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.BOLD);
-        fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.BOLD);
+        fontInfo.addFontProperties("F5", "Times-Roman", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times-Roman", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times-Roman", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times-Roman", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times-Roman", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times-Roman", "italic", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F5", "Times Roman", "normal", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times Roman", "oblique", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F6", "Times Roman", "italic", Font.WEIGHT_NORMAL);
+        fontInfo.addFontProperties("F7", "Times Roman", "normal", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times Roman", "oblique", Font.WEIGHT_BOLD);
+        fontInfo.addFontProperties("F8", "Times Roman", "italic", Font.WEIGHT_BOLD);
         fontInfo.addFontProperties("F9", "Computer-Modern-Typewriter",
-                                   "normal", Font.NORMAL);
+                                   "normal", Font.WEIGHT_NORMAL);
         
         configureInstalledAWTFonts(fontInfo, graphics, LAST_PREDEFINED_FONT_NUMBER + 1);
     }
@@ -252,9 +252,9 @@ public class FontSetup {
         FontMetricsMapper metric = new FontMetricsMapper(family, fontStyle, graphics);
         fontInfo.addMetrics(fontKey, metric);
         
-        int weight = Font.NORMAL;
+        int weight = Font.WEIGHT_NORMAL;
         if ((fontStyle & java.awt.Font.BOLD) != 0) {
-            weight = Font.BOLD;
+            weight = Font.WEIGHT_BOLD;
         }
         String style = "normal";
         if ((fontStyle & java.awt.Font.ITALIC) != 0) {
index 2bb3711bbf76459260abdfb0097066882cd1b696..7d837e6995bb492cbfe3b6d3efe735d23dec3e6f 100644 (file)
@@ -53,10 +53,9 @@ import java.util.Stack;
 
 import org.w3c.dom.Document;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactoryConfigurator;
 import org.apache.fop.area.CTM;
 import org.apache.fop.area.PageViewport;
 import org.apache.fop.area.Trait;
@@ -73,7 +72,6 @@ import org.apache.fop.fonts.Typeface;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.ImageFactory;
 import org.apache.fop.image.XMLImage;
-import org.apache.fop.pdf.PDFAMode;
 import org.apache.fop.render.AbstractPathOrientedRenderer;
 import org.apache.fop.render.Graphics2DAdapter;
 import org.apache.fop.render.RendererContext;
@@ -150,19 +148,6 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
     public Java2DRenderer() {
     }
 
-    /**
-     * @see org.apache.fop.render.AbstractRenderer#configure(
-     *          org.apache.avalon.framework.configuration.Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        super.configure(cfg);
-
-        String s = cfg.getChild(JAVA2D_TRANSPARENT_PAGE_BACKGROUND, true).getValue(null);
-        if (s != null) {
-            this.transparentPageBackground = "true".equalsIgnoreCase(s);
-        }
-    }
-
     /**
      * @see org.apache.fop.render.Renderer#setUserAgent(org.apache.fop.apps.FOUserAgent)
      */
@@ -305,10 +290,10 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
                             + pageHeight + ")");
 
             double scaleX = scaleFactor 
-                * (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION) 
+                * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION) 
                 / userAgent.getTargetPixelUnitToMillimeter();
             double scaleY = scaleFactor
-                * (25.4 / FOUserAgent.DEFAULT_TARGET_RESOLUTION)
+                * (25.4 / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
                 / userAgent.getTargetPixelUnitToMillimeter();
             int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5);
             int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5);
@@ -1023,4 +1008,8 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
         //not necessary in Java2D
     }
 
+    public void setTransparentPageBackground(boolean transparentPageBackground) {
+        this.transparentPageBackground = transparentPageBackground;
+    }
+
 }
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java b/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java
new file mode 100644 (file)
index 0000000..6732a10
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.java2d;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+
+/**
+ * Configurerer for Java 2D renderer
+ */
+public class Java2DRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public Java2DRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the Java 2D renderer.
+     * @param renderer java 2d renderer
+     * @throws FOPException fop exception
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            Java2DRenderer java2dRenderer = (Java2DRenderer)renderer;
+            String value = cfg.getChild(
+                    Java2DRenderer.JAVA2D_TRANSPARENT_PAGE_BACKGROUND, true).getValue(null);
+            if (value != null) {
+                java2dRenderer.setTransparentPageBackground("true".equalsIgnoreCase(value));
+            }
+        }
+    }
+}
index 596dc06d30d03582b262fda1d619686fef591baf..733212e48e3147a84bd94474c4f614cfcf2f4afb 100644 (file)
@@ -53,8 +53,6 @@ import org.w3c.dom.Document;
 import org.apache.xmlgraphics.java2d.GraphicContext;
 
 // FOP
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.fop.apps.FOPException;
@@ -143,31 +141,8 @@ public class PCLRenderer extends PrintRenderer {
     public PCLRenderer() {
     }
 
-    /**
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        super.configure(cfg);
-        String rendering = cfg.getChild("rendering").getValue(null);
-        if ("quality".equalsIgnoreCase(rendering)) {
-            this.qualityBeforeSpeed = true;
-        } else if ("speed".equalsIgnoreCase(rendering)) {
-            this.qualityBeforeSpeed = false;
-        } else if (rendering != null) {
-            throw new ConfigurationException(
-                    "Valid values for 'rendering' are 'quality' and 'speed'. Value found: " 
-                        + rendering);
-        }
-        String textRendering = cfg.getChild("text-rendering").getValue(null);
-        if ("bitmap".equalsIgnoreCase(textRendering)) {
-            this.allTextAsBitmaps = true;
-        } else if ("auto".equalsIgnoreCase(textRendering)) {
-            this.allTextAsBitmaps = false;
-        } else if (textRendering != null) {
-            throw new ConfigurationException(
-                    "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: " 
-                        + textRendering);
-        }
+    public void setQualityBeforeSpeed(boolean qualityBeforeSpeed) {
+        this.qualityBeforeSpeed = qualityBeforeSpeed;
     }
 
     /**
@@ -1499,6 +1474,10 @@ public class PCLRenderer extends PrintRenderer {
             handleIOTrouble(ioe);
         }
     }
+
+    public void setAllTextAsBitmaps(boolean allTextAsBitmaps) {
+        this.allTextAsBitmaps = allTextAsBitmaps;
+    }
     
     
     
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
new file mode 100644 (file)
index 0000000..814b683
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.pcl;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+
+/**
+ * PCL Renderer configurator 
+ */
+public class PCLRendererConfigurator extends PrintRendererConfigurator {
+    
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public PCLRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the TIFF renderer. Get the configuration to be used for
+     * compression
+     * @param renderer PCL renderer
+     * @throws FOPException fop exception
+     * @see org.apache.fop.render.PrintRendererConfigurator#configure(Renderer)
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            PCLRenderer pclRenderer = (PCLRenderer)renderer;
+            String rendering = cfg.getChild("rendering").getValue(null);
+            if ("quality".equalsIgnoreCase(rendering)) {
+                pclRenderer.setQualityBeforeSpeed(true);
+            } else if ("speed".equalsIgnoreCase(rendering)) {
+                pclRenderer.setQualityBeforeSpeed(false);
+            } else if (rendering != null) {
+                throw new FOPException(
+                        "Valid values for 'rendering' are 'quality' and 'speed'. Value found: " 
+                            + rendering);
+            }
+            String textRendering = cfg.getChild("text-rendering").getValue(null);
+            if ("bitmap".equalsIgnoreCase(textRendering)) {
+                pclRenderer.setAllTextAsBitmaps(true);
+            } else if ("auto".equalsIgnoreCase(textRendering)) {
+                pclRenderer.setAllTextAsBitmaps(false);
+            } else if (textRendering != null) {
+                throw new FOPException(
+                        "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: " 
+                            + textRendering);
+            }
+        }
+    }
+}
index aa0bc292b7d6ef908d776584e213cb58f6001238..b7b395341590f65da253e51b91e0ea0b18aa15fb 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the PCL Renderer.\r
@@ -31,14 +32,19 @@ public class PCLRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {\r
         MimeConstants.MIME_PCL,\r
-        MimeConstants.MIME_PCL_ALT};\r
+        MimeConstants.MIME_PCL_ALT\r
+    };\r
     \r
-    \r
-    /**@see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new PCLRenderer();\r
     }\r
 \r
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new PCLRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
@@ -48,5 +54,4 @@ public class PCLRendererMaker extends AbstractRendererMaker {
     public String[] getSupportedMimeTypes() {\r
         return MIMES;\r
     }\r
-\r
 }\r
index 7d584c036ed824a7a8bd120e5559be5ac7c420f7..73c38878efafd0e7fd0608183b6b8f613a7ab1c3 100644 (file)
@@ -41,8 +41,6 @@ import javax.xml.transform.stream.StreamSource;
 import org.w3c.dom.Document;
 
 // Avalon
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.commons.io.IOUtils;
 
 // FOP
@@ -69,7 +67,6 @@ import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.area.inline.SpaceArea;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.ImageFactory;
 import org.apache.fop.image.XMLImage;
@@ -86,7 +83,6 @@ import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFGoTo;
 import org.apache.fop.pdf.PDFICCBasedColorSpace;
 import org.apache.fop.pdf.PDFICCStream;
-import org.apache.fop.pdf.PDFGoTo;
 import org.apache.fop.pdf.PDFInfo;
 import org.apache.fop.pdf.PDFLink;
 import org.apache.fop.pdf.PDFMetadata;
@@ -266,38 +262,6 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
     public PDFRenderer() {
     }
 
-    /**
-     * Configure the PDF renderer.
-     * Get the configuration to be used for pdf stream filters,
-     * fonts etc.
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        //PDF filters
-        this.filterMap = PDFFilterList.buildFilterMapFromConfiguration(cfg);
-
-        //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
-        if (this.fontList == null) {
-            this.fontList = cfgFonts;
-        } else {
-            this.fontList.addAll(cfgFonts);
-        }
-        
-        String s = cfg.getChild(PDF_A_MODE, true).getValue(null);
-        if (s != null) {
-            this.pdfAMode = PDFAMode.valueOf(s);
-        }
-        s = cfg.getChild(PDF_X_MODE, true).getValue(null);
-        if (s != null) {
-            this.pdfXMode = PDFXMode.valueOf(s);
-        }
-        s = cfg.getChild(KEY_OUTPUT_PROFILE, true).getValue(null);
-        if (s != null) {
-            this.outputProfileURI = s;
-        }
-    }
-
     private boolean booleanValueOf(Object obj) {
         if (obj instanceof Boolean) {
             return ((Boolean)obj).booleanValue();
@@ -1891,5 +1855,21 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
     public String getMimeType() {
         return MIME_TYPE;
     }
+    
+    public void setAMode(PDFAMode mode) {
+        this.pdfAMode = mode;
+    }
+
+    public void setXMode(PDFXMode mode) {
+        this.pdfXMode = mode;        
+    }
+
+    public void setOutputProfileURI(String outputProfileURI) {
+        this.outputProfileURI = outputProfileURI;
+    }
+
+    public void setFilterMap(Map filterMap) {
+        this.filterMap = filterMap;
+    }
 }
 
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
new file mode 100644 (file)
index 0000000..5c5894d
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.pdf;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.pdf.PDFXMode;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * PDF renderer configurator 
+ */
+public class PDFRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public PDFRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the PDF renderer.
+     * Get the configuration to be used for pdf stream filters,
+     * fonts etc.
+     * @param renderer pdf renderer
+     * @throws FOPException fop exception
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            PDFRenderer pdfRenderer = (PDFRenderer)renderer;
+            //PDF filters
+            try {
+                Map filterMap = buildFilterMapFromConfiguration(cfg);
+                if (filterMap != null) {
+                    pdfRenderer.setFilterMap(filterMap);
+                }
+            } catch (ConfigurationException e) {
+                LogUtil.handleException(log, e, false);
+            }
+    
+            super.configure(renderer);
+    
+            String s = cfg.getChild(PDFRenderer.PDF_A_MODE, true).getValue(null);
+            if (s != null) {
+                pdfRenderer.setAMode(PDFAMode.valueOf(s));
+            }
+            s = cfg.getChild(PDFRenderer.PDF_X_MODE, true).getValue(null);
+            if (s != null) {
+                pdfRenderer.setXMode(PDFXMode.valueOf(s));
+            }
+            s = cfg.getChild(PDFRenderer.KEY_OUTPUT_PROFILE, true).getValue(null);
+            if (s != null) {
+                pdfRenderer.setOutputProfileURI(s);
+            }
+        }
+    }
+
+    /**
+     * Builds a filter map from an Avalon Configuration object.
+     * @param cfg the Configuration object
+     * @return Map the newly built filter map
+     * @throws ConfigurationException if a filter list is defined twice
+     */
+    public static Map buildFilterMapFromConfiguration(Configuration cfg) 
+                throws ConfigurationException {
+        Map filterMap = new java.util.HashMap();
+        Configuration[] filterLists = cfg.getChildren("filterList");
+        for (int i = 0; i < filterLists.length; i++) {
+            Configuration filters = filterLists[i];
+            String type = filters.getAttribute("type", null);
+            Configuration[] filt = filters.getChildren("value");
+            List filterList = new java.util.ArrayList();
+            for (int j = 0; j < filt.length; j++) {
+                String name = filt[j].getValue();
+                filterList.add(name);
+            }
+            
+            if (type == null) {
+                type = PDFFilterList.DEFAULT_FILTER;
+            }
+    
+            if (!filterList.isEmpty() && log.isDebugEnabled()) {
+                StringBuffer debug = new StringBuffer("Adding PDF filter");
+                if (filterList.size() != 1) {
+                    debug.append("s");
+                }
+                debug.append(" for type ").append(type).append(": ");
+                for (int j = 0; j < filterList.size(); j++) {
+                    if (j != 0) {
+                        debug.append(", ");
+                    }
+                    debug.append(filterList.get(j));
+                }
+                log.debug(debug.toString());
+            }
+            
+            if (filterMap.get(type) != null) {
+                throw new ConfigurationException("A filterList of type '" 
+                    + type + "' has already been defined");
+            }
+            filterMap.put(type, filterList);
+        }
+        return filterMap;                
+    }
+}
index 0f8d8bc1437da133eaed584c25bcb50d1eb05809..00fc1a88f624b5a8d428b21bb353506676933f88 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the PDF Renderer.\r
@@ -31,12 +32,16 @@ public class PDFRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF};\r
     \r
-    \r
-    /**@see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new PDFRenderer();\r
     }\r
 \r
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new PDFRendererConfigurator(userAgent);\r
+    }\r
+    \r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
index 046427682d8a5b432b6ea32c6a694a686d61717d..6ad2cb3d18766a159153e0568e13bf14be9fb264 100644 (file)
@@ -22,7 +22,9 @@ package org.apache.fop.render.print;
 import org.apache.fop.apps.FOUserAgent;\r
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
+import org.apache.fop.render.PrintRendererConfigurator;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the Print Renderer.\r
@@ -31,12 +33,16 @@ public class PrintRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_PRINT};\r
     \r
-    \r
-    /**@see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new PrintRenderer();\r
     }\r
 \r
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new PrintRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return false;\r
index 47f7fb0b8a39751f4b52fc4129566be0ff256a24..5cda145b98117620210cd5e6854e518c09831031 100644 (file)
@@ -159,7 +159,7 @@ public class NativeTextHandler implements TextHandler {
         }
         int fontSize = 1000 * f.getSize();
         String style = f.isItalic() ? "italic" : "normal";
-        int weight = f.isBold() ? Font.BOLD : Font.NORMAL;
+        int weight = f.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
                 
         FontTriplet triplet = fontInfo.findAdjustWeight(fontFamily, style, weight);
         if (triplet == null) {
index 68c6cc86cc3a7d5ef4c7ace47c6ce79a3e8b8277..ad5b0b3ce5baa1f929bcfb81b6370561922b2cae 100644 (file)
@@ -35,8 +35,6 @@ import java.util.Map;
 import javax.xml.transform.Source;
 
 // FOP
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -61,7 +59,6 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.LazyFont;
 import org.apache.fop.fonts.Typeface;
 import org.apache.fop.image.EPSImage;
@@ -145,24 +142,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda
     /** This is a map of PSResource instances of all forms (key: uri) */
     private Map formResources;
     
-    /**
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        super.configure(cfg);
-        this.autoRotateLandscape = cfg.getChild(AUTO_ROTATE_LANDSCAPE).getValueAsBoolean(false);
-        this.languageLevel = cfg.getChild(LANGUAGE_LEVEL).getValueAsInteger(this.languageLevel);
-        this.twoPassGeneration = cfg.getChild(OPTIMIZE_RESOURCES).getValueAsBoolean(false);
-
-        //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
-        if (this.fontList == null) {
-            this.fontList = cfgFonts;
-        } else {
-            this.fontList.addAll(cfgFonts);
-        }
-    }
-
     /**
      * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
      */
diff --git a/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java
new file mode 100644 (file)
index 0000000..c7b5a02
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.ps;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+
+/**
+ * Postscript renderer config 
+ */
+public class PSRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public PSRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the PS renderer.
+     * @param renderer postscript renderer
+     * @throws FOPException fop exception
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            super.configure(renderer);
+
+            PSRenderer psRenderer = (PSRenderer)renderer;
+            psRenderer.setAutoRotateLandscape(
+                cfg.getChild("auto-rotate-landscape").getValueAsBoolean(false));
+        }
+    }
+}
index 45f7663aa6428a0fc134e2b1b7fa5c6d261ca129..0db4281d0d7d3d2f5a45bd140132a498e4a5ad1d 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the PostScript Renderer.\r
@@ -31,12 +32,16 @@ public class PSRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_POSTSCRIPT};\r
     \r
-    \r
-    /** @see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new PSRenderer();\r
     }\r
 \r
+    /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new PSRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
@@ -46,5 +51,4 @@ public class PSRendererMaker extends AbstractRendererMaker {
     public String[] getSupportedMimeTypes() {\r
         return MIMES;\r
     }\r
-\r
 }\r
index 78efd56b9b588eb4fcbeff23f8ce370444db71e1..f4796fd2bf2435ed6361117ab44d1055ab55e047 100644 (file)
@@ -367,8 +367,8 @@ public class PSTextPainter implements TextPainter {
     private int getWeight(AttributedCharacterIterator aci) {
         Float taWeight = (Float)aci.getAttribute(TextAttribute.WEIGHT);
         return ((taWeight != null) &&  (taWeight.floatValue() > 1.0)) 
-                       ? Font.BOLD
-                       : Font.NORMAL;
+                       ? Font.WEIGHT_BOLD
+                       : Font.WEIGHT_NORMAL;
     }
 
     private Font makeFont(AttributedCharacterIterator aci) {
@@ -402,7 +402,7 @@ public class PSTextPainter implements TextPainter {
                 }
             }
         }
-        FontTriplet triplet = fontInfo.fontLookup("any", style, Font.NORMAL);
+        FontTriplet triplet = fontInfo.fontLookup("any", style, Font.WEIGHT_NORMAL);
         int fsize = (int)(fontSize.floatValue() * 1000);
         return fontInfo.getFontInstance(triplet, fsize);
     }
@@ -411,7 +411,7 @@ public class PSTextPainter implements TextPainter {
         final String style = getStyle(aci);
         final int weight = getWeight(aci);
         int fStyle = java.awt.Font.PLAIN;
-        if (weight == Font.BOLD) {
+        if (weight == Font.WEIGHT_BOLD) {
             fStyle |= java.awt.Font.BOLD;
         }
         if ("italic".equals(style)) {
index 85d3dd797863287528c4ec09ca06069d0a9b6bf6..cec1dbc4bd6b99594212249e8794c1cd189ddecf 100644 (file)
@@ -27,8 +27,6 @@ import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.area.Area;
 import org.apache.fop.area.CTM;
@@ -115,12 +113,6 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
     public String getMimeType() {
         return "text/plain";
     }
-
-    /** @see org.apache.fop.render.AbstractRenderer */
-    public void configure(Configuration conf) throws ConfigurationException {
-        super.configure(conf);
-        this.encoding = conf.getChild("encoding", true).getValue(null);
-    }
     
     /**
      * Sets the encoding of the target file.
diff --git a/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java b/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java
new file mode 100644 (file)
index 0000000..ab655c9
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.render.txt;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.Renderer;
+
+/**
+ * TXT Renderer configurator 
+ */
+public class TXTRendererConfigurator extends PrintRendererConfigurator {
+
+    /**
+     * Default constructor
+     * @param userAgent user agent
+     */
+    public TXTRendererConfigurator(FOUserAgent userAgent) {
+        super(userAgent);
+    }
+
+    /**
+     * Configure the PS renderer.
+     * @param renderer TXT renderer
+     * @throws FOPException fop exception
+     */
+    public void configure(Renderer renderer) throws FOPException {
+        Configuration cfg = super.getRendererConfig(renderer);
+        if (cfg != null) {
+            TXTRenderer txtRenderer = (TXTRenderer)renderer;
+            txtRenderer.setEncoding(cfg.getChild("encoding", true).getValue(null));
+        }
+    }
+}
index 5c1b812b6f0a7a09d6cdf77b21a6fbd91d15ee8a..8a92ed11da980ab5843f25e0c9c57fbb93cdc86b 100644 (file)
@@ -23,6 +23,7 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the Plain Text Renderer.\r
@@ -31,12 +32,16 @@ public class TXTRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_PLAIN_TEXT};\r
     \r
-    \r
-    /**@see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new TXTRenderer();\r
     }\r
 \r
+    /**@see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new TXTRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
@@ -46,5 +51,4 @@ public class TXTRendererMaker extends AbstractRendererMaker {
     public String[] getSupportedMimeTypes() {\r
         return MIMES;\r
     }\r
-\r
 }\r
index cccdb6d716eb0e856321df9a9c7f204c642c67ed..b95ea7e18c9a081904681cb543b293d306e127c7 100644 (file)
@@ -41,8 +41,6 @@ import org.xml.sax.SAXException;
 import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.AttributesImpl;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.fop.util.QName;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
@@ -83,7 +81,6 @@ import org.apache.fop.area.inline.WordArea;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.extensions.ExtensionAttachment;
 import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.render.PrintRenderer;
 import org.apache.fop.render.Renderer;
@@ -139,22 +136,6 @@ public class XMLRenderer extends PrintRenderer {
         context = new RendererContext(this, XML_MIME_TYPE);
     }
 
-    /**
-     * Configure the XML renderer.
-     * Get the configuration to be used for fonts etc.
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        super.configure(cfg);
-        //Font configuration
-        List cfgFonts = FontSetup.buildFontListFromConfiguration(cfg, this);
-        if (this.fontList == null) {
-            this.fontList = cfgFonts;
-        } else {
-            this.fontList.addAll(cfgFonts);
-        }
-    }
-
     /**
      * @see org.apache.fop.render.Renderer#setUserAgent(FOUserAgent)
      */
index 1be56f39ac2f177fb04f6e6793e13560c5d42add..582cfb9bef5c1a4aea4cb335921d16e20636d8d9 100644 (file)
@@ -22,7 +22,9 @@ package org.apache.fop.render.xml;
 import org.apache.fop.apps.FOUserAgent;\r
 import org.apache.fop.apps.MimeConstants;\r
 import org.apache.fop.render.AbstractRendererMaker;\r
+import org.apache.fop.render.PrintRendererConfigurator;\r
 import org.apache.fop.render.Renderer;\r
+import org.apache.fop.render.RendererConfigurator;\r
 \r
 /**\r
  * RendererMaker for the Area Tree XML Renderer.\r
@@ -31,12 +33,16 @@ public class XMLRendererMaker extends AbstractRendererMaker {
 \r
     private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_AREA_TREE};\r
     \r
-    \r
-    /**@see org.apache.fop.render.AbstractRendererMaker */\r
-    public Renderer makeRenderer(FOUserAgent ua) {\r
+    /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */\r
+    public Renderer makeRenderer(FOUserAgent userAgent) {\r
         return new XMLRenderer();\r
     }\r
 \r
+    /**@see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */\r
+    public RendererConfigurator getConfigurator(FOUserAgent userAgent) {\r
+        return new PrintRendererConfigurator(userAgent);\r
+    }\r
+\r
     /** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */\r
     public boolean needsOutputStream() {\r
         return true;\r
index 7f96fb060cfd7b1f183858ab72154210d2d8eeaa..494d476365629bbf87981561d8c3d8cafff70e14 100644 (file)
@@ -19,8 +19,6 @@
 
 package org.apache.fop.svg;
 
-import java.util.List;
-
 import org.apache.fop.pdf.PDFPage;
 
 /**
@@ -30,24 +28,10 @@ import org.apache.fop.pdf.PDFPage;
 public class PDFContext {
 
     private PDFPage currentPage;
-    private List fontList;
 
     /** number of pages generated */
     private int pagecount;
     
-    /**
-     * Sets the font list as creates by the FontSetup class.
-     * @param list the font list
-     */
-    public void setFontList(List list) {
-        this.fontList = list;
-    }
-
-    /** @return the font list */
-    public List getFontList() {
-        return this.fontList;
-    }
-
     /** @return true if a page is set up for painting. */
     public boolean isPagePending() {
         return this.currentPage != null;
index 0e699dec7799a339112e2836e09d633efe5a8e90..9c72ade1a9e66a14d17eef34e79d41df36857872 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.apache.fop.svg;
 
+import org.apache.fop.Version;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFPage;
@@ -28,13 +29,8 @@ import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFResources;
 import org.apache.fop.pdf.PDFColor;
 import org.apache.fop.pdf.PDFAnnotList;
-import org.apache.fop.fonts.FontSetup;
 import org.apache.fop.fonts.FontInfo;
-import org.apache.avalon.framework.CascadingRuntimeException;
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.configuration.Configurable;
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.fop.fonts.FontSetup;
 
 import java.awt.Graphics;
 import java.awt.Font;
@@ -56,8 +52,7 @@ import java.io.StringWriter;
  * @version $Id$
  * @see org.apache.fop.svg.PDFGraphics2D
  */
-public class PDFDocumentGraphics2D extends PDFGraphics2D
-            implements Configurable, Initializable {
+public class PDFDocumentGraphics2D extends PDFGraphics2D {
 
     private PDFContext pdfContext;
 
@@ -89,9 +84,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
      */
     protected AffineTransform initialTransform;
 
-    //Avalon component
-    private Configuration cfg;
-
     /**
      * Create a new PDFDocumentGraphics2D.
      * This is used to create a new pdf document, the height,
@@ -106,19 +98,9 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
     public PDFDocumentGraphics2D(boolean textAsShapes) {
         super(textAsShapes);
 
+        this.pdfDoc = new PDFDocument("Apache FOP Version " + Version.getVersion() 
+                + ": PDFDocumentGraphics2D");
         this.pdfContext = new PDFContext();
-        if (!textAsShapes) {
-            fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, null, null);
-            //FontState fontState = new FontState("Helvetica", "normal",
-            //                          FontInfo.NORMAL, 12, 0);
-        }
-        try {
-            initialize();
-        } catch (Exception e) {
-            //Should never happen
-            throw new CascadingRuntimeException("Internal error", e);
-        }
     }
 
     /**
@@ -153,33 +135,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         this(false);
     }
 
-    /**
-     * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-        this.cfg = cfg;
-        this.pdfContext.setFontList(FontSetup.buildFontListFromConfiguration(cfg));
-    }
-
-    /**
-     * @see org.apache.avalon.framework.activity.Initializable#initialize()
-     */
-    public void initialize() throws Exception {
-        if (this.fontInfo == null || this.cfg != null) {
-            fontInfo = new FontInfo();
-            FontSetup.setup(fontInfo, this.pdfContext.getFontList(), null);
-            //FontState fontState = new FontState("Helvetica", "normal",
-            //                          FontInfo.NORMAL, 12, 0);
-        }
-
-        this.pdfDoc = new PDFDocument("Apache FOP: SVG to PDF Transcoder");
-
-        if (this.cfg != null) {
-            this.pdfDoc.setFilterMap(
-                PDFFilterList.buildFilterMapFromConfiguration(cfg));
-        }
-    }
-
     /**
      * Setup the document.
      * @param stream the output stream to write the document
@@ -196,6 +151,18 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         setOutputStream(stream);
     }
 
+    /**
+     * Setup a default FontInfo instance if none has been setup before. 
+     */
+    public void setupDefaultFontInfo() {
+        if (fontInfo == null) {
+            //Default minimal fonts
+            FontInfo fontInfo = new FontInfo();
+            FontSetup.setup(fontInfo, null, null);
+            setFontInfo(fontInfo);
+        }
+    }
+    
     /**
      * Set the device resolution for rendering.  Will take effect at the
      * start of the next page.
@@ -212,6 +179,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         return deviceDPI;
     }
 
+    /**
+     * Sets the font info for this PDF document.
+     * @param fontInfo the font info object with all the fonts
+     */
+    public void setFontInfo(FontInfo fontInfo) {
+        this.fontInfo = fontInfo;
+    }
+    
     /**
      * Get the font info for this pdf document.
      * @return the font information
@@ -228,6 +203,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         return this.pdfDoc;
     }
 
+    /**
+     * Return the PDFContext for this instance.
+     * @return the PDFContext
+     */
+    public PDFContext getPDFContext() {
+        return this.pdfContext;
+    }
+    
     /**
      * Set the dimensions of the svg document that will be drawn.
      * This is useful if the dimensions of the svg document are different
@@ -295,6 +278,10 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
         if (pdfContext.isPagePending()) {
             return;
         }
+        //Setup default font info if no more font configuration has been done by the user.
+        if (!this.textAsShapes && getFontInfo() == null) {
+            setupDefaultFontInfo();
+        }
         try {
             startPage();
         } catch (IOException ioe) {
@@ -389,7 +376,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
     public PDFDocumentGraphics2D(PDFDocumentGraphics2D g) {
         super(g);
         this.pdfContext = g.pdfContext;
-        this.cfg = g.cfg;
         this.width = g.width;
         this.height = g.height;
         this.svgWidth = g.svgWidth;
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
new file mode 100644 (file)
index 0000000..fe4d50a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.svg;
+
+import java.util.List;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontResolver;
+import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.pdf.PDFRendererConfigurator;
+
+/**
+ * Configurator class for PDFDocumentGraphics2D.
+ */
+public class PDFDocumentGraphics2DConfigurator {
+
+    /**
+     * Configures a PDFDocumentGraphics2D instance using an Avalon Configuration object.
+     * @param graphics the PDFDocumentGraphics2D instance
+     * @param cfg the configuration
+     * @throws ConfigurationException if an error occurs while configuring the object
+     */
+    public void configure(PDFDocumentGraphics2D graphics, Configuration cfg) 
+            throws ConfigurationException {
+        PDFDocument pdfDoc = graphics.getPDFDocument();
+        
+        //Filter map
+        pdfDoc.setFilterMap(
+                PDFRendererConfigurator.buildFilterMapFromConfiguration(cfg));
+        
+        //Fonts
+        try {
+            FontResolver fontResolver = FontSetup.createMinimalFontResolver();
+            List fontList = PrintRendererConfigurator.buildFontListFromConfiguration(
+                    cfg, null, fontResolver, false, null);
+            FontInfo fontInfo = new FontInfo();
+            FontSetup.setup(fontInfo, fontList, fontResolver);
+            graphics.setFontInfo(fontInfo);
+        } catch (FOPException e) {
+            throw new ConfigurationException("Error while setting up fonts", e);
+        }
+    }
+    
+}
index 254a93cbafc4d706d9b2f8594d9230697b656fad..3902b30fd5cb1daed2bb5ba62bcb906e3e00f398 100644 (file)
@@ -1429,7 +1429,7 @@ public class PDFGraphics2D extends AbstractGraphics2D {
             }
             float siz = gFont.getSize2D();
             String style = gFont.isItalic() ? "italic" : "normal";
-            int weight = gFont.isBold() ? Font.BOLD : Font.NORMAL;
+            int weight = gFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
             FontTriplet triplet = fontInfo.fontLookup(n, style, weight);
             fontState = fontInfo.getFontInstance(triplet, (int)(siz * 1000 + 0.5));
         } else {
index cf9b7b7bd8d4195593b5b66bc672830b1fbbab54..100711eb9e339fc146630f471f2f42c504d3d116 100644 (file)
@@ -22,7 +22,6 @@ package org.apache.fop.svg;
 import org.apache.batik.gvt.TextNode;
 import org.apache.batik.bridge.SVGTextElementBridge;
 import org.apache.batik.bridge.BridgeContext;
-import org.apache.batik.bridge.TextUtilities;
 import org.apache.batik.gvt.GraphicsNode;
 
 import org.apache.fop.fonts.FontInfo;
@@ -82,12 +81,16 @@ public class PDFTextElementBridge extends SVGTextElementBridge {
      *         easily rendered using normal drawString on the PDFGraphics2D
      */
     private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) {
+        /* I cannot find any reference that 36pt is the maximum font size in PDF. Tests show
+         * no such restriction (jeremias, 28.5.2007)
+         * 
         // Font size, in user space units.
         float fs = TextUtilities.convertFontSize(element).floatValue();
         // PDF cannot display fonts over 36pt
         if (fs > 36) {
             return false;
         }
+        */
 
         Element nodeElement;
         for (Node n = element.getFirstChild();
index eddd89d099b7b25de09e3ccccc28ee0fe1febf53..f05d5ae4fe42f78a7735a95ad750dee3a402be25 100644 (file)
@@ -160,8 +160,8 @@ public class PDFTextPainter implements TextPainter {
         String style = ((posture != null) && (posture.floatValue() > 0.0))
                        ? "italic" : "normal";
         int weight = ((taWeight != null)
-                       &&  (taWeight.floatValue() > 1.0)) ? Font.BOLD
-                       : Font.NORMAL;
+                       &&  (taWeight.floatValue() > 1.0)) ? Font.WEIGHT_BOLD
+                       : Font.WEIGHT_NORMAL;
 
         Font fontState = null;
         FontInfo fi = fontInfo;
@@ -187,7 +187,7 @@ public class PDFTextPainter implements TextPainter {
             }
         }
         if (!found) {
-            FontTriplet triplet = fontInfo.fontLookup("any", style, Font.NORMAL);
+            FontTriplet triplet = fontInfo.fontLookup("any", style, Font.WEIGHT_NORMAL);
             int fsize = (int)(size.floatValue() * 1000);
             fontState = fontInfo.getFontInstance(triplet, fsize);
         } else {
@@ -196,7 +196,7 @@ public class PDFTextPainter implements TextPainter {
             }
         }
         int fStyle = java.awt.Font.PLAIN;
-        if (weight == Font.BOLD) {
+        if (weight == Font.WEIGHT_BOLD) {
             if (style.equals("italic")) {
                 fStyle = java.awt.Font.BOLD | java.awt.Font.ITALIC;
             } else {
index a90765a31e214b16f4db8188af55f4145678f575..f6a986d0c6f57b79208b54434ad8f78b9397118f 100644 (file)
@@ -25,7 +25,6 @@ import java.io.IOException;
 import org.apache.avalon.framework.configuration.Configurable;
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.UnitProcessor;
 import org.apache.batik.bridge.UserAgent;
@@ -35,6 +34,9 @@ import org.apache.batik.transcoder.TranscoderOutput;
 import org.apache.batik.transcoder.TranscodingHints;
 import org.apache.batik.transcoder.image.ImageTranscoder;
 import org.apache.batik.transcoder.keys.FloatKey;
+import org.apache.fop.Version;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontSetup;
 import org.w3c.dom.Document;
 import org.w3c.dom.svg.SVGLength;
 
@@ -120,12 +122,16 @@ public class PDFTranscoder extends AbstractFOPTranscoder
         throws TranscoderException {
 
         graphics = new PDFDocumentGraphics2D();
+        graphics.getPDFDocument().getInfo().setProducer("Apache FOP Version " 
+                + Version.getVersion() 
+                + ": PDF Transcoder for Batik");
         
         try {
             if (this.cfg != null) {
-                ContainerUtil.configure(graphics, this.cfg);
+                PDFDocumentGraphics2DConfigurator configurator
+                        = new PDFDocumentGraphics2DConfigurator();
+                configurator.configure(graphics, this.cfg);
             }
-            ContainerUtil.initialize(graphics);
         } catch (Exception e) {
             throw new TranscoderException(
                 "Error while setting up PDFDocumentGraphics2D", e);
@@ -133,7 +139,9 @@ public class PDFTranscoder extends AbstractFOPTranscoder
 
         super.transcode(document, uri, output);
 
-        getLogger().trace("document size: " + width + " x " + height);
+        if (getLogger().isTraceEnabled()) {
+            getLogger().trace("document size: " + width + " x " + height);
+        }
         
         // prepare the image to be painted
         UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, 
@@ -144,7 +152,9 @@ public class PDFTranscoder extends AbstractFOPTranscoder
         float heightInPt = UnitProcessor.userSpaceToSVG(height, SVGLength.SVG_LENGTHTYPE_PT, 
                 UnitProcessor.HORIZONTAL_LENGTH, uctx);
         int h = (int)(heightInPt + 0.5);
-        getLogger().trace("document size: " + w + "pt x " + h + "pt");
+        if (getLogger().isTraceEnabled()) {
+            getLogger().trace("document size: " + w + "pt x " + h + "pt");
+        }
 
         // prepare the image to be painted
         //int w = (int)(width + 0.5);
diff --git a/src/java/org/apache/fop/util/LogUtil.java b/src/java/org/apache/fop/util/LogUtil.java
new file mode 100644 (file)
index 0000000..60eafb5
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.fop.apps.FOPException;
+
+/**
+ * Convenience Logging utility methods used in FOP 
+ */
+public class LogUtil {
+
+    /**
+     * Convenience method that handles any error appropriately
+     * @param log log
+     * @param errorStr error string
+     * @param strict validate strictly
+     * @throws FOPException fop exception
+     */
+    public static void handleError(Log log, String errorStr, boolean strict) throws FOPException {
+        handleException(log, new FOPException(errorStr), strict);
+    }
+
+    /**
+     * Convenience method that handles any error appropriately
+     * @param log log
+     * @param e exception
+     * @param strict validate strictly
+     * @throws FOPException fop exception
+     */
+    public static void handleException(Log log, Exception e, boolean strict) throws FOPException {
+        if (strict) {
+            if (e instanceof FOPException) {
+                throw (FOPException)e;
+            }
+            throw new FOPException(e);
+        }
+        log.error(e.getMessage());
+    }
+}
index 7a85afb2d8d0429d2ed2b6591d46b3867cc64d64..8b6f66b6c0f206829e9e47e06fd6fb82f7ba89ed 100644 (file)
@@ -26,8 +26,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Writer;
 
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.batik.dom.GenericDOMImplementation;
 import org.apache.batik.svggen.SVGGeneratorContext;
 import org.apache.batik.svggen.SVGGraphics2D;
@@ -78,13 +76,6 @@ public class SVGRenderer extends Java2DRenderer {
     public SVGRenderer() {
     }
 
-    /**
-     * @see org.apache.fop.render.AbstractRenderer#configure(
-     *          org.apache.avalon.framework.configuration.Configuration)
-     */
-    public void configure(Configuration cfg) throws ConfigurationException {
-    }
-
     /** @see org.apache.fop.render.Renderer#startRenderer(java.io.OutputStream) */
     public void startRenderer(OutputStream outputStream) throws IOException {
         this.firstOutputStream = outputStream;
index 8e4e25a0c1f2aee303b9e7e7b087ab3e67076cd7..5d939e2e3e7943a095d7e43f7e52abc5947272be 100644 (file)
@@ -28,6 +28,9 @@
 
   <changes>
     <release version="FOP Trunk">
+      <action context="Code" dev="JM" type="add" fixes-bug="41831" due-to="Adrian Cumiskey">
+        Add support for font auto-detection (easier font configuration).
+      </action>
       <action context="Code" dev="JM" type="update" fixes-bug="42406" due-to="Hussein Shafie">
         Use source resolution setting for bitmap images which don't provide their own
         resolution.
diff --git a/test/config/test_embedurl_bad.xconf b/test/config/test_embedurl_bad.xconf
deleted file mode 100644 (file)
index 3636454..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-               <!-- this font has an embed-url that does not exist on filesystem -->
-               <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/doesnotexist.ttf">
-          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
diff --git a/test/config/test_embedurl_malformed.xconf b/test/config/test_embedurl_malformed.xconf
deleted file mode 100644 (file)
index b11d086..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-               <!-- this font has a malformed embed-url -->
-               <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="badprotocol:test/resources/fonts/glb12.ttf">
-          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
diff --git a/test/config/test_font_attributes_missing.xconf b/test/config/test_font_attributes_missing.xconf
new file mode 100644 (file)
index 0000000..4265e82
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+               <!-- this font is without a metrics-url -->
+               <font>
+          <font-triplet name="Gladiator" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_font_embedurl_bad.xconf b/test/config/test_font_embedurl_bad.xconf
new file mode 100644 (file)
index 0000000..86bf6bc
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+  
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+               <!-- this font has an embed-url that does not exist on filesystem -->
+               <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="test/resources/fonts/doesnotexist.ttf">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_font_embedurl_malformed.xconf b/test/config/test_font_embedurl_malformed.xconf
new file mode 100644 (file)
index 0000000..ee9f7be
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+  
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+               <!-- this font has a malformed embed-url -->
+               <font metrics-url="test/resources/fonts/glb12.ttf.xml" embed-url="badprotocol:test/resources/fonts/glb12.ttf">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_font_metricsurl_bad.xconf b/test/config/test_font_metricsurl_bad.xconf
new file mode 100644 (file)
index 0000000..2f02bdc
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+  
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+               <!-- this font has a metrics-url that does not exist on filesystem -->
+        <font metrics-url="test/resources/fonts/doesnotexist.ttf.ansi.xml">
+          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_font_metricsurl_malformed.xconf b/test/config/test_font_metricsurl_malformed.xconf
new file mode 100644 (file)
index 0000000..33fcfaa
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+  
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+               <!-- this font has a malformed metrics-url -->
+        <font metrics-url="badprotocol:test/resources/fonts/glb12.ttf.xml">
+          <font-triplet name="Gladiator" style="normal" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_font_tripletattribute_missing.xconf b/test/config/test_font_tripletattribute_missing.xconf
new file mode 100644 (file)
index 0000000..0097179
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+        <font metrics-url="test/resources/fonts/glb12.ttf.xml">
+                 <!-- this font-triplet has a missing style attribute -->           
+          <font-triplet name="Gladiator" weight="normal"/>
+        </font>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_fontattributes_missing.xconf b/test/config/test_fontattributes_missing.xconf
deleted file mode 100644 (file)
index f186d80..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-               <!-- this font is without a metrics-url -->
-               <font>
-          <font-triplet name="Gladiator" style="normal" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
index 850f343bb1c4a2383e83d5a475bed09030f36f4d..2aa6ed87959d7876bc83b0b3848293cf3838a306 100644 (file)
@@ -3,6 +3,9 @@
   <!-- Strict configuration On -->
   <strict-configuration>true</strict-configuration>
 
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+
   <!-- Base URL for resolving relative URLs -->
   <base>./</base>
 
diff --git a/test/config/test_fonts_autodetect.xconf b/test/config/test_fonts_autodetect.xconf
new file mode 100644 (file)
index 0000000..0bcbb10
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+       <auto-detect/>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_fonts_directory_bad.xconf b/test/config/test_fonts_directory_bad.xconf
new file mode 100644 (file)
index 0000000..f5c7fe4
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+       <directory>doesnotexist</directory>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_fonts_directory_recursive.xconf b/test/config/test_fonts_directory_recursive.xconf
new file mode 100644 (file)
index 0000000..60a42b9
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<fop version="1.0">
+  <!-- Strict configuration On -->
+  <strict-configuration>true</strict-configuration>
+
+  <!-- Switch off font caching for the purposes of the unit test -->
+  <use-cache>false</use-cache>  
+
+  <!-- Base URL for resolving relative URLs -->
+  <base>./</base>
+
+  <!-- Font Base URL for resolving relative font URLs -->
+  <font-base>./</font-base>
+  
+  <renderers>
+    <renderer mime="application/pdf">
+      <fonts>
+       <directory recursive="true">test/resources/fonts</directory>
+      </fonts>
+    </renderer>
+  </renderers>
+</fop>
diff --git a/test/config/test_fonttripletattribute_missing.xconf b/test/config/test_fonttripletattribute_missing.xconf
deleted file mode 100644 (file)
index 4e13874..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-        <font metrics-url="test/resources/fonts/glb12.ttf.xml">
-                 <!-- this font-triplet has a missing style attribute -->           
-          <font-triplet name="Gladiator" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
diff --git a/test/config/test_metricsurl_bad.xconf b/test/config/test_metricsurl_bad.xconf
deleted file mode 100644 (file)
index a792834..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-               <!-- this font has a metrics-url that does not exist on filesystem -->
-        <font metrics-url="test/resources/fonts/doesnotexist.ttf.ansi.xml">
-          <font-triplet name="Gladiator-Ansi" style="normal" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
diff --git a/test/config/test_metricsurl_malformed.xconf b/test/config/test_metricsurl_malformed.xconf
deleted file mode 100644 (file)
index 7dc6dac..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<fop version="1.0">
-  <!-- Strict configuration On -->
-  <strict-configuration>true</strict-configuration>
-
-  <!-- Base URL for resolving relative URLs -->
-  <base>./</base>
-
-  <!-- Font Base URL for resolving relative font URLs -->
-  <font-base>./</font-base>
-  
-  <renderers>
-    <renderer mime="application/pdf">
-      <fonts>
-               <!-- this font has a malformed metrics-url -->
-        <font metrics-url="badprotocol:test/resources/fonts/glb12.ttf.xml">
-          <font-triplet name="Gladiator" style="normal" weight="normal"/>
-        </font>
-      </fonts>
-    </renderer>
-  </renderers>
-</fop>
diff --git a/test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseConstructiveUserConfigTestCase.java
new file mode 100644 (file)
index 0000000..cd1c26f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+public abstract class BaseConstructiveUserConfigTestCase extends BaseUserConfigTestCase {
+
+    /**
+     * @see junit.framework.TestCase#TestCase(String)
+     */
+    public BaseConstructiveUserConfigTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * Test using a standard FOP font
+     * @throws Exception checkstyle wants a comment here, even a silly one
+     */
+    public void testUserConfig() throws Exception {
+        try {
+            initConfig();
+            convertFO();
+        } catch (Exception e) {
+            // this should *not* happen!
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+}
diff --git a/test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java b/test/java/org/apache/fop/config/BaseDestructiveUserConfigTestCase.java
new file mode 100644 (file)
index 0000000..c02f99c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+import org.apache.fop.apps.FOPException;
+
+public abstract class BaseDestructiveUserConfigTestCase extends BaseUserConfigTestCase {
+
+    /**
+     * @see junit.framework.TestCase#TestCase(String)
+     */
+    public BaseDestructiveUserConfigTestCase(String name) {
+        super(name);
+    }
+
+    public void testUserConfig() throws Exception {
+        try {
+            initConfig();
+            convertFO();
+            fail( getName() + ": Expected Configuration Exception" );
+        } catch (FOPException e) {
+            // this *should* happen!
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail( getName() + ": Expected FOPException but got: " + e.getMessage() );
+        }
+    }
+}
index 3a97f4303f497e00d11e69e8509dddedcf280684..ae862664c0df73fef08c9af55915b5d699cae257 100644 (file)
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-/* $Id$ */
+/* $Id$ */
 
 package org.apache.fop.config;
 
@@ -28,7 +28,6 @@ import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.render.pdf.BasePDFTestCase;
 import org.xml.sax.SAXException;
@@ -39,7 +38,7 @@ import org.xml.sax.SAXException;
  */
 public abstract class BaseUserConfigTestCase extends BasePDFTestCase {
 
-    protected static DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
+    protected DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
 
     /** logging instance */
     protected Log log = LogFactory.getLog(BaseUserConfigTestCase.class);
@@ -59,28 +58,19 @@ public abstract class BaseUserConfigTestCase extends BasePDFTestCase {
         // do nothing
     }
 
-    /**
-     * Test using a standard FOP font
-     * @throws Exception checkstyle wants a comment here, even a silly one
-     */
-    public void testUserConfig() throws Exception {
-        try {
-            fopFactory.setUserConfig(getUserConfig());        
-            final File baseDir = getBaseDir();
-            final String fontFOFilePath = getFontFOFilePath();
-            File foFile = new File(baseDir, fontFOFilePath);
-            final boolean dumpOutput = false;
-            FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
-            convertFO(foFile, foUserAgent, dumpOutput);
-            fail( getName() + ": Expected Configuration Exception" );
-        } catch (FOPException e) {
-            // this *should* happen!
-        } catch (Exception e) {
-            fail( getName() + ": Expected FOPException but got: " + e.getMessage() );
-        }
+    protected void initConfig() throws Exception {
+        fopFactory.setUserConfig(getUserConfig());                
     }
 
-
+    protected void convertFO() throws Exception {
+        final File baseDir = getBaseDir();
+        final String fontFOFilePath = getFontFOFilePath();
+        File foFile = new File(baseDir, fontFOFilePath);
+        final boolean dumpOutput = false;
+        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
+        convertFO(foFile, foUserAgent, dumpOutput);
+    }
+    
     /**
      * get test FOP config File
      * @return fo test filepath
@@ -96,11 +86,31 @@ public abstract class BaseUserConfigTestCase extends BasePDFTestCase {
      * @throws SAXException 
      * @throws ConfigurationException 
      */
-    protected Configuration getUserConfig(String configString)
-            throws ConfigurationException, SAXException, IOException {
+    protected Configuration getUserConfig(String configString) throws ConfigurationException, SAXException, IOException {
         return cfgBuilder.build(new ByteArrayInputStream(configString.getBytes()));
     }
 
+    /** get base config directory */
+    protected String getBaseConfigDir() {
+        return "test/config";
+    }
+
+    /**
+     * @return user config File
+     */
+    abstract protected String getUserConfigFilename();
+
+    /*
+     * @see junit.framework.TestCase#getName()
+     */
+    public String getName() {
+        return getUserConfigFilename();
+    }
+
+    protected File getUserConfigFile() {
+        return new File(getBaseConfigDir() + File.separator + getUserConfigFilename());
+    }
+
     /**
      * get test FOP Configuration
      * @return fo test filepath
@@ -108,18 +118,7 @@ public abstract class BaseUserConfigTestCase extends BasePDFTestCase {
      * @throws SAXException 
      * @throws ConfigurationException 
      */
-    protected Configuration getUserConfig()
-            throws ConfigurationException, SAXException, IOException {
+    protected Configuration getUserConfig() throws ConfigurationException, SAXException, IOException {
         return cfgBuilder.buildFromFile(getUserConfigFile());
-    }
-    
-    /** get base config directory */
-    protected String getBaseConfigDir() {
-        return "test/config";
-    }
-    
-    /**
-     * @return user config File
-     */
-    protected abstract File getUserConfigFile();
+    }        
 }
diff --git a/test/java/org/apache/fop/config/EmbedUrlBadTestCase.java b/test/java/org/apache/fop/config/EmbedUrlBadTestCase.java
deleted file mode 100644 (file)
index 2934004..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.config;
-
-import java.io.File;
-
-// 
-/**
- * this font has an embed-url that does not exist on filesystem.
- */
-public class EmbedUrlBadTestCase extends BaseUserConfigTestCase {
-
-    public EmbedUrlBadTestCase(String name) {
-        super(name);
-    }
-
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_embedurl_bad.xconf");
-    }
-    
-    public String getName() {
-        return "test_embedurl_bad.xconf";
-    }
-}
diff --git a/test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java b/test/java/org/apache/fop/config/EmbedUrlMalformedTestCase.java
deleted file mode 100644 (file)
index ab622fd..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.config;
-
-import java.io.File;
-
-// this font has a malformed embed-url
-public class EmbedUrlMalformedTestCase extends BaseUserConfigTestCase {
-
-    public EmbedUrlMalformedTestCase(String name) {
-        super(name);
-    }
-
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_embedurl_malformed.xconf");
-    }
-    
-    public String getName() {
-        return "test_embedurl_malformed.xconf";
-    }
-}
index fc5b10a601f948556155249628e617c628b933e5..a6333009df6a97620b8a53b9f26931aaf3cc3a54 100644 (file)
 
 package org.apache.fop.config;
 
-import java.io.File;
-
-// this font is without a metrics-url or an embed-url
-public class FontAttributesMissingTestCase extends BaseUserConfigTestCase {
+/*
+ * this font is without a metrics-url or an embed-url
+ */
+public class FontAttributesMissingTestCase extends BaseDestructiveUserConfigTestCase {
 
     public FontAttributesMissingTestCase(String name) {
         super(name);
     }
 
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_fontattributes_missing.xconf");
-    }
-    
-    public String getName() {
-        return "test_fontattributes_missing.xconf";
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_attributes_missing.xconf";
     }
 }
index 4280306d081d73378e49ccaace8bb1631b4591ae..af9031199a319dde1f7f5d6aeab1cba0fc6a44c0 100644 (file)
 
 package org.apache.fop.config;
 
-import java.io.File;
-
-// this font base does not exist and a relative font path is used
-public class FontBaseBadTestCase extends BaseUserConfigTestCase {
+/*
+ * this font base does not exist and a relative font path is used
+ */ 
+public class FontBaseBadTestCase extends BaseDestructiveUserConfigTestCase {
 
     public FontBaseBadTestCase(String name) {
         super(name);
@@ -34,16 +34,9 @@ public class FontBaseBadTestCase extends BaseUserConfigTestCase {
     }
 
     /**
-     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFile()
-     */
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_fontbase_bad.xconf");
-    }
-    
-    /**
-     * @return configuration filename
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
      */
-    public String getName() {
+    public String getUserConfigFilename() {
         return "test_fontbase_bad.xconf";
     }
 }
diff --git a/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java b/test/java/org/apache/fop/config/FontEmbedUrlBadTestCase.java
new file mode 100644 (file)
index 0000000..218cee7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/**
+ * this font has an embed-url that does not exist on filesystem.
+ */
+public class FontEmbedUrlBadTestCase extends BaseDestructiveUserConfigTestCase {
+
+    public FontEmbedUrlBadTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_embedurl_bad.xconf";
+    }
+}
diff --git a/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontEmbedUrlMalformedTestCase.java
new file mode 100644 (file)
index 0000000..e87164e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/** 
+ * this font has a malformed embed-url
+ */
+public class FontEmbedUrlMalformedTestCase extends BaseDestructiveUserConfigTestCase {
+
+    public FontEmbedUrlMalformedTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_embedurl_malformed.xconf";
+    }
+}
diff --git a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java
new file mode 100644 (file)
index 0000000..00c4db7
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/*
+ * this font has a metrics-url that does not exist on filesystem
+ */ 
+public class FontMetricsUrlBadTestCase extends BaseDestructiveUserConfigTestCase {
+
+    /**
+     * @see junit.framework.TestCase#TestCase(String)
+     */
+    public FontMetricsUrlBadTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_metricsurl_bad.xconf";
+    }
+}
diff --git a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java
new file mode 100644 (file)
index 0000000..d5815b4
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/*
+ * this font has a malformed metrics-url
+ */ 
+public class FontMetricsUrlMalformedTestCase extends BaseDestructiveUserConfigTestCase {
+
+    public FontMetricsUrlMalformedTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_metricsurl_malformed.xconf";
+    }
+}
index c321926f8a8d1bb677111306d3b919588f5e7926..aed07ed48b45573653d0eb670609a1569f048198 100644 (file)
 
 package org.apache.fop.config;
 
-import java.io.File;
-
-// this font has an embed-url that does not exist on filesystem
-public class FontTripletAttributeMissingTestCase extends BaseUserConfigTestCase {
+/*
+ * this font has a missing font triplet attribute
+ */ 
+public class FontTripletAttributeMissingTestCase extends BaseDestructiveUserConfigTestCase {
 
     public FontTripletAttributeMissingTestCase(String name) {
         super(name);
     }
 
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_fonttripletattribute_missing.xconf");
-    }
-    
-    public String getName() {
-        return "test_fonttripletattribute_missing.xconf";
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_font_tripletattribute_missing.xconf";
     }
 }
diff --git a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java
new file mode 100644 (file)
index 0000000..3e188a3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+public class FontsAutoDetectTestCase extends BaseConstructiveUserConfigTestCase {
+
+    public FontsAutoDetectTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_fonts_autodetect.xconf";
+    }
+}
diff --git a/test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java b/test/java/org/apache/fop/config/FontsDirectoryBadTestCase.java
new file mode 100644 (file)
index 0000000..b439e37
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/*
+ * this font has a metrics-url that does not exist on filesystem
+ */ 
+public class FontsDirectoryBadTestCase extends BaseDestructiveUserConfigTestCase {
+
+    public FontsDirectoryBadTestCase(String name) {
+        super(name);
+    }
+    
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    public String getUserConfigFilename() {
+        return "test_fonts_directory_bad.xconf";
+    }
+    
+    /** get test FOP config File */
+    protected String getFontFOFilePath() {
+        return "test/xml/bugtests/font-dir.fo";
+    }
+}
diff --git a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java
new file mode 100644 (file)
index 0000000..1759f53
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.config;
+
+/**
+ * tests font directory on system 
+ */
+public class FontsDirectoryRecursiveTestCase extends BaseConstructiveUserConfigTestCase {
+
+    public FontsDirectoryRecursiveTestCase(String name) {
+        super(name);
+    }
+
+    /**
+     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFilename()
+     */
+    protected String getUserConfigFilename() {
+        return "test_fonts_directory_recursive.xconf";
+    }    
+}
diff --git a/test/java/org/apache/fop/config/MetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/MetricsUrlBadTestCase.java
deleted file mode 100644 (file)
index 80f7e28..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.config;
-
-import java.io.File;
-
-// this font has a metrics-url that does not exist on filesystem
-public class MetricsUrlBadTestCase extends BaseUserConfigTestCase {
-
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public MetricsUrlBadTestCase(String name) {
-        super(name);
-    }
-
-    /**
-     * @see org.apache.fop.config.BaseUserConfigTestCase#getUserConfigFile()
-     */
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_metricsurl_bad.xconf");
-    }
-    
-    public String getName() {
-        return "test_metricsurl_bad.xconf";
-    }
-}
diff --git a/test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/MetricsUrlMalformedTestCase.java
deleted file mode 100644 (file)
index 6b623e0..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.config;
-
-import java.io.File;
-
-// this font has a malformed metrics-url
-public class MetricsUrlMalformedTestCase extends BaseUserConfigTestCase {
-
-    public MetricsUrlMalformedTestCase(String name) {
-        super(name);
-    }
-
-    protected File getUserConfigFile() {
-        return new File( getBaseConfigDir() + "/test_metricsurl_malformed.xconf");
-    }
-    
-    public String getName() {
-        return "test_metricsurl_malformed.xconf";
-    }
-}
index ab612d043406803a7f9b52cc6500acf54a5ac30d..439a2c031dcfd47ce2b877505b54b4ce4e4a7736 100644 (file)
@@ -38,10 +38,12 @@ public class UserConfigTestSuite {
         suite.addTest(new TestSuite(FontBaseBadTestCase.class));
         suite.addTest(new TestSuite(FontAttributesMissingTestCase.class));
         suite.addTest(new TestSuite(FontTripletAttributeMissingTestCase.class));
-        suite.addTest(new TestSuite(MetricsUrlBadTestCase.class));
-        suite.addTest(new TestSuite(EmbedUrlBadTestCase.class));
-        suite.addTest(new TestSuite(MetricsUrlMalformedTestCase.class));
-        suite.addTest(new TestSuite(EmbedUrlMalformedTestCase.class));
+        suite.addTest(new TestSuite(FontMetricsUrlBadTestCase.class));
+        suite.addTest(new TestSuite(FontEmbedUrlBadTestCase.class));
+        suite.addTest(new TestSuite(FontMetricsUrlMalformedTestCase.class));
+        suite.addTest(new TestSuite(FontEmbedUrlMalformedTestCase.class));
+        suite.addTest(new TestSuite(FontsDirectoryRecursiveTestCase.class));
+        suite.addTest(new TestSuite(FontsAutoDetectTestCase.class));
         //$JUnit-END$
         return suite;
     }
index 3e399e064ee66dc3cd294894102f80084c2a429b..3b4e0311889bfde4cb68402abe0584a90873edba 100644 (file)
@@ -93,7 +93,10 @@ public class BasePDFTestCase extends AbstractFOPTestCase {
         return result;
     }
 
-    /** get FOP config File */
+    /** 
+     * get FOP config File 
+     * @return user config file to be used for testing 
+     */
     protected File getUserConfigFile() {
         return new File("test/test.xconf");
     }
index c0df5b0ddfb885da5f3aab4f4c401aef781d1d02..56fdd8bd8d416bff963a0b46bf94972d09878a90 100644 (file)
@@ -1,5 +1,9 @@
 <?xml version="1.0"?>
 <fop version="1.0">
+
+  <!-- Switch off font caching for the purposes of unit testing -->
+  <use-cache>false</use-cache>
+  
   <renderers>
     <renderer mime="application/pdf">
       <fonts>
diff --git a/test/xml/bugtests/font-dir.fo b/test/xml/bugtests/font-dir.fo
new file mode 100644 (file)
index 0000000..c2178d7
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+  <fo:layout-master-set>
+      <fo:simple-page-master master-name="simplePM"
+                    page-height="25cm"
+                    page-width="20cm"
+                    margin-top="1cm"
+                    margin-bottom="1cm"
+                    margin-left="1.5cm"
+                    margin-right="1.5cm">
+        <fo:region-body margin-top="3cm" margin-bottom="3cm"/>
+        <fo:region-before extent="2.5cm"/>
+        <fo:region-after extent="2.5cm"/>
+      </fo:simple-page-master>
+  </fo:layout-master-set>
+
+  <fo:page-sequence master-reference="simplePM">
+      <fo:flow flow-name="xsl-region-body">
+      <fo:block font-family="RageItalic" font-size="12pt">
+        This is a simple fo text in Rage italic font.
+      </fo:block>
+    </fo:flow>
+  </fo:page-sequence>
+</fo:root>
index 6046fb45c36c4f7d132e21826378b639b582fb18..82d126328f9482e59a82bca8f2c6718ee9368b22 100644 (file)
@@ -23,6 +23,9 @@
 -->
 
 <fop version="1.0">
+  <!-- Switch off font caching for the purposes of unit testing -->
+  <cache-fonts>false</cache-fonts>
+
   <renderers>
     <renderer mime="application/pdf">
       <!-- disable PDF text compression -->