aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/org/apache/fop')
-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
74 files changed, 3537 insertions, 1319 deletions
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());
+ }
+}