aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/trunk/configuration.xml18
-rw-r--r--src/documentation/content/xdocs/trunk/fonts.xml36
-rw-r--r--src/java/org/apache/fop/apps/FOURIResolver.java189
-rw-r--r--src/java/org/apache/fop/apps/FOUserAgent.java43
-rw-r--r--src/java/org/apache/fop/apps/FopFactory.java364
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryConfigurator.java241
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java2
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java6
-rw-r--r--src/java/org/apache/fop/fonts/CachedFontInfo.java117
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java27
-rw-r--r--src/java/org/apache/fop/fonts/EmbedFontInfo.java29
-rw-r--r--src/java/org/apache/fop/fonts/Font.java20
-rw-r--r--src/java/org/apache/fop/fonts/FontCache.java330
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java11
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java100
-rw-r--r--src/java/org/apache/fop/fonts/FontSetup.java265
-rw-r--r--src/java/org/apache/fop/fonts/FontUtil.java20
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java18
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java23
-rw-r--r--src/java/org/apache/fop/fonts/apps/TTFReader.java21
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java158
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFinder.java38
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java171
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java39
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java55
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java39
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java108
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/package.html23
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java8
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java48
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java23
-rw-r--r--src/java/org/apache/fop/pdf/PDFFilterList.java64
-rw-r--r--src/java/org/apache/fop/render/AbstractRenderer.java60
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererConfigurator.java91
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererMaker.java15
-rw-r--r--src/java/org/apache/fop/render/PrintRenderer.java19
-rw-r--r--src/java/org/apache/fop/render/PrintRendererConfigurator.java332
-rw-r--r--src/java/org/apache/fop/render/RendererConfigurator.java34
-rw-r--r--src/java/org/apache/fop/render/RendererContext.java10
-rw-r--r--src/java/org/apache/fop/render/RendererFactory.java18
-rw-r--r--src/java/org/apache/fop/render/XMLHandlerConfigurator.java92
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRenderer.java211
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java241
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererMaker.java8
-rw-r--r--src/java/org/apache/fop/render/awt/AWTRenderer.java5
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRenderer.java41
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java72
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java11
-rw-r--r--src/java/org/apache/fop/render/java2d/FontSetup.java118
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderer.java25
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java57
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRenderer.java33
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java74
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererMaker.java15
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java52
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java134
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererMaker.java11
-rw-r--r--src/java/org/apache/fop/render/print/PrintRendererMaker.java12
-rw-r--r--src/java/org/apache/fop/render/ps/NativeTextHandler.java2
-rw-r--r--src/java/org/apache/fop/render/ps/PSRenderer.java21
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererConfigurator.java56
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererMaker.java12
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java8
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRenderer.java8
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java53
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRendererMaker.java12
-rw-r--r--src/java/org/apache/fop/render/xml/XMLRenderer.java19
-rw-r--r--src/java/org/apache/fop/render/xml/XMLRendererMaker.java12
-rw-r--r--src/java/org/apache/fop/svg/PDFContext.java16
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java88
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java66
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java2
-rw-r--r--src/java/org/apache/fop/svg/PDFTextElementBridge.java5
-rw-r--r--src/java/org/apache/fop/svg/PDFTextPainter.java8
-rw-r--r--src/java/org/apache/fop/svg/PDFTranscoder.java20
-rw-r--r--src/java/org/apache/fop/util/LogUtil.java57
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGRenderer.java9
77 files changed, 3583 insertions, 1336 deletions
diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml
index 7032379ca..b7984e773 100644
--- a/src/documentation/content/xdocs/trunk/configuration.xml
+++ b/src/documentation/content/xdocs/trunk/configuration.xml
@@ -152,6 +152,24 @@
<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>
<td>Contains the configuration for each renderer. See below.</td>
diff --git a/src/documentation/content/xdocs/trunk/fonts.xml b/src/documentation/content/xdocs/trunk/fonts.xml
index ca6209c6d..2ee297ba0 100644
--- a/src/documentation/content/xdocs/trunk/fonts.xml
+++ b/src/documentation/content/xdocs/trunk/fonts.xml
@@ -24,6 +24,7 @@
<authors>
<person name="Jeremias Märki" email=""/>
<person name="Tore Engvig" email=""/>
+ <person name="Adrian Cumiskey" email=""/>
</authors>
</header>
<body>
@@ -129,8 +130,7 @@
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
diff --git a/src/java/org/apache/fop/apps/FOURIResolver.java b/src/java/org/apache/fop/apps/FOURIResolver.java
index e3ffd22cc..13baeaa56 100644
--- a/src/java/org/apache/fop/apps/FOURIResolver.java
+++ b/src/java/org/apache/fop/apps/FOURIResolver.java
@@ -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,9 +48,42 @@ 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.
* (see also {@link javax.xml.transform.URIResolver#resolve(String, String)}
@@ -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;
}
@@ -201,29 +243,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>
*/
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
index f15ddcc31..24df2f75b 100644
--- a/src/java/org/apache/fop/apps/FOUserAgent.java
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -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();
}
/**
diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java
index f7a3bd251..1e7ab2a62 100644
--- a/src/java/org/apache/fop/apps/FopFactory.java
+++ b/src/java/org/apache/fop/apps/FopFactory.java
@@ -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);
}
/**
@@ -336,11 +323,42 @@ public class FopFactory {
}
/**
+ * 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
index 000000000..d708cd989
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java
@@ -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;
+ }
+}
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java
index 9e293afac..ba819621e 100644
--- a/src/java/org/apache/fop/area/AreaTreeParser.java
+++ b/src/java/org/apache/fop/area/AreaTreeParser.java
@@ -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));
}
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index ce6aa64b8..63a817071 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -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
index 000000000..281289193
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/CachedFontInfo.java
@@ -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;
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index 5d7221c13..1455319e6 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -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()
*/
@@ -60,6 +60,21 @@ public abstract class CustomFont extends Typeface
}
/**
+ * @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.
* @return URI to an embeddable font file or null if not available.
@@ -239,6 +254,14 @@ public abstract class CustomFont extends Typeface
}
/**
+ * 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)
*/
public void setEmbedFileName(String path) {
diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
index 45f9bb6e4..ad8915d9d 100644
--- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java
+++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
@@ -19,17 +19,26 @@
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;
+ }
}
-
diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java
index a6b6d52d4..de83072c6 100644
--- a/src/java/org/apache/fop/fonts/Font.java
+++ b/src/java/org/apache/fop/fonts/Font.java
@@ -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
index 000000000..036ec724e
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontCache.java
@@ -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;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
index 987bb94b7..995d59bf8 100644
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ b/src/java/org/apache/fop/fonts/FontInfo.java
@@ -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;
}
}
-
}
-
-
-
diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java
index 4377f9fab..c48e36453 100644
--- a/src/java/org/apache/fop/fonts/FontLoader.java
+++ b/src/java/org/apache/fop/fonts/FontLoader.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -28,6 +29,8 @@ import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.truetype.TTFFontLoader;
import org.apache.fop.fonts.type1.Type1FontLoader;
@@ -37,6 +40,51 @@ import org.apache.fop.fonts.type1.Type1FontLoader;
public abstract class FontLoader {
/**
+ * logging instance
+ */
+ protected static Log log = LogFactory.getLog(FontLoader.class);
+
+ /** URI representing the font file */
+ protected String fontFileURI = null;
+ /** the InputStream to load the font from */
+ protected InputStream in = null;
+ /** the FontResolver to use for font URI resolution */
+ protected FontResolver resolver = null;
+ /** the loaded font */
+ protected CustomFont returnFont = null;
+
+ /** true if the font has been loaded */
+ protected boolean loaded = false;
+
+ /**
+ * Default constructor.
+ * @param fontFileURI the URI to the PFB file of a Type 1 font
+ * @param in the InputStream reading the PFM file of a Type 1 font
+ * @param resolver the font resolver used to resolve URIs
+ */
+ public FontLoader(String fontFileURI, InputStream in, FontResolver resolver) {
+ this.fontFileURI = fontFileURI;
+ this.in = in;
+ this.resolver = resolver;
+ }
+
+ private static boolean isType1(String fontURI) {
+ return fontURI.toLowerCase().endsWith(".pfb");
+ }
+
+ /**
+ * Loads a custom font from a File. In the case of Type 1 fonts, the PFB file must be specified.
+ * @param fontFile the File representation of the font
+ * @param resolver the font resolver to use when resolving URIs
+ * @return the newly loaded font
+ * @throws IOException In case of an I/O error
+ */
+ public static CustomFont loadFont(File fontFile, FontResolver resolver)
+ throws IOException {
+ return loadFont(fontFile.getAbsolutePath(), resolver);
+ }
+
+ /**
* Loads a custom font from a URI. In the case of Type 1 fonts, the PFB file must be specified.
* @param fontFileURI the URI to the font
* @param resolver the font resolver to use when resolving URIs
@@ -45,21 +93,38 @@ public abstract class FontLoader {
*/
public static CustomFont loadFont(String fontFileURI, FontResolver resolver)
throws IOException {
- FontLoader loader;
fontFileURI = fontFileURI.trim();
String name = fontFileURI.toLowerCase();
String effURI;
- boolean type1 = false;
- if (name.endsWith(".pfb")) {
- type1 = true;
+ boolean type1 = isType1(fontFileURI);
+ if (type1) {
effURI = name.substring(0, fontFileURI.length() - 4) + ".pfm";
} else {
effURI = fontFileURI;
}
-
+ if (log.isDebugEnabled()) {
+ log.debug("opening " + effURI);
+ }
InputStream in = openFontFile(resolver, effURI);
+ return loadFontFromInputStream(fontFileURI, resolver, type1, in);
+ }
+
+ /**
+ * Loads and returns a font given an input stream.
+ * @param fontFileURI font file uri
+ * @param resolver font resolver
+ * @param isType1 is it a type1 font?
+ * @param in input stream
+ * @return the loaded font.
+ * @throws IOException In case of an I/O error
+ */
+ protected static CustomFont loadFontFromInputStream(
+ String fontFileURI, FontResolver resolver, boolean isType1,
+ InputStream in)
+ throws IOException {
+ FontLoader loader;
try {
- if (type1) {
+ if (isType1) {
loader = new Type1FontLoader(fontFileURI, in, resolver);
} else {
loader = new TTFFontLoader(fontFileURI, in, resolver);
@@ -70,6 +135,14 @@ public abstract class FontLoader {
}
}
+ /**
+ * Opens a font file and returns an input stream.
+ * @param resolver the FontResolver to use for font URI resolution
+ * @param uri the URI representing the font
+ * @return the InputStream to read the font from.
+ * @throws IOException In case of an I/O error
+ * @throws MalformedURLException If an invalid URL is built
+ */
private static InputStream openFontFile(FontResolver resolver, String uri)
throws IOException, MalformedURLException {
InputStream in = null;
@@ -96,11 +169,18 @@ public abstract class FontLoader {
}
return in;
}
-
+
/**
- * @return the font loaded by this loader
+ * Reads/parses the font data.
+ * @throws IOException In case of an I/O error
*/
- public abstract CustomFont getFont();
+ protected abstract void read() throws IOException;
-
+ /** @see org.apache.fop.fonts.FontLoader#getFont() */
+ public CustomFont getFont() throws IOException {
+ if (!loaded) {
+ read();
+ }
+ return this.returnFont;
+ }
}
diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java
index 9659398ba..0028f3281 100644
--- a/src/java/org/apache/fop/fonts/FontSetup.java
+++ b/src/java/org/apache/fop/fonts/FontSetup.java
@@ -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);
- }
+ }
}
diff --git a/src/java/org/apache/fop/fonts/FontUtil.java b/src/java/org/apache/fop/fonts/FontUtil.java
index e08ba3815..7ca2a0371 100644
--- a/src/java/org/apache/fop/fonts/FontUtil.java
+++ b/src/java/org/apache/fop/fonts/FontUtil.java
@@ -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();
+ }
+
+
}
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
index 658c0cf1e..9fff44e10 100644
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ b/src/java/org/apache/fop/fonts/LazyFont.java
@@ -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();
}
-
}
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index 1b9263d17..e326140b5 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -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);
}
/**
diff --git a/src/java/org/apache/fop/fonts/apps/TTFReader.java b/src/java/org/apache/fop/fonts/apps/TTFReader.java
index 93388c34f..4d5cc3942 100644
--- a/src/java/org/apache/fop/fonts/apps/TTFReader.java
+++ b/src/java/org/apache/fop/fonts/apps/TTFReader.java
@@ -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
index 000000000..a19ab5a38
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
@@ -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
index 000000000..2bcdc9ae2
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/FontFinder.java
@@ -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
index 000000000..910b5dd59
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
@@ -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
index 000000000..60d3fd7d3
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/MacFontDirFinder.java
@@ -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
index 000000000..e9bfe9447
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/NativeFontDirFinder.java
@@ -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
index 000000000..0d02c6daf
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/UnixFontDirFinder.java
@@ -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
index 000000000..19901dc0a
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/WindowsFontDirFinder.java
@@ -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
index 000000000..0a29acbb1
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/package.html
@@ -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>
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
index 319a208d7..7653d8df1 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
@@ -567,6 +567,14 @@ public class TTFFile {
}
/**
+ * 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
*/
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
index 81810874d..f5a0447b4 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
@@ -27,7 +27,6 @@ import java.util.Map;
import org.apache.fop.fonts.BFEntry;
import org.apache.fop.fonts.CIDFontType;
-import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.FontLoader;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.MultiByteFont;
@@ -37,18 +36,23 @@ import org.apache.fop.fonts.MultiByteFont;
*/
public class TTFFontLoader extends FontLoader {
- private String fontFileURI;
- private TTFFile ttf;
private MultiByteFont multiFont;
- private CustomFont returnFont;
- private FontResolver resolver;
- public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver)
- throws IOException {
- this.fontFileURI = fontFileURI;
- this.resolver = resolver;
-
- this.ttf = new TTFFile();
+ /**
+ * Default constructor
+ * @param fontFileURI the URI representing the font file
+ * @param in the InputStream to load the font from
+ * @param resolver the FontResolver for font URI resolution
+ */
+ public TTFFontLoader(String fontFileURI, InputStream in, FontResolver resolver) {
+ super(fontFileURI, in, resolver);
+ }
+
+ /**
+ * @see FontLoader#read()
+ */
+ protected void read() throws IOException {
+ TTFFile ttf = new TTFFile();
FontFileReader reader = new FontFileReader(in);
boolean supported = ttf.readFont(reader, null);
if (!supported) {
@@ -61,11 +65,9 @@ public class TTFFontLoader extends FontLoader {
multiFont = new MultiByteFont();
multiFont.setResolver(this.resolver);
returnFont = multiFont;
- read();
- }
-
- private void read() throws IOException {
+
returnFont.setFontName(ttf.getFamilyName());
+ returnFont.setFontSubFamilyName(ttf.getSubFamilyName());
//multiFont.setTTCName(ttcName)
returnFont.setCapHeight(ttf.getCapHeight());
returnFont.setXHeight(ttf.getXHeight());
@@ -77,6 +79,7 @@ public class TTFFontLoader extends FontLoader {
returnFont.setStemV(Integer.parseInt(ttf.getStemV())); //not used for TTF
returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
returnFont.setMissingWidth(0);
+
multiFont.setCIDType(CIDFontType.CIDTYPE2);
int[] wx = ttf.getWidths();
multiFont.setWidthArray(wx);
@@ -93,9 +96,12 @@ public class TTFFontLoader extends FontLoader {
multiFont.setBFEntries(bfentries);
copyKerning(ttf, true);
multiFont.setEmbedFileName(this.fontFileURI);
-
+ loaded = true;
}
+ /**
+ * Copy kerning information.
+ */
private void copyKerning(TTFFile ttf, boolean isCid) {
// Get kerning
@@ -115,15 +121,7 @@ public class TTFFontLoader extends FontLoader {
} else {
h2 = (Map)ttf.getAnsiKerning().get(kpx1);
}
-
returnFont.putKerningEntry(kpx1, h2);
}
- }
-
-
- /** @see org.apache.fop.fonts.FontLoader#getFont() */
- public CustomFont getFont() {
- return this.returnFont;
- }
-
+ }
}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
index ef0d45767..3db4a6d2d 100644
--- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
+++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
@@ -22,7 +22,6 @@ package org.apache.fop.fonts.type1;
import java.io.IOException;
import java.io.InputStream;
-import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.FontLoader;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontType;
@@ -33,11 +32,8 @@ import org.apache.fop.fonts.SingleByteFont;
*/
public class Type1FontLoader extends FontLoader {
- private String fontFileURI;
private PFMFile pfm;
private SingleByteFont singleFont;
- private CustomFont returnFont;
- private FontResolver resolver;
/**
* Constructs a new Type 1 font loader.
@@ -48,19 +44,19 @@ public class Type1FontLoader extends FontLoader {
*/
public Type1FontLoader(String fontFileURI, InputStream in, FontResolver resolver)
throws IOException {
- this.fontFileURI = fontFileURI;
- this.resolver = resolver;
+ super(fontFileURI, in, resolver);
+ }
+ /**
+ * @see FontLoader#read()
+ */
+ protected void read() throws IOException {
pfm = new PFMFile();
pfm.load(in);
singleFont = new SingleByteFont();
singleFont.setFontType(FontType.TYPE1);
singleFont.setResolver(this.resolver);
returnFont = singleFont;
- read();
- }
-
- private void read() throws IOException {
returnFont.setFontName(pfm.getPostscriptName());
returnFont.setCapHeight(pfm.getCapHeight());
returnFont.setXHeight(pfm.getXHeight());
@@ -77,12 +73,5 @@ public class Type1FontLoader extends FontLoader {
singleFont.setWidth(i, pfm.getCharWidth(i));
}
singleFont.setEmbedFileName(this.fontFileURI);
-
- }
-
- /** @see org.apache.fop.fonts.FontLoader#getFont() */
- public CustomFont getFont() {
- return this.returnFont;
}
-
}
diff --git a/src/java/org/apache/fop/pdf/PDFFilterList.java b/src/java/org/apache/fop/pdf/PDFFilterList.java
index 3ab0b8419..e0ee7eb4b 100644
--- a/src/java/org/apache/fop/pdf/PDFFilterList.java
+++ b/src/java/org/apache/fop/pdf/PDFFilterList.java
@@ -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;
- }
-
}
diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java
index 50c314f15..e2d314885 100644
--- a/src/java/org/apache/fop/render/AbstractRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractRenderer.java
@@ -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");
@@ -118,12 +113,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)
*/
public abstract void setupFontInfo(FontInfo fontInfo);
@@ -805,39 +794,6 @@ public abstract class AbstractRenderer
}
/**
- * 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
* rendering target.
@@ -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
index 000000000..1e485735b
--- /dev/null
+++ b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
@@ -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;
+ }
+}
diff --git a/src/java/org/apache/fop/render/AbstractRendererMaker.java b/src/java/org/apache/fop/render/AbstractRendererMaker.java
index 0c6bea631..ab1ddb338 100644
--- a/src/java/org/apache/fop/render/AbstractRendererMaker.java
+++ b/src/java/org/apache/fop/render/AbstractRendererMaker.java
@@ -29,10 +29,10 @@ public abstract class AbstractRendererMaker {
/**
* Instantiates a new renderer.
- * @param ua the user agent
+ * @param userAgent the user agent
* @return the newly instantiated renderer
*/
- public abstract Renderer makeRenderer(FOUserAgent ua);
+ public abstract Renderer makeRenderer(FOUserAgent userAgent);
/**
* @return Indicates whether this renderer requires an OutputStream to work with.
@@ -45,6 +45,16 @@ public abstract class AbstractRendererMaker {
public abstract String[] getSupportedMimeTypes();
/**
+ * Returns a renderer config object that can be used to
+ * configure the renderer.
+ * @param userAgent user agent
+ * @return a config object that can be used to configure the renderer
+ */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return null;
+ }
+
+ /**
* Indicates whether a specific MIME type is supported by this renderer.
* @param mimeType the MIME type (ex. "application/pdf")
* @return true if the MIME type is supported
@@ -58,5 +68,4 @@ public abstract class AbstractRendererMaker {
}
return false;
}
-
}
diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java
index 6a3cdf2c6..f725bd711 100644
--- a/src/java/org/apache/fop/render/PrintRenderer.java
+++ b/src/java/org/apache/fop/render/PrintRenderer.java
@@ -46,8 +46,27 @@ 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
*
* @param inFontInfo font info to set up
diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
new file mode 100644
index 000000000..d9b922965
--- /dev/null
+++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
@@ -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
index 000000000..566daf07d
--- /dev/null
+++ b/src/java/org/apache/fop/render/RendererConfigurator.java
@@ -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;
+}
diff --git a/src/java/org/apache/fop/render/RendererContext.java b/src/java/org/apache/fop/render/RendererContext.java
index 49f53b327..feffc05ed 100644
--- a/src/java/org/apache/fop/render/RendererContext.java
+++ b/src/java/org/apache/fop/render/RendererContext.java
@@ -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);
- }
-
+ }
}
}
diff --git a/src/java/org/apache/fop/render/RendererFactory.java b/src/java/org/apache/fop/render/RendererFactory.java
index 4d3f3a12c..d81f900e0 100644
--- a/src/java/org/apache/fop/render/RendererFactory.java
+++ b/src/java/org/apache/fop/render/RendererFactory.java
@@ -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
index 000000000..bf63329d7
--- /dev/null
+++ b/src/java/org/apache/fop/render/XMLHandlerConfigurator.java
@@ -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);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java
index 78d8b7d0a..ea1087893 100644
--- a/src/java/org/apache/fop/render/afp/AFPRenderer.java
+++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java
@@ -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;
@@ -303,195 +298,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)
*/
public void setUserAgent(FOUserAgent agent) {
@@ -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
index 000000000..aebabd97b
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -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);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererMaker.java b/src/java/org/apache/fop/render/afp/AFPRendererMaker.java
index 2d6d5711d..70bbe9076 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererMaker.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererMaker.java
@@ -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;
diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java
index 6a50c0294..e83d8d220 100644
--- a/src/java/org/apache/fop/render/awt/AWTRenderer.java
+++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java
@@ -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);
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
index c96c82259..5c22c8f34 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
@@ -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
index 000000000..2e4e29691
--- /dev/null
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java
@@ -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);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java b/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
index ee2ba75fd..5e9f18261 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
@@ -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 TIFF Renderer.
@@ -31,12 +32,16 @@ public class TIFFRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_TIFF};
-
- /** @see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new TIFFRenderer();
}
+ /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new TIFFRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
diff --git a/src/java/org/apache/fop/render/java2d/FontSetup.java b/src/java/org/apache/fop/render/java2d/FontSetup.java
index ceda8f16c..e1dffd0e7 100644
--- a/src/java/org/apache/fop/render/java2d/FontSetup.java
+++ b/src/java/org/apache/fop/render/java2d/FontSetup.java
@@ -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) {
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
index 2bb3711bb..7d837e699 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
@@ -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;
@@ -151,19 +149,6 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
}
/**
- * @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)
*/
public void setUserAgent(FOUserAgent 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
index 000000000..6732a10fe
--- /dev/null
+++ b/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java
@@ -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));
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderer.java b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
index 596dc06d3..733212e48 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRenderer.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRenderer.java
@@ -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
index 000000000..814b6837c
--- /dev/null
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
@@ -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);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java b/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java
index aa0bc292b..b7b395341 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererMaker.java
@@ -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 PCL Renderer.
@@ -31,14 +32,19 @@ public class PCLRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {
MimeConstants.MIME_PCL,
- MimeConstants.MIME_PCL_ALT};
+ MimeConstants.MIME_PCL_ALT
+ };
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new PCLRenderer();
}
+ /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PCLRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
@@ -48,5 +54,4 @@ public class PCLRendererMaker extends AbstractRendererMaker {
public String[] getSupportedMimeTypes() {
return MIMES;
}
-
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 7d584c036..73c38878e 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -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
index 000000000..5c5894d3b
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
@@ -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;
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java b/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java
index 0f8d8bc14..00fc1a88f 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererMaker.java
@@ -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 PDF Renderer.
@@ -31,12 +32,16 @@ public class PDFRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF};
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new PDFRenderer();
}
+ /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PDFRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
diff --git a/src/java/org/apache/fop/render/print/PrintRendererMaker.java b/src/java/org/apache/fop/render/print/PrintRendererMaker.java
index 046427682..6ad2cb3d1 100644
--- a/src/java/org/apache/fop/render/print/PrintRendererMaker.java
+++ b/src/java/org/apache/fop/render/print/PrintRendererMaker.java
@@ -22,7 +22,9 @@ package org.apache.fop.render.print;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.AbstractRendererMaker;
+import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfigurator;
/**
* RendererMaker for the Print Renderer.
@@ -31,12 +33,16 @@ public class PrintRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_PRINT};
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new PrintRenderer();
}
+ /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PrintRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return false;
diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
index 47f7fb0b8..5cda145b9 100644
--- a/src/java/org/apache/fop/render/ps/NativeTextHandler.java
+++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
@@ -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) {
diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java
index 68c6cc86c..ad5b0b3ce 100644
--- a/src/java/org/apache/fop/render/ps/PSRenderer.java
+++ b/src/java/org/apache/fop/render/ps/PSRenderer.java
@@ -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;
@@ -146,24 +143,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer implements ImageAda
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)
*/
public void setUserAgent(FOUserAgent agent) {
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
index 000000000..c7b5a025b
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java
@@ -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));
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererMaker.java b/src/java/org/apache/fop/render/ps/PSRendererMaker.java
index 45f7663aa..0db4281d0 100644
--- a/src/java/org/apache/fop/render/ps/PSRendererMaker.java
+++ b/src/java/org/apache/fop/render/ps/PSRendererMaker.java
@@ -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 PostScript Renderer.
@@ -31,12 +32,16 @@ public class PSRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_POSTSCRIPT};
-
- /** @see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /** @see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new PSRenderer();
}
+ /** @see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PSRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
@@ -46,5 +51,4 @@ public class PSRendererMaker extends AbstractRendererMaker {
public String[] getSupportedMimeTypes() {
return MIMES;
}
-
}
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index 78efd56b9..f4796fd2b 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -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)) {
diff --git a/src/java/org/apache/fop/render/txt/TXTRenderer.java b/src/java/org/apache/fop/render/txt/TXTRenderer.java
index 85d3dd797..cec1dbc4b 100644
--- a/src/java/org/apache/fop/render/txt/TXTRenderer.java
+++ b/src/java/org/apache/fop/render/txt/TXTRenderer.java
@@ -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
index 000000000..ab655c92e
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java
@@ -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));
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/txt/TXTRendererMaker.java b/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
index 5c1b812b6..8a92ed11d 100644
--- a/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
+++ b/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
@@ -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 Plain Text Renderer.
@@ -31,12 +32,16 @@ public class TXTRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PLAIN_TEXT};
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new TXTRenderer();
}
+ /**@see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new TXTRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
@@ -46,5 +51,4 @@ public class TXTRendererMaker extends AbstractRendererMaker {
public String[] getSupportedMimeTypes() {
return MIMES;
}
-
}
diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java
index cccdb6d71..b95ea7e18 100644
--- a/src/java/org/apache/fop/render/xml/XMLRenderer.java
+++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java
@@ -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;
@@ -140,22 +137,6 @@ public class XMLRenderer extends PrintRenderer {
}
/**
- * 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)
*/
public void setUserAgent(FOUserAgent agent) {
diff --git a/src/java/org/apache/fop/render/xml/XMLRendererMaker.java b/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
index 1be56f39a..582cfb9be 100644
--- a/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
+++ b/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
@@ -22,7 +22,9 @@ package org.apache.fop.render.xml;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.AbstractRendererMaker;
+import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfigurator;
/**
* RendererMaker for the Area Tree XML Renderer.
@@ -31,12 +33,16 @@ public class XMLRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_AREA_TREE};
-
- /**@see org.apache.fop.render.AbstractRendererMaker */
- public Renderer makeRenderer(FOUserAgent ua) {
+ /**@see org.apache.fop.render.AbstractRendererMaker#makeRenderer(FOUserAgent) */
+ public Renderer makeRenderer(FOUserAgent userAgent) {
return new XMLRenderer();
}
+ /**@see org.apache.fop.render.AbstractRendererMaker#getConfigurator(FOUserAgent) */
+ public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
+ return new PrintRendererConfigurator(userAgent);
+ }
+
/** @see org.apache.fop.render.AbstractRendererMaker#needsOutputStream() */
public boolean needsOutputStream() {
return true;
diff --git a/src/java/org/apache/fop/svg/PDFContext.java b/src/java/org/apache/fop/svg/PDFContext.java
index 7f96fb060..494d47636 100644
--- a/src/java/org/apache/fop/svg/PDFContext.java
+++ b/src/java/org/apache/fop/svg/PDFContext.java
@@ -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;
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
index 0e699dec7..9c72ade1a 100644
--- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java
@@ -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);
- }
}
/**
@@ -154,33 +136,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
}
/**
- * @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
* @param width the width of the page
@@ -197,6 +152,18 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
}
/**
+ * 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.
* @param deviceDPI the device resolution (in dpi)
@@ -213,6 +180,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
}
/**
+ * 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
*/
@@ -229,6 +204,14 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D
}
/**
+ * 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
* from the pdf document that is to be created.
@@ -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
index 000000000..fe4d50a4a
--- /dev/null
+++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
@@ -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);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index 254a93cba..3902b30fd 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -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 {
diff --git a/src/java/org/apache/fop/svg/PDFTextElementBridge.java b/src/java/org/apache/fop/svg/PDFTextElementBridge.java
index cf9b7b7bd..100711eb9 100644
--- a/src/java/org/apache/fop/svg/PDFTextElementBridge.java
+++ b/src/java/org/apache/fop/svg/PDFTextElementBridge.java
@@ -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();
diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java
index eddd89d09..f05d5ae4f 100644
--- a/src/java/org/apache/fop/svg/PDFTextPainter.java
+++ b/src/java/org/apache/fop/svg/PDFTextPainter.java
@@ -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 {
diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java
index a90765a31..f6a986d0c 100644
--- a/src/java/org/apache/fop/svg/PDFTranscoder.java
+++ b/src/java/org/apache/fop/svg/PDFTranscoder.java
@@ -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
index 000000000..60eafb51a
--- /dev/null
+++ b/src/java/org/apache/fop/util/LogUtil.java
@@ -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());
+ }
+}
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java b/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
index 7a85afb2d..8b6f66b6c 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGRenderer.java
@@ -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;