aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
authorSimon Pepping <spepping@apache.org>2007-09-25 09:00:20 +0000
committerSimon Pepping <spepping@apache.org>2007-09-25 09:00:20 +0000
commit51efe0f61308aa92bc793a2d6dd278acf6d98ea5 (patch)
tree2d52913a4b8e8ca278da445800702ad68a8c2a7f /src/java/org/apache/fop
parentb341ca9c88c187c04f142408fb3156757d8b6f24 (diff)
downloadxmlgraphics-fop-51efe0f61308aa92bc793a2d6dd278acf6d98ea5.tar.gz
xmlgraphics-fop-51efe0f61308aa92bc793a2d6dd278acf6d98ea5.zip
Merged revisions 540001-550000 via svnmerge from
https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk ........ r540036 | jeremias | 2007-05-21 08:17:48 +0200 (Mon, 21 May 2007) | 3 lines Bugzilla #42067: Fixed a possible StringIndexOutOfBoundsException. Submitted by: Paul Vinkenoog <paul.at.vinkenoog.nl> ........ r540042 | jeremias | 2007-05-21 08:57:03 +0200 (Mon, 21 May 2007) | 1 line PFMFile is now also used inside FOP's normal operations, so don't log too much in "info" level. ........ r540049 | jeremias | 2007-05-21 09:32:46 +0200 (Mon, 21 May 2007) | 3 lines Bugzilla #42109: Fixed the rendering of zero-width spaces for certain fonts by not generating them into the area tree. Submitted by: Paul Vinkenoog <paul.at.vinkenoog.nl> ........ r540052 | jeremias | 2007-05-21 09:59:05 +0200 (Mon, 21 May 2007) | 3 lines Bugzilla #42406: Use source resolution setting for bitmap images which don't provide their own resolution. Submitted by: Hussein Shafie <hussein.at.xmlmind.com> ........ r541628 | jeremias | 2007-05-25 14:52:22 +0200 (Fri, 25 May 2007) | 1 line Checkstyle only. ........ r542036 | jeremias | 2007-05-27 23:03:22 +0200 (Sun, 27 May 2007) | 1 line One Factory per VM is enough here. ........ r542237 | jeremias | 2007-05-28 16:31:24 +0200 (Mon, 28 May 2007) | 16 lines Bugzilla #41831: - Add support font auto-detection (easier font configuration) including a font cache to speed up the auto-detection process. - Refactoring of the configuration code: All Avalon configuration stuff is extracted into separate "Configurator" classes. - Refactoring of the FOURIResolver. Submitted by: Adrian Cumiskey <fop-dev.at.cumiskey.com> Changes to the patch by jeremias during the review: - Font cache simplified (Java object serialization instead of XML), functionality fixed and moved to the fonts.package. - Relocated default cache file location to user directory. - Fixed the font configuration for PDFDocumentGraphics2D/PDFTranscoder that got lost with the patch. - Fixed a problem with having a non-file URL as font base URL. - Simplified RendererContextInfo stuff to make it easier to understand. - Fixed handling of Type 1 fonts in auto-detection. - Reduced verbosity of font-related log output. - Updated Jakarta Commons IO to version 1.3.1 (the patch depends on it) - Various javadocs improvements ........ r542242 | jeremias | 2007-05-28 16:48:09 +0200 (Mon, 28 May 2007) | 1 line Discover the .otf font extension (OpenType fonts), too. ........ r542447 | vhennebert | 2007-05-29 09:51:52 +0200 (Tue, 29 May 2007) | 7 lines Bug #42476: - fix NPE in XMLReader when no handler is found for the image - prevent SVGReader from closing the input stream if the image actually isn't SVG - reduce log level in SVGReader and XMLReader to avoid "false positive" (read error reported whereas the image format actually isn't recognized). This may hide regular I/O errors to the end-user, but I assume this will be rare enough compared to the annoyance of such messages when third-party plugins are used. Patch submitted by Max Berger (max.at.berger.name) ........ r544748 | vhennebert | 2007-06-06 09:22:04 +0200 (Wed, 06 Jun 2007) | 2 lines Add Max Berger to the list of FOP's active contributors. Many thanks to Max for his contributions so far! ........ r544758 | vhennebert | 2007-06-06 09:37:52 +0200 (Wed, 06 Jun 2007) | 3 lines Add Adrian Cumiskey to the list of FOP's active contributors. Many thanks to Adrian for his contributions so far! Patch provided by Adrian himself ;-) ........ r545224 | clay | 2007-06-07 17:57:47 +0200 (Thu, 07 Jun 2007) | 1 line Updates to promote FOP 0.93 over 0.20.5 ........ r545589 | spepping | 2007-06-08 20:47:44 +0200 (Fri, 08 Jun 2007) | 2 lines Apply a similar change to the page of the trunk as to that of the 0.93 release ........ r547550 | jeremias | 2007-06-15 08:49:40 +0200 (Fri, 15 Jun 2007) | 2 lines Add JEuclid as it now provides its own FOP extension. Correct Barcode4J's URL. ........ r547553 | jeremias | 2007-06-15 08:55:02 +0200 (Fri, 15 Jun 2007) | 1 line Add Assentis:DocDesign (an FO editor) ........ r547971 | pietsch | 2007-06-16 21:59:30 +0200 (Sat, 16 Jun 2007) | 1 line remove deprecated style task ........ r547979 | pietsch | 2007-06-16 22:48:24 +0200 (Sat, 16 Jun 2007) | 1 line removed hyphenation advice from basic example ........ r548105 | pietsch | 2007-06-17 22:39:55 +0200 (Sun, 17 Jun 2007) | 1 line corrected some misspellings and other potential annoyances in example ........ r548619 | vhennebert | 2007-06-19 09:08:33 +0200 (Tue, 19 Jun 2007) | 2 lines Move Glen Mazza to the list of inactive committers, as per his own request. While I'm at it, replace his column with mine in "Areas of Expertise". ........ r549767 | cbowditch | 2007-06-22 12:26:39 +0200 (Fri, 22 Jun 2007) | 3 lines Bugzilla #42576 Fix bug in force-page-count Submitted by Adrian Cumiskey <dev.at.cumiskey.com> ........ r549816 | jeremias | 2007-06-22 15:34:37 +0200 (Fri, 22 Jun 2007) | 4 lines Updated PDF/A-1b support according to ISO-19005-1:2005/Cor.1:2007. Changed test.xconf to match the triplet generated by auto-font-detection (Gladiator is bold) and adjusted PDF/A test files accordingly. Updated XML Graphics Commons to latest snapshot to include the PDF/A fixes. Added a unit test for the synchronization of PDF Info and XMP metadata as described in PDF/A-1. ........ r549827 | jeremias | 2007-06-22 16:23:30 +0200 (Fri, 22 Jun 2007) | 1 line A note on the PDF/A namespace confusion. ........ git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking@579136 13f79535-47bb-0310-9956-ffa450edef68
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/area/Trait.java3
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java6
-rw-r--r--src/java/org/apache/fop/fo/pagination/PageSequence.java2
-rw-r--r--src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java8
-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.java37
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java157
-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/PFMFile.java4
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java23
-rw-r--r--src/java/org/apache/fop/image/analyser/BMPReader.java12
-rw-r--r--src/java/org/apache/fop/image/analyser/GIFReader.java10
-rw-r--r--src/java/org/apache/fop/image/analyser/ImageReaderFactory.java2
-rw-r--r--src/java/org/apache/fop/image/analyser/JPEGReader.java15
-rw-r--r--src/java/org/apache/fop/image/analyser/PNGReader.java11
-rw-r--r--src/java/org/apache/fop/image/analyser/SVGReader.java58
-rw-r--r--src/java/org/apache/fop/image/analyser/TIFFReader.java27
-rw-r--r--src/java/org/apache/fop/image/analyser/XMLReader.java19
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java33
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java7
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java11
-rw-r--r--src/java/org/apache/fop/pdf/PDFFilterList.java64
-rw-r--r--src/java/org/apache/fop/pdf/PDFMetadata.java30
-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/CharUtilities.java20
-rw-r--r--src/java/org/apache/fop/util/LogUtil.java57
-rw-r--r--src/java/org/apache/fop/util/UnclosableInputStream.java46
92 files changed, 3715 insertions, 1474 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/area/Trait.java b/src/java/org/apache/fop/area/Trait.java
index 32582dec1..fb7065e77 100644
--- a/src/java/org/apache/fop/area/Trait.java
+++ b/src/java/org/apache/fop/area/Trait.java
@@ -520,7 +520,8 @@ public class Trait implements Serializable {
String[] result = {null, null};
if (attrValue != null) {
int len = attrValue.length();
- if (len >= 2 && attrValue.charAt(0) == '(' && attrValue.charAt(len - 1) == ')') {
+ if (len >= 2 && attrValue.charAt(0) == '(' && attrValue.charAt(len - 1) == ')'
+ && attrValue.indexOf(',') != -1) {
String value = attrValue.substring(1, len - 1); // remove brackets
int delimIndex = value.indexOf(',');
result[0] = value.substring(0, delimIndex).trim(); // PV key
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/fo/pagination/PageSequence.java b/src/java/org/apache/fop/fo/pagination/PageSequence.java
index 1e8f1f52b..b61d3b8b7 100644
--- a/src/java/org/apache/fop/fo/pagination/PageSequence.java
+++ b/src/java/org/apache/fop/fo/pagination/PageSequence.java
@@ -127,8 +127,6 @@ public class PageSequence extends FObj {
throw new ValidationException("master-reference '" + masterReference
+ "' for fo:page-sequence matches no"
+ " simple-page-master or page-sequence-master", locator);
- } else {
- pageSequenceMaster.reset();
}
}
diff --git a/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java b/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
index e48d0dc64..fc12205b7 100644
--- a/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
+++ b/src/java/org/apache/fop/fo/pagination/PageSequenceMaster.java
@@ -43,7 +43,7 @@ public class PageSequenceMaster extends FObj {
private LayoutMasterSet layoutMasterSet;
private List subSequenceSpecifiers;
private SubSequenceSpecifier currentSubSequence;
- private int currentSubSequenceNumber;
+ private int currentSubSequenceNumber = -1;
// The terminology may be confusing. A 'page-sequence-master' consists
// of a sequence of what the XSL spec refers to as
@@ -135,8 +135,10 @@ public class PageSequenceMaster extends FObj {
public void reset() {
currentSubSequenceNumber = -1;
currentSubSequence = null;
- for (int i = 0; i < subSequenceSpecifiers.size(); i++) {
- ((SubSequenceSpecifier)subSequenceSpecifiers.get(i)).reset();
+ if (subSequenceSpecifiers != null) {
+ for (int i = 0; i < subSequenceSpecifiers.size(); i++) {
+ ((SubSequenceSpecifier)subSequenceSpecifiers.get(i)).reset();
+ }
}
}
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 95251d060..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;
@@ -44,6 +45,7 @@ public class TTFReader extends AbstractFontReader {
/** Used to detect incompatible versions of the generated XML files */
public static final String METRICS_VERSION_ATTR = "metrics-version";
+ /** Current version number for the metrics file */
public static final int METRICS_VERSION = 2;
/**
@@ -243,7 +245,7 @@ public class TTFReader extends AbstractFontReader {
}
Element root = doc.createElement("font-metrics");
doc.appendChild(root);
- root.setAttribute(METRICS_VERSION_ATTR,String.valueOf(METRICS_VERSION));
+ root.setAttribute(METRICS_VERSION_ATTR, String.valueOf(METRICS_VERSION));
if (isCid) {
root.setAttribute("type", "TYPE0");
} else {
@@ -257,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));
}
@@ -449,49 +451,34 @@ 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.
+ /**
+ * Bugzilla 40739, check that attr has a metrics-version attribute
+ * compatible with ours.
* @param attr attributes read from the root element of a metrics XML file
* @throws SAXException if incompatible
*/
public static void checkMetricsVersion(Attributes attr) throws SAXException {
String err = null;
final String str = attr.getValue(METRICS_VERSION_ATTR);
- if(str==null) {
+ if (str == null) {
err = "Missing " + METRICS_VERSION_ATTR + " attribute";
} else {
int version = 0;
try {
version = Integer.parseInt(str);
- if(version < METRICS_VERSION) {
+ if (version < METRICS_VERSION) {
err = "Incompatible " + METRICS_VERSION_ATTR
+ " value (" + version + ", should be " + METRICS_VERSION
+ ")"
;
}
- } catch(NumberFormatException e) {
+ } catch (NumberFormatException e) {
err = "Invalid " + METRICS_VERSION_ATTR
+ " attribute value (" + str + ")";
}
}
- if(err!=null) {
+ if (err != null) {
throw new SAXException(
err
+ " - please regenerate the font metrics file with "
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..246fd2aed
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
@@ -0,0 +1,157 @@
+/*
+ * 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.io.filefilter.SuffixFileFilter;
+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(),
+ new SuffixFileFilter(new String[] {".ttf", ".otf", ".pfb"})
+ //TODO Add *.ttc when support for it has been added to the auto-detection mech.
+ );
+ }
+
+ /**
+ * @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/PFMFile.java b/src/java/org/apache/fop/fonts/type1/PFMFile.java
index ed9c9eeb0..4dc7b88c3 100644
--- a/src/java/org/apache/fop/fonts/type1/PFMFile.java
+++ b/src/java/org/apache/fop/fonts/type1/PFMFile.java
@@ -190,8 +190,8 @@ public class PFMFile {
int i = inStream.readShort();
- if (log.isInfoEnabled()) {
- log.info(i + " kerning pairs");
+ if (log.isDebugEnabled()) {
+ log.debug(i + " kerning pairs");
}
while (i > 0) {
int g1 = (int)inStream.readByte();
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/image/analyser/BMPReader.java b/src/java/org/apache/fop/image/analyser/BMPReader.java
index 7dfb29dc7..a4f401462 100644
--- a/src/java/org/apache/fop/image/analyser/BMPReader.java
+++ b/src/java/org/apache/fop/image/analyser/BMPReader.java
@@ -54,7 +54,11 @@ public class BMPReader implements ImageReader {
boolean supported = ((header[0] == (byte) 0x42)
&& (header[1] == (byte) 0x4d));
if (supported) {
- FopImage.ImageInfo info = getDimension(header);
+ FopImage.ImageInfo info = new FopImage.ImageInfo();
+ info.dpiHorizontal = ua.getFactory().getSourceResolution();
+ info.dpiVertical = info.dpiHorizontal;
+
+ getDimension(header, info);
info.originalURI = uri;
info.mimeType = getMimeType();
info.inputStream = bis;
@@ -73,9 +77,7 @@ public class BMPReader implements ImageReader {
return "image/bmp";
}
- private FopImage.ImageInfo getDimension(byte[] header) {
- FopImage.ImageInfo info = new FopImage.ImageInfo();
-
+ private void getDimension(byte[] header, FopImage.ImageInfo info) {
// little endian notation
int byte1 = header[WIDTH_OFFSET] & 0xff;
int byte2 = header[WIDTH_OFFSET + 1] & 0xff;
@@ -109,8 +111,6 @@ public class BMPReader implements ImageReader {
if (l > 0) {
info.dpiVertical = l / 39.37d;
}
-
- return info;
}
private byte[] getDefaultHeader(InputStream imageStream)
diff --git a/src/java/org/apache/fop/image/analyser/GIFReader.java b/src/java/org/apache/fop/image/analyser/GIFReader.java
index 74e528481..206947f88 100644
--- a/src/java/org/apache/fop/image/analyser/GIFReader.java
+++ b/src/java/org/apache/fop/image/analyser/GIFReader.java
@@ -48,7 +48,11 @@ public class GIFReader implements ImageReader {
&& (header[4] == '7' || header[4] == '9')
&& (header[5] == 'a'));
if (supported) {
- FopImage.ImageInfo info = getDimension(header);
+ FopImage.ImageInfo info = new FopImage.ImageInfo();
+ info.dpiHorizontal = ua.getFactory().getSourceResolution();
+ info.dpiVertical = info.dpiHorizontal;
+
+ getDimension(header, info);
info.originalURI = uri;
info.mimeType = getMimeType();
info.inputStream = bis;
@@ -67,8 +71,7 @@ public class GIFReader implements ImageReader {
return "image/gif";
}
- private FopImage.ImageInfo getDimension(byte[] header) {
- FopImage.ImageInfo info = new FopImage.ImageInfo();
+ private void getDimension(byte[] header, FopImage.ImageInfo info) {
// little endian notation
int byte1 = header[6] & 0xff;
int byte2 = header[7] & 0xff;
@@ -77,7 +80,6 @@ public class GIFReader implements ImageReader {
byte1 = header[8] & 0xff;
byte2 = header[9] & 0xff;
info.height = ((byte2 << 8) | byte1) & 0xffff;
- return info;
}
private byte[] getDefaultHeader(InputStream imageStream)
diff --git a/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java b/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java
index 4e4c4bce7..b9621474f 100644
--- a/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java
+++ b/src/java/org/apache/fop/image/analyser/ImageReaderFactory.java
@@ -87,6 +87,8 @@ public class ImageReaderFactory {
return info;
}
}
+ log.warn("No ImageReader found for " + uri);
+ in.close();
} catch (IOException ex) {
log.error("Error while recovering Image Informations ("
+ uri + ")", ex);
diff --git a/src/java/org/apache/fop/image/analyser/JPEGReader.java b/src/java/org/apache/fop/image/analyser/JPEGReader.java
index 1cb1d9212..bfa7d78d8 100644
--- a/src/java/org/apache/fop/image/analyser/JPEGReader.java
+++ b/src/java/org/apache/fop/image/analyser/JPEGReader.java
@@ -61,7 +61,11 @@ public class JPEGReader implements ImageReader {
boolean supported = ((header[0] == (byte) 0xff)
&& (header[1] == (byte) 0xd8));
if (supported) {
- FopImage.ImageInfo info = getDimension(fis);
+ FopImage.ImageInfo info = new FopImage.ImageInfo();
+ info.dpiHorizontal = ua.getFactory().getSourceResolution();
+ info.dpiVertical = info.dpiHorizontal;
+
+ getDimension(fis, info);
info.originalURI = uri;
info.mimeType = getMimeType();
info.inputStream = fis;
@@ -97,8 +101,9 @@ public class JPEGReader implements ImageReader {
return header;
}
- private FopImage.ImageInfo getDimension(InputStream imageStream) throws IOException {
- FopImage.ImageInfo info = new FopImage.ImageInfo();
+ private void getDimension(InputStream imageStream,
+ FopImage.ImageInfo info)
+ throws IOException {
try {
int pos=0, avail = imageStream.available();
imageStream.mark(avail);
@@ -163,7 +168,8 @@ outer:
info.dpiHorizontal = xdensity;
info.dpiVertical = ydensity;
} else {
- //nop, nyi --> 72dpi
+ // Use resolution specified in
+ // FOUserAgent.getFactory() (default 72dpi).
}
int restlen = reclen - 12;
@@ -237,7 +243,6 @@ outer:
}
throw ioe;
}
- return info;
}
private int read2bytes(InputStream imageStream) throws IOException {
diff --git a/src/java/org/apache/fop/image/analyser/PNGReader.java b/src/java/org/apache/fop/image/analyser/PNGReader.java
index ab2c6bff3..1c46f8d6e 100644
--- a/src/java/org/apache/fop/image/analyser/PNGReader.java
+++ b/src/java/org/apache/fop/image/analyser/PNGReader.java
@@ -51,7 +51,11 @@ public class PNGReader implements ImageReader {
&& (header[7] == (byte) 0x0a));
if (supported) {
- FopImage.ImageInfo info = getDimension(header);
+ FopImage.ImageInfo info = new FopImage.ImageInfo();
+ info.dpiHorizontal = ua.getFactory().getSourceResolution();
+ info.dpiVertical = info.dpiHorizontal;
+
+ getDimension(header, info);
info.originalURI = uri;
info.mimeType = getMimeType();
info.inputStream = bis;
@@ -70,9 +74,7 @@ public class PNGReader implements ImageReader {
return "image/png";
}
- private FopImage.ImageInfo getDimension(byte[] header) {
- FopImage.ImageInfo info = new FopImage.ImageInfo();
-
+ private void getDimension(byte[] header, FopImage.ImageInfo info) {
// png is always big endian
int byte1 = header[16] & 0xff;
int byte2 = header[17] & 0xff;
@@ -90,7 +92,6 @@ public class PNGReader implements ImageReader {
byte4 = header[23] & 0xff;
l = (long) ((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4);
info.height = (int) l;
- return info;
}
private byte[] getDefaultHeader(InputStream imageStream)
diff --git a/src/java/org/apache/fop/image/analyser/SVGReader.java b/src/java/org/apache/fop/image/analyser/SVGReader.java
index b487572a5..da702d0c1 100644
--- a/src/java/org/apache/fop/image/analyser/SVGReader.java
+++ b/src/java/org/apache/fop/image/analyser/SVGReader.java
@@ -43,6 +43,7 @@ import org.apache.fop.image.XMLImage;
import org.apache.fop.image.FopImage;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.util.UnclosableInputStream;
/**
* ImageReader object for SVG document image type.
@@ -112,58 +113,7 @@ public class SVGReader implements ImageReader {
// parse document and get the size attributes of the svg element
try {
- int length = 5;
- fis.mark(length);
- byte[] b = new byte[length];
- fis.read(b);
- String start = new String(b);
- fis.reset();
-
- //TODO "true ||" here is a hack to improve SVG detection rate. Please improve.
- if (true || start.equals("<?xml")) {
- // we have xml, might be another doc
- // so stop batik from closing the stream
- final InputStream input = fis;
- fis =
- new InputStream() {
- public int read() throws IOException {
- return input.read();
- }
-
- public int read(byte[] b) throws IOException {
- return input.read(b);
- }
-
- public int read(byte[] b, int off, int len)
- throws IOException {
- return input.read(b, off, len);
- }
-
- public long skip(long n) throws IOException {
- return input.skip(n);
- }
-
- public int available() throws IOException {
- return input.available();
- }
-
- public void mark(int rl) {
- input.mark(rl);
- }
-
- public boolean markSupported() {
- return input.markSupported();
- }
-
- public void reset() throws IOException {
- input.reset();
- }
-
- public void close() throws IOException {
- //ignore
- }
- };
- }
+ fis = new UnclosableInputStream(fis);
FopImage.ImageInfo info = new FopImage.ImageInfo();
@@ -175,7 +125,7 @@ public class SVGReader implements ImageReader {
info.mimeType = getMimeType();
info.str = SVGDOMImplementation.SVG_NAMESPACE_URI;
- length = fis.available();
+ int length = fis.available();
fis.mark(length + 1);
SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(
XMLImage.getParserName());
@@ -217,7 +167,7 @@ public class SVGReader implements ImageReader {
batik = false;
log.warn("Batik not in class path", ncdfe);
return null;
- } catch (Exception e) {
+ } catch (IOException e) {
// If the svg is invalid then it throws an IOException
// so there is no way of knowing if it is an svg document
diff --git a/src/java/org/apache/fop/image/analyser/TIFFReader.java b/src/java/org/apache/fop/image/analyser/TIFFReader.java
index 049e154a0..a70a105d7 100644
--- a/src/java/org/apache/fop/image/analyser/TIFFReader.java
+++ b/src/java/org/apache/fop/image/analyser/TIFFReader.java
@@ -62,7 +62,11 @@ public class TIFFReader implements ImageReader {
}
if (supported) {
- FopImage.ImageInfo info = getDimension(header);
+ FopImage.ImageInfo info = new FopImage.ImageInfo();
+ info.dpiHorizontal = ua.getFactory().getSourceResolution();
+ info.dpiVertical = info.dpiHorizontal;
+
+ getDimension(header, info);
info.originalURI = uri;
info.mimeType = getMimeType();
info.inputStream = bis;
@@ -81,33 +85,14 @@ public class TIFFReader implements ImageReader {
return "image/tiff";
}
- private FopImage.ImageInfo getDimension(byte[] header) {
+ private void getDimension(byte[] header, FopImage.ImageInfo info) {
// currently not setting the width and height
// these are set again by the Jimi image reader.
// I suppose I'll do it one day to be complete. Or
// someone else will.
// Note: bytes 4,5,6,7 contain the byte offset in the stream of the first IFD block
- /*
- * //png is always big endian
- * int byte1 = header[ 16 ] & 0xff;
- * int byte2 = header[ 17 ] & 0xff;
- * int byte3 = header[ 18 ] & 0xff;
- * int byte4 = header[ 19 ] & 0xff;
- * long l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) |
- * ( byte3 << 8 ) | byte4 );
- * this.width = ( int ) ( l );
- * byte1 = header[ 20 ] & 0xff;
- * byte2 = header[ 21 ] & 0xff;
- * byte3 = header[ 22 ] & 0xff;
- * byte4 = header[ 23 ] & 0xff;
- * l = ( long ) ( ( byte1 << 24 ) | ( byte2 << 16 ) | ( byte3 << 8 ) |
- * byte4 );
- * this.height = ( int ) ( l );
- */
- FopImage.ImageInfo info = new FopImage.ImageInfo();
info.width = -1;
info.height = -1;
- return info;
}
private byte[] getDefaultHeader(InputStream imageStream)
diff --git a/src/java/org/apache/fop/image/analyser/XMLReader.java b/src/java/org/apache/fop/image/analyser/XMLReader.java
index 34d34ef4a..aa558c1e7 100644
--- a/src/java/org/apache/fop/image/analyser/XMLReader.java
+++ b/src/java/org/apache/fop/image/analyser/XMLReader.java
@@ -31,6 +31,7 @@ import org.w3c.dom.Element;
// FOP
import org.apache.fop.image.FopImage;
+import org.apache.fop.util.UnclosableInputStream;
import org.apache.fop.apps.FOUserAgent;
// Commons-Logging
@@ -63,8 +64,8 @@ public class XMLReader implements ImageReader {
FOUserAgent ua)
throws IOException {
FopImage.ImageInfo info = loadImage(uri, fis, ua);
- info.originalURI = uri;
if (info != null) {
+ info.originalURI = uri;
IOUtils.closeQuietly(fis);
}
return info;
@@ -98,16 +99,17 @@ public class XMLReader implements ImageReader {
/**
* Creates an ImageInfo object from an XML image read from a stream.
*
- * @param is The InputStream
+ * @param input The InputStream
* @param ua The user agent
* @return An ImageInfo object describing the image
*/
- public FopImage.ImageInfo createDocument(InputStream is, FOUserAgent ua) {
+ public FopImage.ImageInfo createDocument(final InputStream input, final FOUserAgent ua) {
Document doc = null;
FopImage.ImageInfo info = new FopImage.ImageInfo();
info.mimeType = getMimeType();
try {
+ final InputStream is = new UnclosableInputStream(input);
int length = is.available();
is.mark(length);
@@ -128,14 +130,21 @@ public class XMLReader implements ImageReader {
}
}
} catch (Exception e) {
- log.warn("Error while constructing image from XML", e);
+ log.debug("Error while constructing image from XML", e);
try {
- is.reset();
+ input.reset();
} catch (IOException ioe) {
// throw the original exception, not this one
}
return null;
}
+ if (info != null) {
+ try {
+ input.close();
+ } catch (IOException io) {
+ // ignore
+ }
+ }
return info;
}
diff --git a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
index 5cf7e2f62..4d5562aa1 100644
--- a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
@@ -40,6 +40,7 @@ import org.apache.fop.fo.flow.RetrieveMarker;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
+import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.fo.pagination.Region;
import org.apache.fop.fo.pagination.RegionBody;
import org.apache.fop.fo.pagination.SideRegion;
@@ -143,10 +144,11 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
areaTreeHandler.getAreaTreeModel().startPageSequence(title);
- log.debug("Starting layout");
+ if (log.isDebugEnabled()) {
+ log.debug("Starting layout");
+ }
curPage = makeNewPage(false, false);
-
Flow mainFlow = pageSeq.getMainFlow();
childFLM = getLayoutManagerMaker().
@@ -172,7 +174,19 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
areaTreeHandler.notifyPageSequenceFinished(pageSeq,
(currentPageNum - startPageNum) + 1);
pageSeq.releasePageSequence();
- log.debug("Ending layout");
+
+ // If this sequence has a page sequence master so we must reset
+ // it in preparation for the next sequence
+ String masterReference = pageSeq.getMasterReference();
+ PageSequenceMaster pageSeqMaster
+ = pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(masterReference);
+ if (pageSeqMaster != null) {
+ pageSeqMaster.reset();
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Ending layout");
+ }
}
@@ -778,7 +792,9 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
private void finishPage() {
- curPage.getPageViewport().dumpMarkers();
+ if (log.isTraceEnabled()) {
+ curPage.getPageViewport().dumpMarkers();
+ }
// Layout side regions
layoutSideRegion(FO_REGION_BEFORE);
layoutSideRegion(FO_REGION_AFTER);
@@ -1129,7 +1145,6 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
// If there is no next page-sequence
// or if the value of its initial-page-number is "auto" do not force any page.
-
// if force-page-count is auto then set the value of forcePageCount
// depending on the initial-page-number of the next page-sequence
if (nextPageSeqInitialPageNumber != null && forcePageCount == Constants.EN_AUTO) {
@@ -1156,19 +1171,19 @@ public class PageSequenceLayoutManager extends AbstractLayoutManager {
}
if (forcePageCount == Constants.EN_EVEN) {
- if ((currentPageNum - startPageNum + 1) % 2 != 0) { // we have a odd number of pages
+ if ((currentPageNum - startPageNum + 1) % 2 != 0) { // we have an odd number of pages
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_ODD) {
- if ((currentPageNum - startPageNum + 1) % 2 == 0) { // we have a even number of pages
+ if ((currentPageNum - startPageNum + 1) % 2 == 0) { // we have an even number of pages
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_END_ON_EVEN) {
- if (currentPageNum % 2 != 0) { // we are now on a odd page
+ if (currentPageNum % 2 != 0) { // we are now on an odd page
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_END_ON_ODD) {
- if (currentPageNum % 2 == 0) { // we are now on a even page
+ if (currentPageNum % 2 == 0) { // we are now on an even page
curPage = makeNewPage(true, false);
}
} else if (forcePageCount == Constants.EN_NO_FORCE) {
diff --git a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
index 26dc8c3b4..3d1291480 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/CharacterLayoutManager.java
@@ -75,11 +75,14 @@ public class CharacterLayoutManager extends LeafNodeLayoutManager {
}
private org.apache.fop.area.inline.TextArea getCharacterInlineArea(Character node) {
- org.apache.fop.area.inline.TextArea text
+ org.apache.fop.area.inline.TextArea text
= new org.apache.fop.area.inline.TextArea();
char ch = node.getCharacter();
if (CharUtilities.isAnySpace(ch)) {
- text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch));
+ // add space unless it's zero-width:
+ if (!CharUtilities.isZeroWidthSpace(ch)) {
+ text.addSpace(ch, 0, CharUtilities.isAdjustableSpace(ch));
+ }
} else {
text.addWord(String.valueOf(ch), 0);
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 7e14f49da..8d6c13670 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.LinkedList;
import java.util.ListIterator;
-import java.util.NoSuchElementException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -378,7 +377,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
iTotalAdjust += (iWordSpaceDim - wordSpaceIPD.opt) * iWScount;
if (iTotalAdjust != iDifference) {
// the applied adjustment is greater or smaller than the needed one
- log.trace("TextLM.addAreas: error in word / letter space adjustment = "
+ log.trace("TextLM.addAreas: error in word / letter space adjustment = "
+ (iTotalAdjust - iDifference));
// set iTotalAdjust = iDifference, so that the width of the TextArea
// will counterbalance the error and the other inline areas will be
@@ -458,11 +457,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
areaInfo = (AreaInfo) vecAreaInfo.get(i);
if (areaInfo.isSpace) {
// areaInfo stores information about spaces
- // add the spaces to the TextArea
+ // add the spaces - except zero-width spaces - to the TextArea
for (int j = areaInfo.iStartIndex; j < areaInfo.iBreakIndex; j++) {
char spaceChar = textArray[j];
- textArea.addSpace(spaceChar, 0,
- CharUtilities.isAdjustableSpace(spaceChar));
+ if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
+ textArea.addSpace(spaceChar, 0,
+ CharUtilities.isAdjustableSpace(spaceChar));
+ }
}
} else {
// areaInfo stores information about a word fragment
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/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java
index 571b77499..addd7f2b1 100644
--- a/src/java/org/apache/fop/pdf/PDFMetadata.java
+++ b/src/java/org/apache/fop/pdf/PDFMetadata.java
@@ -34,7 +34,6 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter;
import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter;
-import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAOldXMPSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema;
import org.xml.sax.SAXException;
@@ -136,7 +135,7 @@ public class PDFMetadata extends PDFStream {
info.setCreationDate(d);
}
- //Important: Acrobat's preflight check for PDF/A-1b wants the creation date in the Info
+ //Important: Acrobat 7's preflight check for PDF/A-1b wants the creation date in the Info
//object and in the XMP metadata to have the same timezone or else it shows a validation
//error even if the times are essentially equal.
@@ -149,7 +148,8 @@ public class PDFMetadata extends PDFStream {
dc.setTitle(info.getTitle());
}
if (info.getSubject() != null) {
- dc.addSubject(info.getSubject());
+ //Subject maps to dc:description["x-default"] as per ISO-19005-1:2005/Cor.1:2007
+ dc.setDescription(null, info.getSubject());
}
dc.addDate(info.getCreationDate());
@@ -157,25 +157,22 @@ public class PDFMetadata extends PDFStream {
PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode();
if (pdfaMode.isPDFA1LevelB()) {
PDFAAdapter pdfa = PDFAXMPSchema.getAdapter(meta);
- //Create the identification a second time with the old namespace to keep
- //Adobe Acrobat happy
- PDFAAdapter pdfaOld = PDFAOldXMPSchema.getAdapter(meta);
pdfa.setPart(1);
- pdfaOld.setPart(1);
if (pdfaMode == PDFAMode.PDFA_1A) {
pdfa.setConformance("A"); //PDF/A-1a
- pdfaOld.setConformance("A"); //PDF/A-1a
} else {
pdfa.setConformance("B"); //PDF/A-1b
- pdfaOld.setConformance("B"); //PDF/A-1b
}
}
//XMP Basic Schema
XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(meta);
xmpBasic.setCreateDate(info.getCreationDate());
- PDFProfile profile = pdfDoc.getProfile();
- if (profile.isModDateRequired()) {
+ PDFProfile profile = pdfDoc.getProfile();
+ if (info.getModDate() != null) {
+ xmpBasic.setModifyDate(info.getModDate());
+ } else if (profile.isModDateRequired()) {
+ //if modify date is needed but none is in the Info object, use creation date
xmpBasic.setModifyDate(info.getCreationDate());
}
if (info.getCreator() != null) {
@@ -210,14 +207,9 @@ public class PDFMetadata extends PDFStream {
} else {
info.setAuthor(null);
}
- String[] subjects = dc.getSubjects();
- //PDF/A-1 defines dc:subject as "Text" but XMP defines it as "bag Text".
- //We're simply doing the inverse from createXMPFromUserAgent() above.
- if (subjects != null && subjects.length > 0) {
- info.setSubject(subjects[0]);
- } else {
- info.setSubject(null);
- }
+
+ //dc:description["x-default"] maps to Subject as per ISO-19005-1:2005/Cor.1:2007
+ info.setSubject(dc.getDescription());
AdobePDFAdapter pdf = AdobePDFSchema.getAdapter(meta);
info.setKeywords(pdf.getKeywords());
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/CharUtilities.java b/src/java/org/apache/fop/util/CharUtilities.java
index dc2d987f3..1aad75ad7 100644
--- a/src/java/org/apache/fop/util/CharUtilities.java
+++ b/src/java/org/apache/fop/util/CharUtilities.java
@@ -64,8 +64,8 @@ public class CharUtilities {
public static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
/** soft hyphen */
public static final char SOFT_HYPHEN = '\u00AD';
-
-
+
+
/**
* Utility class: Constructor prevents instantiating when subclassed.
*/
@@ -98,7 +98,17 @@ public class CharUtilities {
public static boolean isBreakableSpace(char c) {
return (c == SPACE || isFixedWidthSpace(c));
}
-
+
+ /**
+ * Method to determine if the character is a zero-width space.
+ * @param c the character to check
+ * @return true if the character is a zero-width space
+ */
+ public static boolean isZeroWidthSpace(char c) {
+ return c == ZERO_WIDTH_SPACE // 200Bh
+ || c == ZERO_WIDTH_NOBREAK_SPACE; // FEFFh (also used as BOM)
+ }
+
/**
* Method to determine if the character is a (breakable) fixed-width space.
* @param c the character to check
@@ -111,7 +121,7 @@ public class CharUtilities {
// c == '\u2002' // en space
// c == '\u2003' // em space
// c == '\u2004' // three-per-em space
-// c == '\u2005' // four--per-em space
+// c == '\u2005' // four-per-em space
// c == '\u2006' // six-per-em space
// c == '\u2007' // figure space
// c == '\u2008' // punctuation space
@@ -120,7 +130,7 @@ public class CharUtilities {
// c == '\u200B' // zero width space
// c == '\u3000' // ideographic space
}
-
+
/**
* Method to determine if the character is a nonbreaking
* space.
diff --git a/src/java/org/apache/fop/util/LogUtil.java b/src/java/org/apache/fop/util/LogUtil.java
new file mode 100644
index 000000000..60eafb51a
--- /dev/null
+++ b/src/java/org/apache/fop/util/LogUtil.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.fop.apps.FOPException;
+
+/**
+ * Convenience Logging utility methods used in FOP
+ */
+public class LogUtil {
+
+ /**
+ * Convenience method that handles any error appropriately
+ * @param log log
+ * @param errorStr error string
+ * @param strict validate strictly
+ * @throws FOPException fop exception
+ */
+ public static void handleError(Log log, String errorStr, boolean strict) throws FOPException {
+ handleException(log, new FOPException(errorStr), strict);
+ }
+
+ /**
+ * Convenience method that handles any error appropriately
+ * @param log log
+ * @param e exception
+ * @param strict validate strictly
+ * @throws FOPException fop exception
+ */
+ public static void handleException(Log log, Exception e, boolean strict) throws FOPException {
+ if (strict) {
+ if (e instanceof FOPException) {
+ throw (FOPException)e;
+ }
+ throw new FOPException(e);
+ }
+ log.error(e.getMessage());
+ }
+}
diff --git a/src/java/org/apache/fop/util/UnclosableInputStream.java b/src/java/org/apache/fop/util/UnclosableInputStream.java
new file mode 100644
index 000000000..0384a62ff
--- /dev/null
+++ b/src/java/org/apache/fop/util/UnclosableInputStream.java
@@ -0,0 +1,46 @@
+/*
+ * 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 java.io.FilterInputStream;
+import java.io.InputStream;
+
+/**
+ * Provides an InputStreamFilter which avoids closing the original stream.
+ */
+public class UnclosableInputStream extends FilterInputStream {
+
+ /**
+ * Default constructor.
+ *
+ * @param in the Stream to filter.
+ */
+ public UnclosableInputStream(InputStream in) {
+ super(in);
+ }
+
+ /**
+ * Does <strong>not</strong> close the original stream.
+ */
+ public void close() {
+ // ignore
+ }
+
+}