aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdrian Cumiskey <acumiskey@apache.org>2009-03-20 15:18:54 +0000
committerAdrian Cumiskey <acumiskey@apache.org>2009-03-20 15:18:54 +0000
commit6caf23b89cd7ec194aa91126bd5691cde323e9ae (patch)
treed7256c2a4add35f7e9dc8463f3c8b6162df9efc7 /src
parent41850c971a518fbf1662199518143c8581f179c8 (diff)
downloadxmlgraphics-fop-6caf23b89cd7ec194aa91126bd5691cde323e9ae.tar.gz
xmlgraphics-fop-6caf23b89cd7ec194aa91126bd5691cde323e9ae.zip
A little font configuration cleaning.
* Extracted business logic from PrintRendererConfigurator and created a new FontDetector and FontAdder in org.apache.fop.fonts package. * Created a new FontInfoConfigurator that factors out a lot of the static stuff in PrintRendererConfigurator. * PDFDocumentGraphics2DConfigurator now uses a new FontInfoConfigurator() instead of static PrintRendererConfigurator.buildFontListFromConfiguration() call. * static method updateReferencedFonts() in PrintRendererConfigurator moved to an instance method in FontManager. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@756522 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/java/org/apache/fop/fonts/FontAdder.java72
-rw-r--r--src/java/org/apache/fop/fonts/FontDetector.java101
-rw-r--r--src/java/org/apache/fop/fonts/FontInfoConfigurator.java310
-rw-r--r--src/java/org/apache/fop/fonts/FontManager.java25
-rw-r--r--src/java/org/apache/fop/render/AbstractConfigurator.java89
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererConfigurator.java62
-rw-r--r--src/java/org/apache/fop/render/PrintRendererConfigurator.java363
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java15
8 files changed, 630 insertions, 407 deletions
diff --git a/src/java/org/apache/fop/fonts/FontAdder.java b/src/java/org/apache/fop/fonts/FontAdder.java
new file mode 100644
index 000000000..0d6a730cf
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontAdder.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.fonts;
+
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.fonts.autodetect.FontInfoFinder;
+
+/**
+ * Adds a list of fonts to a given font info list
+ */
+public class FontAdder {
+ private FontEventListener listener;
+ private FontResolver resolver;
+ private FontManager manager;
+
+ /**
+ * Main constructor
+ * @param manager a font manager
+ * @param resolver a font resolver
+ * @param listener a font event handler
+ */
+ public FontAdder(FontManager manager, FontResolver resolver, FontEventListener listener) {
+ this.manager = manager;
+ this.resolver = resolver;
+ this.listener = listener;
+ }
+
+ /**
+ * Iterates over font url list adding to font info list
+ * @param fontURLList font file list
+ * @param fontInfoList a configured font info list
+ */
+ public void add(List/*<URL>*/ fontURLList, List/*<EmbedFontInfo>*/ fontInfoList) {
+ FontCache cache = manager.getFontCache();
+ FontInfoFinder finder = new FontInfoFinder();
+ finder.setEventListener(listener);
+
+ for (Iterator iter = fontURLList.iterator(); iter.hasNext();) {
+ URL fontUrl = (URL)iter.next();
+ EmbedFontInfo[] embedFontInfos = finder.find(fontUrl, resolver, cache);
+ if (embedFontInfos == null) {
+ continue;
+ }
+ for (int i = 0, c = embedFontInfos.length; i < c; i++) {
+ EmbedFontInfo fontInfo = embedFontInfos[i];
+ if (fontInfo != null) {
+ fontInfoList.add(fontInfo);
+ }
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontDetector.java b/src/java/org/apache/fop/fonts/FontDetector.java
new file mode 100644
index 000000000..09671f1f8
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontDetector.java
@@ -0,0 +1,101 @@
+/*
+ * 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.net.URL;
+import java.util.List;
+
+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.fonts.autodetect.FontFileFinder;
+import org.apache.fop.util.LogUtil;
+import org.apache.xmlgraphics.util.ClasspathResource;
+
+/**
+ * Detector of operating system and classpath fonts
+ */
+public class FontDetector {
+ private static Log log = LogFactory.getLog(FontDetector.class);
+
+ private static final String[] FONT_MIMETYPES = {
+ "application/x-font", "application/x-font-truetype"
+ };
+
+ private FontManager fontManager;
+ private FontAdder fontAdder;
+ private boolean strict;
+
+ /**
+ * Main constructor
+ * @param manager the font manager
+ * @param adder the font adder
+ * @param strict true if an Exception should be thrown if an error is found.
+ */
+ public FontDetector(FontManager manager, FontAdder adder, boolean strict) {
+ this.fontManager = manager;
+ this.fontAdder = adder;
+ this.strict = strict;
+ }
+
+ /**
+ * Detect installed fonts on the system
+ * @param fontInfoList a list of fontinfo to populate
+ * @throws FOPException thrown if a problem occurred during detection
+ */
+ public void detect(List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
+ // search in font base if it is defined and
+ // is a directory but don't recurse
+ FontFileFinder fontFileFinder = new FontFileFinder();
+ String fontBaseURL = fontManager.getFontBaseURL();
+ if (fontBaseURL != null) {
+ try {
+ File fontBase = FileUtils.toFile(new URL(fontBaseURL));
+ if (fontBase != null) {
+ List/*<URL>*/ fontURLList = fontFileFinder.find(
+ fontBase.getAbsolutePath());
+ fontAdder.add(fontURLList, fontInfoList);
+
+ //Can only use the font base URL if it's a file URL
+ }
+ } catch (IOException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ }
+
+ // native o/s font directory finding
+ List/*<URL>*/ systemFontList;
+ try {
+ systemFontList = fontFileFinder.find();
+ fontAdder.add(systemFontList, fontInfoList);
+ } catch (IOException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+
+ // classpath font finding
+ ClasspathResource resource = ClasspathResource.getInstance();
+ for (int i = 0; i < FONT_MIMETYPES.length; i++) {
+ fontAdder.add(resource.listResourcesOfMimeType(FONT_MIMETYPES[i]), fontInfoList);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
new file mode 100644
index 000000000..fe0ca85cd
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
@@ -0,0 +1,310 @@
+/*
+ * 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.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import javax.xml.transform.Source;
+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.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fonts.autodetect.FontFileFinder;
+import org.apache.fop.fonts.autodetect.FontInfoFinder;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * An abstract FontInfo configurator
+ */
+public class FontInfoConfigurator {
+ /** logger instance */
+ protected static Log log = LogFactory.getLog(FontInfoConfigurator.class);
+
+ private Configuration cfg;
+ private FontManager fontManager;
+ private FontResolver fontResolver;
+ private FontEventListener listener;
+ private boolean strict;
+
+ /**
+ * Main constructor
+ * @param cfg the configuration object
+ * @param fontManager the font manager
+ * @param fontResolver the font resolver
+ * @param listener the font event listener
+ * @param strict true if an Exception should be thrown if an error is found.
+ */
+ public FontInfoConfigurator(Configuration cfg, FontManager fontManager,
+ FontResolver fontResolver, FontEventListener listener, boolean strict) {
+ this.cfg = cfg;
+ this.fontManager = fontManager;
+ this.fontResolver = fontResolver;
+ this.listener = listener;
+ this.strict = strict;
+ }
+
+ /**
+ * Initializes font info settings from the user configuration
+ * @param fontInfoList a font info list
+ * @throws FOPException if an exception occurs while processing the configuration
+ */
+ public void configure(List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
+ FontCache fontCache = fontManager.getFontCache();
+ String fontBaseURL = fontManager.getFontBaseURL();
+
+ Configuration fonts = cfg.getChild("fonts", false);
+ if (fonts != null) {
+ long start = 0;
+ if (log.isDebugEnabled()) {
+ log.debug("Starting font configuration...");
+ start = System.currentTimeMillis();
+ }
+
+ FontAdder fontAdder = new FontAdder(fontManager, fontResolver, listener);
+
+ // native o/s search (autodetect) configuration
+ boolean autodetectFonts = (fonts.getChild("auto-detect", false) != null);
+ if (autodetectFonts) {
+ FontDetector fontDetector = new FontDetector(fontManager, fontAdder, strict);
+ fontDetector.detect(fontInfoList);
+ }
+
+ // Add configured directories to FontInfo
+ addDirectories(fonts, fontAdder, fontInfoList);
+
+ // Add configured fonts to FontInfo
+ addFonts(fonts, fontCache, fontInfoList);
+
+ // Update referenced fonts (fonts which are not to be embedded)
+ fontManager.updateReferencedFonts(fontInfoList);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Finished font configuration in "
+ + (System.currentTimeMillis() - start) + "ms");
+ }
+ }
+ }
+
+ private void addDirectories(Configuration fontsCfg,
+ FontAdder fontAdder, List/*<URL>*/ fontInfoList) throws FOPException {
+ // directory (multiple font) configuration
+ Configuration[] directories = fontsCfg.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;
+ }
+
+ // add fonts found in directory
+ FontFileFinder fontFileFinder = new FontFileFinder(recursive ? -1 : 1);
+ List/*<URL>*/ fontURLList;
+ try {
+ fontURLList = fontFileFinder.find(directory);
+ fontAdder.add(fontURLList, fontInfoList);
+ } catch (IOException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ }
+ }
+
+ /**
+ * Populates the font info list from the fonts configuration
+ * @param fontsCfg a fonts configuration
+ * @param fontCache a font cache
+ * @param fontInfoList a font info list
+ * @throws FOPException if an exception occurs while processing the configuration
+ */
+ protected void addFonts(Configuration fontsCfg, FontCache fontCache,
+ List/*<EmbedFontInfo>*/ fontInfoList) throws FOPException {
+ // font file (singular) configuration
+ Configuration[] font = fontsCfg.getChildren("font");
+ for (int i = 0; i < font.length; i++) {
+ EmbedFontInfo embedFontInfo = getFontInfo(
+ font[i], fontCache);
+ if (embedFontInfo != null) {
+ fontInfoList.add(embedFontInfo);
+ }
+ }
+ }
+
+ private static void closeSource(Source src) {
+ if (src instanceof StreamSource) {
+ StreamSource streamSource = (StreamSource)src;
+ IOUtils.closeQuietly(streamSource.getInputStream());
+ IOUtils.closeQuietly(streamSource.getReader());
+ }
+ }
+
+ /**
+ * Returns a font info from a font node Configuration definition
+ *
+ * @param fontCfg Configuration object (font node)
+ * @param fontCache the font cache (or null if it is disabled)
+ * @return the embedded font info
+ * @throws FOPException if something's wrong with the config data
+ */
+ protected EmbedFontInfo getFontInfo(
+ Configuration fontCfg, FontCache fontCache)
+ throws FOPException {
+ String metricsUrl = fontCfg.getAttribute("metrics-url", null);
+ String embedUrl = fontCfg.getAttribute("embed-url", null);
+ String subFont = fontCfg.getAttribute("sub-font", null);
+
+ if (metricsUrl == null && embedUrl == null) {
+ LogUtil.handleError(log,
+ "Font configuration without metric-url or embed-url attribute",
+ strict);
+ return null;
+ }
+ if (strict) {
+ //This section just checks early whether the URIs can be resolved
+ //Stream are immediately closed again since they will never be used anyway
+ if (embedUrl != null) {
+ Source source = fontResolver.resolve(embedUrl);
+ closeSource(source);
+ if (source == null) {
+ LogUtil.handleError(log,
+ "Failed to resolve font with embed-url '" + embedUrl + "'", strict);
+ return null;
+ }
+ }
+ if (metricsUrl != null) {
+ Source source = fontResolver.resolve(metricsUrl);
+ closeSource(source);
+ if (source == null) {
+ LogUtil.handleError(log,
+ "Failed to resolve font with metric-url '" + metricsUrl + "'", strict);
+ return null;
+ }
+ }
+ }
+
+ Configuration[] tripletCfg = fontCfg.getChildren("font-triplet");
+
+ // no font triplet info
+ if (tripletCfg.length == 0) {
+ LogUtil.handleError(log, "font without font-triplet", strict);
+
+ File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl});
+ URL fontUrl;
+ try {
+ fontUrl = fontFile.toURI().toURL();
+ } catch (MalformedURLException e) {
+ // Should never happen
+ log.debug("Malformed Url: " + e.getMessage());
+ return null;
+ }
+ if (fontFile != null) {
+ FontInfoFinder finder = new FontInfoFinder();
+ finder.setEventListener(listener);
+ EmbedFontInfo[] infos = finder.find(fontUrl, fontResolver, fontCache);
+ return infos[0]; //When subFont is set, only one font is returned
+ } else {
+ return null;
+ }
+ }
+
+ List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/();
+ for (int j = 0; j < tripletCfg.length; j++) {
+ FontTriplet fontTriplet = getFontTriplet(tripletCfg[j]);
+ tripletList.add(fontTriplet);
+ }
+
+ boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true);
+ EncodingMode encodingMode = EncodingMode.valueOf(
+ fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName()));
+ EmbedFontInfo embedFontInfo
+ = new EmbedFontInfo(metricsUrl, useKerning, tripletList, embedUrl, subFont);
+ embedFontInfo.setEncodingMode(encodingMode);
+ if (fontCache != null) {
+ if (!fontCache.containsFont(embedFontInfo)) {
+ fontCache.addFont(embedFontInfo);
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ String embedFile = embedFontInfo.getEmbedFile();
+ log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "")
+ + "metric file " + embedFontInfo.getMetricsFile());
+ for (int j = 0; j < tripletList.size(); ++j) {
+ FontTriplet triplet = (FontTriplet) tripletList.get(j);
+ log.debug(" Font triplet "
+ + triplet.getName() + ", "
+ + triplet.getStyle() + ", "
+ + triplet.getWeight());
+ }
+ }
+ return embedFontInfo;
+ }
+
+ /**
+ * Creates a new FontTriplet given a triple Configuration
+ *
+ * @param tripletCfg a triplet configuration
+ * @return a font triplet font key
+ * @throws FOPException thrown if a FOP exception occurs
+ */
+ private FontTriplet getFontTriplet(Configuration tripletCfg) throws FOPException {
+ try {
+ String name = tripletCfg.getAttribute("name");
+ if (name == null) {
+ LogUtil.handleError(log, "font-triplet without name", strict);
+ return null;
+ }
+
+ String weightStr = tripletCfg.getAttribute("weight");
+ if (weightStr == null) {
+ LogUtil.handleError(log, "font-triplet without weight", strict);
+ return null;
+ }
+ int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr));
+
+ String style = tripletCfg.getAttribute("style");
+ if (style == null) {
+ LogUtil.handleError(log, "font-triplet without style", strict);
+ return null;
+ } else {
+ style = FontUtil.stripWhiteSpace(style);
+ }
+ return FontInfo.createFontKey(name, style, weight);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ return null;
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/FontManager.java b/src/java/org/apache/fop/fonts/FontManager.java
index b3833cf50..daf0a0cdb 100644
--- a/src/java/org/apache/fop/fonts/FontManager.java
+++ b/src/java/org/apache/fop/fonts/FontManager.java
@@ -20,6 +20,8 @@
package org.apache.fop.fonts;
import java.net.MalformedURLException;
+import java.util.Iterator;
+import java.util.List;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
@@ -186,4 +188,27 @@ public class FontManager {
public Matcher getReferencedFontsMatcher() {
return this.referencedFontsMatcher;
}
+
+ /**
+ * Updates the referenced font list
+ * @param fontInfoList a font info list
+ */
+ public void updateReferencedFonts(List fontInfoList) {
+ Matcher matcher = getReferencedFontsMatcher();
+ if (matcher == null) {
+ return; //No referenced fonts
+ }
+ Iterator iter = fontInfoList.iterator();
+ while (iter.hasNext()) {
+ EmbedFontInfo fontInfo = (EmbedFontInfo)iter.next();
+ Iterator triplets = fontInfo.getFontTriplets().iterator();
+ while (triplets.hasNext()) {
+ FontTriplet triplet = (FontTriplet)triplets.next();
+ if (matcher.matches(triplet)) {
+ fontInfo.setEmbedded(false);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/src/java/org/apache/fop/render/AbstractConfigurator.java b/src/java/org/apache/fop/render/AbstractConfigurator.java
new file mode 100644
index 000000000..b1ac1c61a
--- /dev/null
+++ b/src/java/org/apache/fop/render/AbstractConfigurator.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+/**
+ * An abstract configurator
+ */
+public abstract class AbstractConfigurator {
+ /** logger instance */
+ protected static Log log = LogFactory.getLog(AbstractConfigurator.class);
+
+ private static final String MIME = "mime";
+
+ /** fop factory configuration */
+ protected FOUserAgent userAgent = null;
+
+ /**
+ * Default constructor
+ * @param userAgent user agent
+ */
+ public AbstractConfigurator(FOUserAgent userAgent) {
+ super();
+ this.userAgent = userAgent;
+ }
+
+ /**
+ * Returns the configuration subtree for a specific renderer.
+ * @param mimeType the MIME type of the renderer
+ * @return the requested configuration subtree, null if there's no configuration
+ */
+ protected Configuration getConfig(String mimeType) {
+ Configuration cfg = userAgent.getFactory().getUserConfig();
+ if (cfg == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("userconfig is null");
+ }
+ return null;
+ }
+
+ Configuration userConfig = null;
+
+ String type = getType();
+ Configuration[] cfgs
+ = cfg.getChild(type + "s").getChildren(type);
+ for (int i = 0; i < cfgs.length; ++i) {
+ Configuration child = cfgs[i];
+ try {
+ if (child.getAttribute(MIME).equals(mimeType)) {
+ userConfig = child;
+ break;
+ }
+ } catch (ConfigurationException e) {
+ // silently pass over configurations without mime type
+ }
+ }
+ log.debug((userConfig == null ? "No u" : "U")
+ + "ser configuration found for MIME type " + mimeType);
+ return userConfig;
+ }
+
+ /**
+ * Returns the configurator type
+ * @return the configurator type
+ */
+ public abstract String getType();
+}
diff --git a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
index 09540dfbb..b31e5bfe6 100644
--- a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
@@ -20,31 +20,22 @@
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;
+public abstract class AbstractRendererConfigurator extends AbstractConfigurator {
+ private static final String TYPE = "renderer";
+
/**
* Default constructor
* @param userAgent user agent
*/
public AbstractRendererConfigurator(FOUserAgent userAgent) {
- super();
- this.userAgent = userAgent;
+ super(userAgent);
}
/**
@@ -53,15 +44,7 @@ public abstract class AbstractRendererConfigurator {
* @return the requested configuration subtree, null if there's no configuration
*/
protected Configuration getRendererConfig(Renderer renderer) {
- String mimeType = renderer.getMimeType();
- if (mimeType == null) {
- if (log.isInfoEnabled()) {
- log.info("renderer mimeType is null");
- }
- return null;
- }
-
- return getRendererConfig(mimeType);
+ return super.getConfig(renderer.getMimeType());
}
/**
@@ -70,31 +53,14 @@ public abstract class AbstractRendererConfigurator {
* @return the requested configuration subtree, null if there's no configuration
*/
protected Configuration getRendererConfig(String mimeType) {
- Configuration cfg = userAgent.getFactory().getUserConfig();
- if (cfg == null) {
- if (log.isDebugEnabled()) {
- log.debug("userconfig 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;
+ return super.getConfig(mimeType);
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getType() {
+ return TYPE;
+ }
+
}
diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
index 3f5a2eb39..26c34585e 100644
--- a/src/java/org/apache/fop/render/PrintRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
@@ -19,42 +19,24 @@
package org.apache.fop.render;
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Iterator;
import java.util.List;
-import javax.xml.transform.Source;
-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.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.xmlgraphics.util.ClasspathResource;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.fonts.CustomFontCollection;
-import org.apache.fop.fonts.EmbedFontInfo;
-import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontCache;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontEventAdapter;
import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontInfoConfigurator;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontResolver;
-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.fonts.base14.Base14FontCollection;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
@@ -96,7 +78,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
FontEventListener listener = new FontEventAdapter(
renderer.getUserAgent().getEventBroadcaster());
- List embedFontInfoList = buildFontList(cfg, fontResolver, listener);
+ List/*<EmbedFontInfo>*/ embedFontInfoList = buildFontList(cfg, fontResolver, listener);
printRenderer.addFontList(embedFontInfoList);
}
@@ -108,7 +90,7 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
* @return the list of {@code EmbedFontInfo} objects
* @throws FOPException if an error occurs while processing the configuration
*/
- protected List buildFontList(Configuration cfg, FontResolver fontResolver,
+ protected List/*<EmbedFontInfo>*/ buildFontList(Configuration cfg, FontResolver fontResolver,
FontEventListener listener) throws FOPException {
FopFactory factory = userAgent.getFactory();
FontManager fontManager = factory.getFontManager();
@@ -120,344 +102,18 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
boolean strict = factory.validateUserConfigStrictly();
FontCache fontCache = fontManager.getFontCache();
- List/*<EmbedFontInfo>*/ embedFontInfoList = buildFontListFromConfiguration(cfg,
- fontResolver, strict, fontManager, listener);
+ //Read font configuration
+ FontInfoConfigurator fontInfoConfigurator
+ = new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict);
+ List/*<EmbedFontInfo>*/ fontInfoList = new java.util.ArrayList/*<EmbedFontInfo>*/();
+ fontInfoConfigurator.configure(fontInfoList);
if (fontCache != null && fontCache.hasChanged()) {
fontCache.save();
}
- return embedFontInfoList;
- }
-
- /**
- * Builds a list of EmbedFontInfo objects for use with the setup() method.
- *
- * @param cfg Configuration object
- * @param fontResolver the FontResolver to use
- * @param strict true if an Exception should be thrown if an error is found.
- * @param fontManager the font manager
- * @param listener a font event listener
- * @return a List of EmbedFontInfo objects.
- * @throws FOPException If an error occurs while processing the configuration
- */
- public static List/*<EmbedFontInfo>*/ buildFontListFromConfiguration(Configuration cfg,
- FontResolver fontResolver,
- boolean strict, FontManager fontManager,
- FontEventListener listener) throws FOPException {
- FontCache fontCache = fontManager.getFontCache();
- String fontBaseURL = fontManager.getFontBaseURL();
- List/*<EmbedFontInfo>*/ fontInfoList
- = new java.util.ArrayList/*<EmbedFontInfo>*/();
-
- Configuration fonts = cfg.getChild("fonts", false);
- 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 (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,
- listener
- );
- }
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- }
- }
-
- // native o/s font directory finder
- try {
- addFontInfoListFromFileList(
- fontFileFinder.find(),
- fontInfoList,
- fontResolver,
- fontCache,
- listener
- );
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- }
-
- // load fonts from classpath
- addFontInfoListFromFileList(ClasspathResource.getInstance()
- .listResourcesOfMimeType("application/x-font"),
- fontInfoList, fontResolver, fontCache, listener);
- addFontInfoListFromFileList(
- ClasspathResource.getInstance()
- .listResourcesOfMimeType(
- "application/x-font-truetype"),
- fontInfoList, fontResolver, fontCache, listener);
- }
-
- // 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,
- listener
- );
- } 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 embedFontInfo = getFontInfoFromConfiguration(
- font[i], fontResolver, strict, fontCache, listener);
- if (embedFontInfo != null) {
- fontInfoList.add(embedFontInfo);
- }
- }
-
- // Update referenced fonts (fonts which are not to be embedded)
- updateReferencedFonts(fontInfoList, fontManager.getReferencedFontsMatcher());
-
- if (log.isDebugEnabled()) {
- log.debug("Finished font configuration in "
- + (System.currentTimeMillis() - start) + "ms");
- }
- }
return fontInfoList;
}
-
- private static void updateReferencedFonts(List fontInfoList, FontTriplet.Matcher matcher) {
- if (matcher == null) {
- return; //No referenced fonts
- }
- Iterator iter = fontInfoList.iterator();
- while (iter.hasNext()) {
- EmbedFontInfo fontInfo = (EmbedFontInfo)iter.next();
- Iterator triplets = fontInfo.getFontTriplets().iterator();
- while (triplets.hasNext()) {
- FontTriplet triplet = (FontTriplet)triplets.next();
- if (matcher.matches(triplet)) {
- fontInfo.setEmbedded(false);
- break;
- }
- }
- }
- }
-
-
- /**
- * Iterates over font file list adding font info to list
- * @param fontFileList font file list
- * @param embedFontInfoList a configured font info list
- * @param resolver font resolver
- */
- private static void addFontInfoListFromFileList(
- List fontFileList, List/*<EmbedFontInfo>*/ embedFontInfoList,
- FontResolver resolver, FontCache fontCache, FontEventListener listener) {
- for (Iterator iter = fontFileList.iterator(); iter.hasNext();) {
- URL fontUrl = (URL)iter.next();
- // parse font to ascertain font info
- FontInfoFinder finder = new FontInfoFinder();
- finder.setEventListener(listener);
- //EmbedFontInfo fontInfo = finder.find(fontUrl, resolver, fontCache);
-
- //List<EmbedFontInfo> embedFontInfoList = finder.find(fontUrl, resolver, fontCache);
- EmbedFontInfo[] embedFontInfos = finder.find(fontUrl, resolver, fontCache);
-
- if (embedFontInfos == null) {
- continue;
- }
-
- for (int i = 0, c = embedFontInfos.length; i < c; i++) {
- EmbedFontInfo fontInfo = embedFontInfos[i];
- if (fontInfo != null) {
- embedFontInfoList.add(fontInfo);
- }
- }
- }
- }
-
- private static void closeSource(Source src) {
- if (src instanceof StreamSource) {
- StreamSource streamSource = (StreamSource)src;
- IOUtils.closeQuietly(streamSource.getInputStream());
- IOUtils.closeQuietly(streamSource.getReader());
- }
- }
-
- /**
- * Creates a new FontTriplet given a triple Configuration
- *
- * @param tripletCfg a triplet configuration
- * @param strict use strict validation
- * @return a font triplet font key
- * @throws FOPException thrown if a FOP exception occurs
- */
- private static FontTriplet getFontTripletFromConfiguration(
- Configuration tripletCfg, boolean strict) throws FOPException {
- try {
- String name = tripletCfg.getAttribute("name");
- if (name == null) {
- LogUtil.handleError(log, "font-triplet without name", strict);
- return null;
- }
-
- String weightStr = tripletCfg.getAttribute("weight");
- if (weightStr == null) {
- LogUtil.handleError(log, "font-triplet without weight", strict);
- return null;
- }
- int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr));
-
- String style = tripletCfg.getAttribute("style");
- if (style == null) {
- LogUtil.handleError(log, "font-triplet without style", strict);
- return null;
- } else {
- style = FontUtil.stripWhiteSpace(style);
- }
- return FontInfo.createFontKey(name, style, weight);
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- }
- return null;
- }
-
- /**
- * 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 the embedded font info
- * @throws FOPException if something's wrong with the config data
- */
- private static EmbedFontInfo getFontInfoFromConfiguration(
- Configuration fontCfg, FontResolver fontResolver, boolean strict,
- FontCache fontCache, FontEventListener listener)
- throws FOPException {
- String metricsUrl = fontCfg.getAttribute("metrics-url", null);
- String embedUrl = fontCfg.getAttribute("embed-url", null);
- String subFont = fontCfg.getAttribute("sub-font", null);
-
- if (metricsUrl == null && embedUrl == null) {
- LogUtil.handleError(log,
- "Font configuration without metric-url or embed-url attribute",
- strict);
- return null;
- }
- if (strict) {
- //This section just checks early whether the URIs can be resolved
- //Stream are immediately closed again since they will never be used anyway
- if (embedUrl != null) {
- Source source = fontResolver.resolve(embedUrl);
- closeSource(source);
- if (source == null) {
- LogUtil.handleError(log,
- "Failed to resolve font with embed-url '" + embedUrl + "'", strict);
- return null;
- }
- }
- if (metricsUrl != null) {
- Source source = fontResolver.resolve(metricsUrl);
- closeSource(source);
- if (source == null) {
- LogUtil.handleError(log,
- "Failed to resolve font with metric-url '" + metricsUrl + "'", strict);
- return null;
- }
- }
- }
-
- Configuration[] tripletCfg = fontCfg.getChildren("font-triplet");
-
- // no font triplet info
- if (tripletCfg.length == 0) {
- LogUtil.handleError(log, "font without font-triplet", strict);
-
- File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl});
- URL fontUrl;
- try {
- fontUrl = fontFile.toURI().toURL();
- } catch (MalformedURLException e) {
- // Should never happen
- log.debug("Malformed Url: " + e.getMessage());
- return null;
- }
- if (fontFile != null) {
- FontInfoFinder finder = new FontInfoFinder();
- finder.setEventListener(listener);
- EmbedFontInfo[] infos = finder.find(fontUrl, fontResolver, fontCache);
- return infos[0]; //When subFont is set, only one font is returned
- } else {
- return null;
- }
- }
-
- List/*<FontTriplet>*/ tripletList = new java.util.ArrayList/*<FontTriplet>*/();
- for (int j = 0; j < tripletCfg.length; j++) {
- FontTriplet fontTriplet = getFontTripletFromConfiguration(tripletCfg[j], strict);
- tripletList.add(fontTriplet);
- }
-
- boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true);
- EncodingMode encodingMode = EncodingMode.valueOf(
- fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName()));
- EmbedFontInfo embedFontInfo
- = new EmbedFontInfo(metricsUrl, useKerning, tripletList, embedUrl, subFont);
- embedFontInfo.setEncodingMode(encodingMode);
- if (fontCache != null) {
- if (!fontCache.containsFont(embedFontInfo)) {
- fontCache.addFont(embedFontInfo);
- }
- }
-
- if (log.isDebugEnabled()) {
- String embedFile = embedFontInfo.getEmbedFile();
- log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "")
- + "metric file " + embedFontInfo.getMetricsFile());
- for (int j = 0; j < tripletList.size(); ++j) {
- FontTriplet triplet = (FontTriplet) tripletList.get(j);
- log.debug(" Font triplet "
- + triplet.getName() + ", "
- + triplet.getStyle() + ", "
- + triplet.getWeight());
- }
- }
- return embedFontInfo;
- }
-
+
// ---=== IFDocumentHandler configuration ===---
/** {@inheritDoc} */
@@ -486,5 +142,4 @@ public class PrintRendererConfigurator extends AbstractRendererConfigurator
new FontCollection[fontCollections.size()]));
documentHandler.setFontInfo(fontInfo);
}
-
}
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
index 03ad4ee71..e101a9573 100644
--- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
+++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
@@ -25,12 +25,13 @@ 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.FontEventListener;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontInfoConfigurator;
import org.apache.fop.fonts.FontManager;
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;
/**
@@ -61,15 +62,19 @@ public class PDFDocumentGraphics2DConfigurator {
//TODO Make use of fontBaseURL, font substitution and referencing configuration
//Requires a change to the expected configuration layout
- List/*<EmbedFontInfo>*/ embedFontInfoList
- = PrintRendererConfigurator.buildFontListFromConfiguration(
- cfg, fontResolver, false, fontManager, null);
//TODO Wire in the FontEventListener
+ final FontEventListener listener = null;
+ final boolean strict = false;
+ FontInfoConfigurator fontInfoConfigurator
+ = new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict);
+ List/*<EmbedFontInfo>*/ fontInfoList = new java.util.ArrayList/*<EmbedFontInfo>*/();
+ fontInfoConfigurator.configure(fontInfoList);
+
if (fontManager.useCache()) {
fontManager.getFontCache().save();
}
FontInfo fontInfo = new FontInfo();
- FontSetup.setup(fontInfo, embedFontInfoList, fontResolver);
+ FontSetup.setup(fontInfo, fontInfoList, fontResolver);
graphics.setFontInfo(fontInfo);
} catch (FOPException e) {
throw new ConfigurationException("Error while setting up fonts", e);