aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Hancock <phancock@apache.org>2012-07-03 16:01:48 +0000
committerPeter Hancock <phancock@apache.org>2012-07-03 16:01:48 +0000
commitfb48ed8bc5d5d14b7a1086486378c640cd8b56f8 (patch)
tree206b64290514dbc4fa622c8758153f99fbf2d58c /src
parent3e31e071ea47f37ef7f8749b324dfdfe76745d18 (diff)
parentfdb801262c8abbf13b12d9df5900a5c4627dda12 (diff)
downloadxmlgraphics-fop-fb48ed8bc5d5d14b7a1086486378c640cd8b56f8.tar.gz
xmlgraphics-fop-fb48ed8bc5d5d14b7a1086486378c640cd8b56f8.zip
Merged trunk@1356765
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_RoundedCorners@1356804 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/documentation/content/xdocs/team.xml17
-rw-r--r--src/java/org/apache/fop/afp/AFPDataObjectInfo.java2
-rw-r--r--src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java3
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceInfo.java3
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceLevel.java141
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java3
-rw-r--r--src/java/org/apache/fop/afp/AFPResourceManager.java24
-rw-r--r--src/java/org/apache/fop/afp/AFPStreamer.java108
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java5
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPFont.java18
-rw-r--r--src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java11
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java10
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java75
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetType.java32
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java28
-rw-r--r--src/java/org/apache/fop/afp/fonts/DoubleByteFont.java9
-rw-r--r--src/java/org/apache/fop/afp/fonts/FopCharacterSet.java4
-rw-r--r--src/java/org/apache/fop/afp/fonts/OutlineFont.java5
-rw-r--r--src/java/org/apache/fop/afp/fonts/RasterFont.java14
-rw-r--r--src/java/org/apache/fop/afp/modca/IncludedResourceObject.java7
-rw-r--r--src/java/org/apache/fop/afp/util/AFPResourceAccessor.java76
-rw-r--r--src/java/org/apache/fop/afp/util/AFPResourceUtil.java60
-rw-r--r--src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java87
-rw-r--r--src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java76
-rw-r--r--src/java/org/apache/fop/apps/EnvironmentProfile.java (renamed from src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java)34
-rw-r--r--src/java/org/apache/fop/apps/EnvironmentalProfileFactory.java113
-rw-r--r--src/java/org/apache/fop/apps/FOURIResolver.java376
-rw-r--r--src/java/org/apache/fop/apps/FOUserAgent.java326
-rw-r--r--src/java/org/apache/fop/apps/Fop.java6
-rw-r--r--src/java/org/apache/fop/apps/FopConfParser.java348
-rw-r--r--src/java/org/apache/fop/apps/FopFactory.java597
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryBuilder.java648
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryConfig.java130
-rw-r--r--src/java/org/apache/fop/apps/FopFactoryConfigurator.java406
-rw-r--r--src/java/org/apache/fop/apps/MimeConstants.java2
-rw-r--r--src/java/org/apache/fop/apps/io/InternalResourceResolver.java153
-rw-r--r--src/java/org/apache/fop/apps/io/Resource.java (renamed from src/java/org/apache/fop/render/DefaultFontResolver.java)43
-rw-r--r--src/java/org/apache/fop/apps/io/ResourceResolver.java51
-rw-r--r--src/java/org/apache/fop/apps/io/ResourceResolverFactory.java276
-rw-r--r--src/java/org/apache/fop/apps/io/TempResourceResolver.java48
-rw-r--r--src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java57
-rw-r--r--src/java/org/apache/fop/apps/io/package.html6
-rw-r--r--src/java/org/apache/fop/area/AreaTreeHandler.java2
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java6
-rw-r--r--src/java/org/apache/fop/area/CachedRenderPagesModel.java47
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java56
-rw-r--r--src/java/org/apache/fop/cli/IFInputHandler.java2
-rw-r--r--src/java/org/apache/fop/cli/InputHandler.java19
-rw-r--r--src/java/org/apache/fop/fo/FOTreeBuilder.java2
-rw-r--r--src/java/org/apache/fop/fo/PropertyList.java8
-rw-r--r--src/java/org/apache/fop/fo/extensions/svg/SVGElement.java10
-rw-r--r--src/java/org/apache/fop/fo/flow/ExternalGraphic.java2
-rw-r--r--src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java2
-rw-r--r--src/java/org/apache/fop/fonts/CIDFont.java9
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java80
-rw-r--r--src/java/org/apache/fop/fonts/CustomFontCollection.java26
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfig.java343
-rw-r--r--src/java/org/apache/fop/fonts/DefaultFontConfigurator.java186
-rw-r--r--src/java/org/apache/fop/fonts/EmbedFontInfo.java83
-rw-r--r--src/java/org/apache/fop/fonts/FontAdder.java17
-rw-r--r--src/java/org/apache/fop/fonts/FontCache.java20
-rw-r--r--src/java/org/apache/fop/fonts/FontCacheManager.java (renamed from src/java/org/apache/fop/fonts/FontResolver.java)34
-rw-r--r--src/java/org/apache/fop/fonts/FontCacheManagerFactory.java92
-rw-r--r--src/java/org/apache/fop/fonts/FontConfig.java50
-rw-r--r--src/java/org/apache/fop/fonts/FontConfigurator.java (renamed from src/java/org/apache/fop/afp/util/ResourceAccessor.java)23
-rw-r--r--src/java/org/apache/fop/fonts/FontDetector.java82
-rw-r--r--src/java/org/apache/fop/fonts/FontDetectorFactory.java119
-rw-r--r--src/java/org/apache/fop/fonts/FontInfoConfigurator.java328
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java112
-rw-r--r--src/java/org/apache/fop/fonts/FontManager.java151
-rw-r--r--src/java/org/apache/fop/fonts/FontManagerConfigurator.java80
-rw-r--r--src/java/org/apache/fop/fonts/FontReader.java112
-rw-r--r--src/java/org/apache/fop/fonts/FontSetup.java55
-rw-r--r--src/java/org/apache/fop/fonts/FontTriplet.java13
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java114
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java8
-rw-r--r--src/java/org/apache/fop/fonts/MutableFont.java7
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteFont.java8
-rw-r--r--src/java/org/apache/fop/fonts/apps/TTFReader.java19
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java75
-rw-r--r--src/java/org/apache/fop/fonts/truetype/FontFileReader.java44
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java13
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java24
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFBParser.java33
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFMFile.java25
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java38
-rw-r--r--src/java/org/apache/fop/hyphenation/Hyphenator.java159
-rw-r--r--src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java7
-rw-r--r--src/java/org/apache/fop/pdf/PDFAMode.java10
-rw-r--r--src/java/org/apache/fop/pdf/PDFDocument.java19
-rw-r--r--src/java/org/apache/fop/pdf/PDFEncryptionParams.java13
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java104
-rw-r--r--src/java/org/apache/fop/pdf/PDFXMode.java8
-rw-r--r--src/java/org/apache/fop/pdf/StreamCacheFactory.java62
-rw-r--r--src/java/org/apache/fop/render/AbstractConfigurator.java38
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererConfigurator.java35
-rw-r--r--src/java/org/apache/fop/render/AbstractRendererMaker.java6
-rw-r--r--src/java/org/apache/fop/render/DefaultRendererConfigurator.java48
-rw-r--r--src/java/org/apache/fop/render/PrintRenderer.java24
-rw-r--r--src/java/org/apache/fop/render/PrintRendererConfigurator.java182
-rw-r--r--src/java/org/apache/fop/render/RendererConfig.java64
-rw-r--r--src/java/org/apache/fop/render/RendererConfigOption.java (renamed from src/java/org/apache/fop/render/RendererConfigurator.java)15
-rw-r--r--src/java/org/apache/fop/render/RendererFactory.java37
-rw-r--r--src/java/org/apache/fop/render/XMLHandlerConfigurator.java2
-rw-r--r--src/java/org/apache/fop/render/afp/AFPCustomizable.java8
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java28
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandlerMaker.java7
-rw-r--r--src/java/org/apache/fop/render/afp/AFPFontConfig.java442
-rw-r--r--src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java43
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java3
-rw-r--r--src/java/org/apache/fop/render/afp/AFPPainter.java60
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfig.java375
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java537
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererOption.java64
-rw-r--r--src/java/org/apache/fop/render/afp/AFPSVGHandler.java2
-rw-r--r--src/java/org/apache/fop/render/afp/AFPShadingMode.java15
-rw-r--r--src/java/org/apache/fop/render/awt/AWTRenderer.java8
-rw-r--r--src/java/org/apache/fop/render/awt/AWTRendererMaker.java11
-rw-r--r--src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java25
-rw-r--r--src/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java178
-rw-r--r--src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java131
-rw-r--r--src/java/org/apache/fop/render/bitmap/BitmapRendererOption.java74
-rw-r--r--src/java/org/apache/fop/render/bitmap/BitmapRenderingSettings.java14
-rw-r--r--src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java9
-rw-r--r--src/java/org/apache/fop/render/bitmap/PNGDocumentHandlerMaker.java7
-rw-r--r--src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java54
-rw-r--r--src/java/org/apache/fop/render/bitmap/PNGRendererMaker.java16
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFCompressionValues.java (renamed from src/java/org/apache/fop/render/bitmap/TIFFConstants.java)42
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java10
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFDocumentHandlerMaker.java7
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRenderer.java15
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java102
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java78
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java19
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java26
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java9
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java5
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java52
-rw-r--r--src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java4
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFDocumentHandler.java7
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java2
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFException.java31
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFParser.java4
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFRenderer.java3
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFRendererConfig.java63
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFSerializer.java17
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFSerializerMaker.java6
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFUtil.java3
-rw-r--r--src/java/org/apache/fop/render/intermediate/util/IFDocumentHandlerProxy.java5
-rw-r--r--src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java60
-rw-r--r--src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java26
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DDocumentHandler.java156
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java2
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DPainter.java12
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderer.java29
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRendererConfig.java83
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java26
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRendererOption.java (renamed from src/java/org/apache/fop/render/ps/PSConfigurationConstants.java)26
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DRenderingSettings.java2
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DUtil.java2
-rw-r--r--src/java/org/apache/fop/render/pcl/Java2DRendererOption.java49
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java19
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java7
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLGenerator.java8
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java2
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLPainter.java45
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererConfig.java123
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java104
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLRenderingMode.java30
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java84
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java52
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java8
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java6
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFEncryptionOption.java98
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFPainter.java41
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfig.java227
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java223
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererOption.java112
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java123
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java309
-rw-r--r--src/java/org/apache/fop/render/print/PrintRendererMaker.java15
-rw-r--r--src/java/org/apache/fop/render/ps/PSDocumentHandler.java43
-rw-r--r--src/java/org/apache/fop/render/ps/PSDocumentHandlerMaker.java13
-rw-r--r--src/java/org/apache/fop/render/ps/PSFontUtils.java27
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java2
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageUtils.java4
-rw-r--r--src/java/org/apache/fop/render/ps/PSPainter.java41
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererConfig.java147
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererConfigurator.java77
-rw-r--r--src/java/org/apache/fop/render/ps/PSRendererOption.java57
-rw-r--r--src/java/org/apache/fop/render/ps/PSRenderingUtil.java13
-rw-r--r--src/java/org/apache/fop/render/ps/PSSVGHandler.java2
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java2
-rw-r--r--src/java/org/apache/fop/render/ps/ResourceHandler.java4
-rw-r--r--src/java/org/apache/fop/render/rtf/RTFHandler.java13
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java20
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRendererMaker.java15
-rw-r--r--src/java/org/apache/fop/render/txt/TxtRendererConfig.java99
-rw-r--r--src/java/org/apache/fop/render/xml/XMLRendererMaker.java14
-rw-r--r--src/java/org/apache/fop/servlet/FopServlet.java25
-rw-r--r--src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java68
-rw-r--r--src/java/org/apache/fop/svg/PDFTranscoder.java2
-rw-r--r--src/java/org/apache/fop/tools/TestConverter.java17
-rw-r--r--src/java/org/apache/fop/tools/anttasks/Fop.java52
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontListGenerator.java3
-rw-r--r--src/java/org/apache/fop/tools/fontlist/FontListMain.java6
-rw-r--r--src/java/org/apache/fop/util/ColorSpaceCache.java33
-rw-r--r--src/java/org/apache/fop/util/ColorUtil.java12
-rw-r--r--src/sandbox/org/apache/fop/render/mif/MIFHandler.java3
-rw-r--r--src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java5
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java6
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java7
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGPainter.java18
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java17
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java7
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGRendererMaker.java12
218 files changed, 7918 insertions, 5552 deletions
diff --git a/src/documentation/content/xdocs/team.xml b/src/documentation/content/xdocs/team.xml
index a8f0602e4..a6e2e51c9 100644
--- a/src/documentation/content/xdocs/team.xml
+++ b/src/documentation/content/xdocs/team.xml
@@ -58,7 +58,7 @@
recent XML/XSL-FO convert, he has been nit-picking FAQs &amp; assorted web
pages since his first webmaster position @brain.com in 1996. Most
important creation? He's got a couple of cool kids.</li>
- <li id="jm"><link href="mailto:jeremias@apache.org">Jeremias M�rki</link> (JM)
+ <li id="jm"><link href="mailto:jeremias@apache.org">Jeremias Märki</link> (JM)
is an independent software engineer and consultant from Lucerne, Switzerland. He's also
the creator of <fork href="http://barcode4j.sourceforge.net">Barcode4J</fork>.
See his <fork href="http://www.jeremias-maerki.ch">home page</fork> for more information
@@ -67,20 +67,25 @@
<li id="sp"><link href="mailto:spepping@apache.org">Simon Pepping</link> (SP) came to FOP
from the TeX/LaTeX world. See his <fork href="http://www.leverkruid.eu">home
page</fork> for some of his private projects.</li>
- <li id="jp"><link href="mailto:pietsch@apache.org">J�rg Pietschmann</link> (JP)</li>
+ <li id="jp"><link href="mailto:pietsch@apache.org">Jörg Pietschmann</link> (JP)</li>
<li id="ps"><link href="mailto:tcho@club-internet.fr">Pascal Sancho</link> (PS)
- is an XML developper from Aix-en-Provence (France). He works on software solutions for
- rendering various kind of documents on various supports, more specifically taking care
- of PDF generation with FOP.</li>
+ is an XML developper from Aix-en-Provence (France). He works on software solutions for
+ rendering various kind of documents on various supports, more specifically taking care
+ of PDF generation with FOP.</li>
</ul>
</section>
<section id="contribute-active">
<title>Active Contributors</title>
<ul>
+ <li id="ag">Alexios Giotis holds a Ph.D. in the optimization of turbomachinery cascades
+ using evolutionary algorithms, neural networks and parallel processing. He is one of
+ the founding members of i-docs (software for enterprises) and he has been leading its
+ technical design &amp; implementation based on open source libraries since its inception.
+ He is relying on Apache FOP for generating high volumes of documents on major banks and
+ telecom operators since FOP's 1.0 release. He lives in Athens, Greece.</li>
<li id="gd">Georg Datterl is a software developer from Austria, currently working for
Geneon media solutions gmbh in Nuremberg, Germany. He needs FOP to wrestle gigabytes of
electronic data into thousands of printed pages.</li>
- <li id="lm">Louis Masters</li>
<li id="lb">Luis Bernardo</li>
</ul>
</section>
diff --git a/src/java/org/apache/fop/afp/AFPDataObjectInfo.java b/src/java/org/apache/fop/afp/AFPDataObjectInfo.java
index 7589ef4fe..b93056f02 100644
--- a/src/java/org/apache/fop/afp/AFPDataObjectInfo.java
+++ b/src/java/org/apache/fop/afp/AFPDataObjectInfo.java
@@ -57,6 +57,8 @@ public class AFPDataObjectInfo {
/** controls the mapping of the image data into the image area */
private byte mappingOption = MappingOptionTriplet.SCALE_TO_FILL;
+ public static final byte DEFAULT_MAPPING_OPTION = 0x00;
+
/**
* Default constructor
*/
diff --git a/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java b/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
index d1c693afb..a953718bd 100644
--- a/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
+++ b/src/java/org/apache/fop/afp/AFPDitheredRectanglePainter.java
@@ -28,6 +28,7 @@ import java.io.IOException;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.util.MimeConstants;
+import org.apache.fop.afp.AFPResourceLevel.ResourceType;
import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
import org.apache.fop.util.bitmap.DitherUtil;
@@ -66,7 +67,7 @@ public class AFPDitheredRectanglePainter extends AbstractAFPPainter {
AFPImageObjectInfo imageObjectInfo = new AFPImageObjectInfo();
imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
//imageObjectInfo.setCreatePageSegment(true);
- imageObjectInfo.getResourceInfo().setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
+ imageObjectInfo.getResourceInfo().setLevel(new AFPResourceLevel(ResourceType.INLINE));
imageObjectInfo.getResourceInfo().setImageDimension(ditherSize);
imageObjectInfo.setBitsPerPixel(1);
imageObjectInfo.setColor(false);
diff --git a/src/java/org/apache/fop/afp/AFPResourceInfo.java b/src/java/org/apache/fop/afp/AFPResourceInfo.java
index 1bf26f2bb..bbd552c67 100644
--- a/src/java/org/apache/fop/afp/AFPResourceInfo.java
+++ b/src/java/org/apache/fop/afp/AFPResourceInfo.java
@@ -21,6 +21,7 @@ package org.apache.fop.afp;
import java.awt.Dimension;
+import org.apache.fop.afp.AFPResourceLevel.ResourceType;
/**
* The level at which a resource is to reside in the AFP output
@@ -29,7 +30,7 @@ public class AFPResourceInfo {
/** the general default resource level */
public static final AFPResourceLevel DEFAULT_LEVEL
- = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
+ = new AFPResourceLevel(ResourceType.PRINT_FILE);
/** the URI of this resource */
private String uri = null;
diff --git a/src/java/org/apache/fop/afp/AFPResourceLevel.java b/src/java/org/apache/fop/afp/AFPResourceLevel.java
index d884b56a6..860ca3d26 100644
--- a/src/java/org/apache/fop/afp/AFPResourceLevel.java
+++ b/src/java/org/apache/fop/afp/AFPResourceLevel.java
@@ -19,46 +19,56 @@
package org.apache.fop.afp;
+import java.net.URI;
+
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.DOCUMENT;
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.EXTERNAL;
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.INLINE;
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PAGE;
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PAGE_GROUP;
+import static org.apache.fop.afp.AFPResourceLevel.ResourceType.PRINT_FILE;
+
/**
* A resource level
*/
public class AFPResourceLevel {
+ public enum ResourceType {
+ /** directly in page **/
+ INLINE("inline"),
+ /** page level **/
+ PAGE("page"),
+ /** page group level **/
+ PAGE_GROUP("page-group"),
+ /** document level **/
+ DOCUMENT("document"),
+ /** print file level **/
+ PRINT_FILE("print-file"),
+ /** external level **/
+ EXTERNAL("external");
+
+ private final String name;
+
+ private ResourceType(String name) {
+ this.name = name;
+ }
- /** directly in page **/
- public static final int INLINE = 0;
-
- /** page level **/
- public static final int PAGE = 1;
-
- /** page group level **/
- public static final int PAGE_GROUP = 2;
-
- /** document level **/
- public static final int DOCUMENT = 3;
-
- /** print file level **/
- public static final int PRINT_FILE = 4;
-
- /** external level **/
- public static final int EXTERNAL = 5;
-
- private static final String NAME_INLINE = "inline";
- private static final String NAME_PAGE = "page";
- private static final String NAME_PAGE_GROUP = "page-group";
- private static final String NAME_DOCUMENT = "document";
- private static final String NAME_PRINT_FILE = "print-file";
- private static final String NAME_EXTERNAL = "external";
-
- private static final String[] NAMES = new String[] {
- NAME_INLINE, NAME_PAGE, NAME_PAGE_GROUP, NAME_DOCUMENT, NAME_PRINT_FILE, NAME_EXTERNAL
- };
-
+ public static ResourceType getValueOf(String levelString) {
+ for (ResourceType resType : ResourceType.values()) {
+ if (resType.name.equalsIgnoreCase(levelString)) {
+ return resType;
+ }
+ }
+ return null;
+ }
- /** where the resource will reside in the AFP output */
- private int level = PRINT_FILE; // default is print-file level (images)
+ public String getName() {
+ return name;
+ }
+ }
/** the external resource group file path */
- private String extFilePath = null;
+ private URI extUri = null;
+ private ResourceType resourceType;
/**
* Sets the resource placement level within the AFP output
@@ -67,18 +77,8 @@ public class AFPResourceLevel {
* @return true if the resource level was successfully set
*/
public static AFPResourceLevel valueOf(String levelString) {
- if (levelString != null) {
- levelString = levelString.toLowerCase();
- AFPResourceLevel resourceLevel = null;
- for (int i = 0; i < NAMES.length; i++) {
- if (NAMES[i].equals(levelString)) {
- resourceLevel = new AFPResourceLevel(i);
- break;
- }
- }
- return resourceLevel;
- }
- return null;
+ ResourceType resType = ResourceType.getValueOf(levelString);
+ return resType != null ? new AFPResourceLevel(resType) : null;
}
/**
@@ -86,17 +86,8 @@ public class AFPResourceLevel {
*
* @param level the resource level
*/
- public AFPResourceLevel(int level) {
- setLevel(level);
- }
-
- /**
- * Sets the resource level
- *
- * @param level the resource level
- */
- public void setLevel(int level) {
- this.level = level;
+ public AFPResourceLevel(ResourceType resourceType) {
+ this.resourceType = resourceType;
}
/**
@@ -105,7 +96,7 @@ public class AFPResourceLevel {
* @return true if this is at page level
*/
public boolean isPage() {
- return level == PAGE;
+ return resourceType == PAGE;
}
/**
@@ -114,7 +105,7 @@ public class AFPResourceLevel {
* @return true if this is at page group level
*/
public boolean isPageGroup() {
- return level == PAGE_GROUP;
+ return resourceType == PAGE_GROUP;
}
/**
@@ -123,7 +114,7 @@ public class AFPResourceLevel {
* @return true if this is at document level
*/
public boolean isDocument() {
- return level == DOCUMENT;
+ return resourceType == DOCUMENT;
}
/**
@@ -132,7 +123,7 @@ public class AFPResourceLevel {
* @return true if this is at external level
*/
public boolean isExternal() {
- return level == EXTERNAL;
+ return resourceType == EXTERNAL;
}
/**
@@ -141,7 +132,7 @@ public class AFPResourceLevel {
* @return true if this is at print-file level
*/
public boolean isPrintFile() {
- return level == PRINT_FILE;
+ return resourceType == PRINT_FILE;
}
/**
@@ -150,30 +141,30 @@ public class AFPResourceLevel {
* @return true if this resource level is inline
*/
public boolean isInline() {
- return level == INLINE;
+ return resourceType == INLINE;
}
/**
- * Returns the destination file path of the external resource group file
+ * Returns the URI of the external resource group.
*
- * @return the destination file path of the external resource group file
+ * @return the destination URI of the external resource group
*/
- public String getExternalFilePath() {
- return this.extFilePath;
+ public URI getExternalURI() {
+ return this.extUri;
}
/**
- * Sets the external destination of the resource
+ * Sets the URI of the external resource group.
*
- * @param filePath the external resource group file
+ * @param filePath the URI of the external resource group
*/
- public void setExternalFilePath(String filePath) {
- this.extFilePath = filePath;
+ public void setExternalUri(URI uri) {
+ this.extUri = uri;
}
/** {@inheritDoc} */
public String toString() {
- return NAMES[level] + (isExternal() ? ", file=" + extFilePath : "");
+ return resourceType + (isExternal() ? ", uri=" + extUri : "");
}
/** {@inheritDoc} */
@@ -186,16 +177,16 @@ public class AFPResourceLevel {
}
AFPResourceLevel rl = (AFPResourceLevel)obj;
- return (level == rl.level)
- && (extFilePath == rl.extFilePath
- || extFilePath != null && extFilePath.equals(rl.extFilePath));
+ return (resourceType == rl.resourceType)
+ && (extUri == rl.extUri
+ || extUri != null && extUri.equals(rl.extUri));
}
/** {@inheritDoc} */
public int hashCode() {
int hash = 7;
- hash = 31 * hash + level;
- hash = 31 * hash + (null == extFilePath ? 0 : extFilePath.hashCode());
+ hash = 31 * hash + resourceType.hashCode();
+ hash = 31 * hash + (null == extUri ? 0 : extUri.hashCode());
return hash;
}
}
diff --git a/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java b/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java
index 8cb0ebaaf..aea97cb7d 100644
--- a/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java
+++ b/src/java/org/apache/fop/afp/AFPResourceLevelDefaults.java
@@ -22,6 +22,7 @@ package org.apache.fop.afp;
import java.util.Iterator;
import java.util.Map;
+import org.apache.fop.afp.AFPResourceLevel.ResourceType;
import org.apache.fop.afp.modca.ResourceObject;
/**
@@ -58,7 +59,7 @@ public class AFPResourceLevelDefaults {
// level not explicitly set/changed so default to inline for GOCA graphic objects
// (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine)
setDefaultResourceLevel(ResourceObject.TYPE_GRAPHIC,
- new AFPResourceLevel(AFPResourceLevel.INLINE));
+ new AFPResourceLevel(ResourceType.INLINE));
}
/**
diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java
index 9544f76c7..43dc626a7 100644
--- a/src/java/org/apache/fop/afp/AFPResourceManager.java
+++ b/src/java/org/apache/fop/afp/AFPResourceManager.java
@@ -31,6 +31,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.afp.AFPResourceLevel.ResourceType;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
@@ -41,8 +42,9 @@ import org.apache.fop.afp.modca.PageSegment;
import org.apache.fop.afp.modca.Registry;
import org.apache.fop.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.ResourceObject;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.afp.util.AFPResourceUtil;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.apps.io.InternalResourceResolver;
/**
* Manages the creation and storage of document resources
@@ -74,9 +76,9 @@ public class AFPResourceManager {
/**
* Main constructor
*/
- public AFPResourceManager() {
+ public AFPResourceManager(InternalResourceResolver resourceResolver) {
this.factory = new Factory();
- this.streamer = new AFPStreamer(factory);
+ this.streamer = new AFPStreamer(factory, resourceResolver);
this.dataObjectFactory = new AFPDataObjectFactory(factory);
}
@@ -119,8 +121,8 @@ public class AFPResourceManager {
* @param filePath the default resource group file path
*/
- public void setDefaultResourceGroupFilePath(String filePath) {
- streamer.setDefaultResourceGroupFilePath(filePath);
+ public void setDefaultResourceGroupUri(URI uri) {
+ streamer.setDefaultResourceGroupUri(uri);
}
/**
@@ -325,7 +327,7 @@ public class AFPResourceManager {
if (afpFont.isEmbeddable()) {
//Embed fonts (char sets and code pages)
if (charSet.getResourceAccessor() != null) {
- ResourceAccessor accessor = charSet.getResourceAccessor();
+ AFPResourceAccessor accessor = charSet.getResourceAccessor();
createIncludedResource(
charSet.getName(), accessor,
ResourceObject.TYPE_FONT_CHARACTER_SET);
@@ -352,7 +354,7 @@ public class AFPResourceManager {
* @param resourceObjectType the resource object type ({@link ResourceObject}.*)
* @throws IOException if an I/O error occurs while loading the resource
*/
- public void createIncludedResource(String resourceName, ResourceAccessor accessor,
+ public void createIncludedResource(String resourceName, AFPResourceAccessor accessor,
byte resourceObjectType) throws IOException {
URI uri;
try {
@@ -373,9 +375,9 @@ public class AFPResourceManager {
* @param resourceObjectType the resource object type ({@link ResourceObject}.*)
* @throws IOException if an I/O error occurs while loading the resource
*/
- public void createIncludedResource(String resourceName, URI uri, ResourceAccessor accessor,
+ public void createIncludedResource(String resourceName, URI uri, AFPResourceAccessor accessor,
byte resourceObjectType) throws IOException {
- AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
+ AFPResourceLevel resourceLevel = new AFPResourceLevel(ResourceType.PRINT_FILE);
AFPResourceInfo resourceInfo = new AFPResourceInfo();
resourceInfo.setLevel(resourceLevel);
@@ -416,9 +418,9 @@ public class AFPResourceManager {
* @throws IOException if an I/O error occurs while loading the resource
*/
public void createIncludedResourceFromExternal(final String resourceName,
- final URI uri, final ResourceAccessor accessor) throws IOException {
+ final URI uri, final AFPResourceAccessor accessor) throws IOException {
- AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE);
+ AFPResourceLevel resourceLevel = new AFPResourceLevel(ResourceType.PRINT_FILE);
AFPResourceInfo resourceInfo = new AFPResourceInfo();
resourceInfo.setLevel(resourceLevel);
diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java
index 65686b92a..072dc1796 100644
--- a/src/java/org/apache/fop/afp/AFPStreamer.java
+++ b/src/java/org/apache/fop/afp/AFPStreamer.java
@@ -20,20 +20,22 @@
package org.apache.fop.afp;
import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
-import java.io.RandomAccessFile;
+import java.net.URI;
+import java.util.HashMap;
import java.util.Iterator;
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.afp.modca.ResourceGroup;
import org.apache.fop.afp.modca.StreamedResourceGroup;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.TempResourceURIGenerator;
/**
* Manages the streaming of the AFP output
@@ -42,43 +44,45 @@ public class AFPStreamer implements Streamable {
/** Static logging instance */
private static final Log LOG = LogFactory.getLog(AFPStreamer.class);
- private static final String AFPDATASTREAM_TEMP_FILE_PREFIX = "AFPDataStream_";
-
- private static final int BUFFER_SIZE = 4096; // 4k writing buffer
-
private static final String DEFAULT_EXTERNAL_RESOURCE_FILENAME = "resources.afp";
+ private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+ = new TempResourceURIGenerator("AFPDataStream_");
private final Factory factory;
+ private final InternalResourceResolver resourceResolver;
+
/** A mapping of external resource destinations to resource groups */
- private final Map/*<String,AFPExternalResourceGroup>*/pathResourceGroupMap
- = new java.util.HashMap/*<String,AFPExternalResourceGroup>*/();
+ private final Map<URI, ResourceGroup> pathResourceGroupMap = new HashMap<URI, ResourceGroup>();
private StreamedResourceGroup printFileResourceGroup;
/** Sets the default resource group file path */
- private String defaultResourceGroupFilePath = DEFAULT_EXTERNAL_RESOURCE_FILENAME;
+ private URI defaultResourceGroupUri;
- private File tempFile;
+ private final URI tempUri;
/** temporary document outputstream */
- private OutputStream documentOutputStream;
+ private OutputStream tempOutputStream;
/** the final outputstream */
private OutputStream outputStream;
- private RandomAccessFile documentFile;
-
private DataStream dataStream;
/**
* Main constructor
*
* @param factory a factory
+ * @param resourceResolver resource resolver
*/
- public AFPStreamer(Factory factory) {
+ public AFPStreamer(Factory factory, InternalResourceResolver resourceResolver) {
this.factory = factory;
+ this.resourceResolver = resourceResolver;
+ this.tempUri = TEMP_URI_GENERATOR.generate();
+ defaultResourceGroupUri = URI.create(DEFAULT_EXTERNAL_RESOURCE_FILENAME);
+
}
/**
@@ -89,11 +93,8 @@ public class AFPStreamer implements Streamable {
* @throws IOException thrown if an I/O exception of some sort has occurred
*/
public DataStream createDataStream(AFPPaintingState paintingState) throws IOException {
- this.tempFile = File.createTempFile(AFPDATASTREAM_TEMP_FILE_PREFIX, null);
- this.documentFile = new RandomAccessFile(tempFile, "rw");
- this.documentOutputStream = new BufferedOutputStream(
- new FileOutputStream(documentFile.getFD()));
- this.dataStream = factory.createDataStream(paintingState, documentOutputStream);
+ this.tempOutputStream = new BufferedOutputStream(resourceResolver.getOutputStream(tempUri));
+ this.dataStream = factory.createDataStream(paintingState, tempOutputStream);
return dataStream;
}
@@ -102,8 +103,8 @@ public class AFPStreamer implements Streamable {
*
* @param filePath the default resource group file path
*/
- public void setDefaultResourceGroupFilePath(String filePath) {
- this.defaultResourceGroupFilePath = filePath;
+ public void setDefaultResourceGroupUri(URI uri) {
+ this.defaultResourceGroupUri = uri;
}
/**
@@ -118,23 +119,23 @@ public class AFPStreamer implements Streamable {
return null;
}
if (level.isExternal()) {
- String filePath = level.getExternalFilePath();
- if (filePath == null) {
+ URI uri = level.getExternalURI();
+ if (uri == null) {
LOG.warn("No file path provided for external resource, using default.");
- filePath = defaultResourceGroupFilePath;
+ uri = defaultResourceGroupUri;
}
- resourceGroup = (ResourceGroup)pathResourceGroupMap.get(filePath);
+ resourceGroup = pathResourceGroupMap.get(uri);
if (resourceGroup == null) {
OutputStream os = null;
try {
- os = new BufferedOutputStream(new FileOutputStream(filePath));
- } catch (FileNotFoundException fnfe) {
- LOG.error("Failed to create/open external resource group file '"
- + filePath + "'");
+ os = new BufferedOutputStream(resourceResolver.getOutputStream(uri));
+ } catch (IOException ioe) {
+ LOG.error("Failed to create/open external resource group for uri '"
+ + uri + "'");
} finally {
if (os != null) {
resourceGroup = factory.createStreamedResourceGroup(os);
- pathResourceGroupMap.put(filePath, resourceGroup);
+ pathResourceGroupMap.put(uri, resourceGroup);
}
}
}
@@ -156,34 +157,20 @@ public class AFPStreamer implements Streamable {
*
* @throws IOException if an an I/O exception of some sort has occurred
*/
- // write out any external resource groups
+ // write out any external resource groups
public void close() throws IOException {
Iterator it = pathResourceGroupMap.values().iterator();
while (it.hasNext()) {
StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next();
resourceGroup.close();
}
-
// close any open print-file resource group
if (printFileResourceGroup != null) {
printFileResourceGroup.close();
}
-
// write out document
writeToStream(outputStream);
-
outputStream.close();
-
-
- if (documentOutputStream != null) {
- documentOutputStream.close();
- }
-
- if (documentFile != null) {
- documentFile.close();
- }
- // delete temporary file
- tempFile.delete();
}
/**
@@ -197,28 +184,11 @@ public class AFPStreamer implements Streamable {
/** {@inheritDoc} */
public void writeToStream(OutputStream os) throws IOException {
-// long start = System.currentTimeMillis();
- int len = (int)documentFile.length();
- int numChunks = len / BUFFER_SIZE;
- int remainingChunkSize = len % BUFFER_SIZE;
- byte[] buffer;
-
- documentFile.seek(0);
- if (numChunks > 0) {
- buffer = new byte[BUFFER_SIZE];
- for (int i = 0; i < numChunks; i++) {
- documentFile.read(buffer, 0, BUFFER_SIZE);
- os.write(buffer, 0, BUFFER_SIZE);
- }
- } else {
- buffer = new byte[remainingChunkSize];
- }
- if (remainingChunkSize > 0) {
- documentFile.read(buffer, 0, remainingChunkSize);
- os.write(buffer, 0, remainingChunkSize);
- }
+ tempOutputStream.close();
+ InputStream tempInputStream = resourceResolver.getResource(tempUri);
+ IOUtils.copy(tempInputStream, os);
+ //TODO this should notify the stream provider that it is safe to delete the temp data
+ tempInputStream.close();
os.flush();
-// long end = System.currentTimeMillis();
-// log.debug("writing time " + (end - start) + "ms");
}
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java b/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
index 244e6122c..2d7dd3694 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPBase12FontCollection.java
@@ -165,9 +165,8 @@ public class AFPBase12FontCollection implements FontCollection {
}
private RasterFont createReferencedRasterFont(String fontFamily) {
- RasterFont font = new RasterFont(fontFamily);
- font.setEmbeddable(false); //Font is assumed to be available on the target platform
- return font;
+ boolean embeddable = false; //Font is assumed to be available on the target platform
+ return new RasterFont(fontFamily, embeddable);
}
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPFont.java b/src/java/org/apache/fop/afp/fonts/AFPFont.java
index 8a4ae3dc1..06f484f37 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPFont.java
@@ -35,16 +35,18 @@ import org.apache.fop.fonts.Typeface;
public abstract class AFPFont extends Typeface {
/** The font name */
- protected String name;
+ protected final String name;
- private boolean embeddable = true;
+ private final boolean embeddable;
/**
* Constructor for the base font requires the name.
* @param name the name of the font
+ * @param embeddable whether this font is to be embedded
*/
- public AFPFont(String name) {
+ public AFPFont(String name, boolean embeddable) {
this.name = name;
+ this.embeddable = embeddable;
}
/** {@inheritDoc} */
@@ -89,7 +91,7 @@ public abstract class AFPFont extends Typeface {
* Returns the kerning map for the font.
* @return the kerning map
*/
- public Map getKerningInfo() {
+ public Map<Integer, Map<Integer, Integer>> getKerningInfo() {
return null;
}
@@ -101,14 +103,6 @@ public abstract class AFPFont extends Typeface {
public abstract CharacterSet getCharacterSet(int size);
/**
- * Controls whether this font is embeddable or not.
- * @param value true to enable embedding, false otherwise.
- */
- public void setEmbeddable(boolean value) {
- this.embeddable = value;
- }
-
- /**
* Indicates if this font may be embedded.
* @return True, if embedding is possible/permitted
*/
diff --git a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
index fdd238242..1a2611d8d 100644
--- a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
@@ -32,13 +32,12 @@ public abstract class AbstractOutlineFont extends AFPFont {
/**
* Constructor for an outline font.
*
- * @param name
- * the name of the font
- * @param charSet
- * the chracter set
+ * @param name the name of the font
+ * @param embeddable sets whether or not this font is to be embedded
+ * @param charSet the chracter set
*/
- public AbstractOutlineFont(String name, CharacterSet charSet) {
- super(name);
+ public AbstractOutlineFont(String name, boolean embeddable, CharacterSet charSet) {
+ super(name, embeddable);
this.charSet = charSet;
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index fad5e95e6..49e7f99ba 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -30,7 +30,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.afp.util.StringUtils;
/**
@@ -77,7 +77,7 @@ public class CharacterSet {
protected final String name;
/** The path to the installed fonts */
- private final ResourceAccessor accessor;
+ private final AFPResourceAccessor accessor;
/** The current orientation (currently only 0 is supported by FOP) */
private final String currentOrientation = "0";
@@ -100,7 +100,7 @@ public class CharacterSet {
* @param eventProducer for handling AFP related events
*/
CharacterSet(String codePage, String encoding, CharacterSetType charsetType, String name,
- ResourceAccessor accessor, AFPEventProducer eventProducer) {
+ AFPResourceAccessor accessor, AFPEventProducer eventProducer) {
if (name.length() > MAX_NAME_LEN) {
String msg = "Character set name '" + name + "' must be a maximum of "
+ MAX_NAME_LEN + " characters";
@@ -115,7 +115,7 @@ public class CharacterSet {
}
this.codePage = codePage;
this.encoding = encoding;
- this.encoder = CharactersetEncoder.newInstance(encoding, charsetType);
+ this.encoder = charsetType.getEncoder(encoding);
this.accessor = accessor;
this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
@@ -211,7 +211,7 @@ public class CharacterSet {
* Returns the resource accessor to load the font resources with.
* @return the resource accessor to load the font resources with
*/
- public ResourceAccessor getResourceAccessor() {
+ public AFPResourceAccessor getResourceAccessor() {
return this.accessor;
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index 7da2d71ca..7331178f5 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -19,9 +19,9 @@
package org.apache.fop.afp.fonts;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
@@ -38,8 +38,9 @@ import org.apache.xmlgraphics.image.loader.util.SoftMapCache;
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.AFPEventProducer;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.afp.util.StructuredFieldReader;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.Typeface;
/**
@@ -138,28 +139,24 @@ public abstract class CharacterSetBuilder {
* Returns an InputStream to a given file path and filename
*
* * @param accessor the resource accessor
- * @param filename the file name
+ * @param uriStr the URI
* @param eventProducer for handling AFP related events
* @return an inputStream
- *
* @throws IOException in the event that an I/O exception of some sort has occurred
*/
- protected InputStream openInputStream(ResourceAccessor accessor, String filename,
+ private InputStream openInputStream(AFPResourceAccessor accessor, String uriStr,
AFPEventProducer eventProducer)
throws IOException {
URI uri;
try {
- uri = new URI(filename.trim());
+ uri = InternalResourceResolver.cleanURI(uriStr.trim());
} catch (URISyntaxException e) {
- throw new FileNotFoundException("Invalid filename: "
- + filename + " (" + e.getMessage() + ")");
+ throw new MalformedURLException("Invalid uri: " + uriStr + " (" + e.getMessage() + ")");
}
-
if (LOG.isDebugEnabled()) {
LOG.debug("Opening " + uri);
}
- InputStream inputStream = accessor.createInputStream(uri);
- return inputStream;
+ return accessor.createInputStream(uri);
}
/**
@@ -167,7 +164,7 @@ public abstract class CharacterSetBuilder {
*
* @param inputStream the inputstream to close
*/
- protected void closeInputStream(InputStream inputStream) {
+ private void closeInputStream(InputStream inputStream) {
try {
if (inputStream != null) {
inputStream.close();
@@ -191,7 +188,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O error occurs
*/
public CharacterSet buildSBCS(String characterSetName, String codePageName, String encoding,
- ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
+ AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
return processFont(characterSetName, codePageName, encoding, CharacterSetType.SINGLE_BYTE,
accessor, eventProducer);
}
@@ -211,7 +208,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O error occurs
*/
public CharacterSet buildDBCS(String characterSetName, String codePageName, String encoding,
- CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer)
+ CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
return processFont(characterSetName, codePageName, encoding, charsetType, accessor,
eventProducer);
@@ -236,7 +233,7 @@ public abstract class CharacterSetBuilder {
}
private CharacterSet processFont(String characterSetName, String codePageName, String encoding,
- CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer)
+ CharacterSetType charsetType, AFPResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
// check for cached version of the characterset
String descriptor = characterSetName + "_" + encoding + "_" + codePageName;
@@ -329,7 +326,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O exception of some sort has occurred.
*/
protected Map<String, String> loadCodePage(String codePage, String encoding,
- ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
+ AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
// Create the HashMap to store code page information
Map<String, String> codePages = new HashMap<String, String>();
@@ -337,7 +334,11 @@ public abstract class CharacterSetBuilder {
InputStream inputStream = null;
try {
inputStream = openInputStream(accessor, codePage.trim(), eventProducer);
-
+ } catch (IOException e) {
+ eventProducer.codePageNotFound(this, e);
+ throw e;
+ }
+ try {
StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream);
byte[] data = structuredFieldReader.getNext(CHARACTER_TABLE_SF);
@@ -367,8 +368,6 @@ public abstract class CharacterSetBuilder {
position++;
}
}
- } catch (FileNotFoundException e) {
- eventProducer.codePageNotFound(this, e);
} finally {
closeInputStream(inputStream);
}
@@ -383,9 +382,8 @@ public abstract class CharacterSetBuilder {
* @return a class representing the font descriptor
* @throws IOException if an I/O exception of some sort has occurred.
*/
- protected static FontDescriptor processFontDescriptor(
- StructuredFieldReader structuredFieldReader)
- throws IOException {
+ private static FontDescriptor processFontDescriptor(
+ StructuredFieldReader structuredFieldReader) throws IOException {
byte[] fndData = structuredFieldReader.getNext(FONT_DESCRIPTOR_SF);
return new FontDescriptor(fndData);
@@ -399,8 +397,8 @@ public abstract class CharacterSetBuilder {
* @return the FontControl
* @throws IOException if an I/O exception of some sort has occurred.
*/
- protected FontControl processFontControl(StructuredFieldReader structuredFieldReader)
- throws IOException {
+ private FontControl processFontControl(StructuredFieldReader structuredFieldReader)
+ throws IOException {
byte[] fncData = structuredFieldReader.getNext(FONT_CONTROL_SF);
@@ -431,7 +429,7 @@ public abstract class CharacterSetBuilder {
* @return CharacterSetOrientation array
* @throws IOException if an I/O exception of some sort has occurred.
*/
- protected CharacterSetOrientation[] processFontOrientation(
+ private CharacterSetOrientation[] processFontOrientation(
StructuredFieldReader structuredFieldReader) throws IOException {
byte[] data = structuredFieldReader.getNext(FONT_ORIENTATION_SF);
@@ -464,7 +462,6 @@ public abstract class CharacterSetBuilder {
}
}
-
return orientations.toArray(EMPTY_CSO_ARRAY);
}
@@ -480,7 +477,7 @@ public abstract class CharacterSetBuilder {
* font metric values
* @throws IOException if an I/O exception of some sort has occurred.
*/
- protected void processFontPosition(StructuredFieldReader structuredFieldReader,
+ private void processFontPosition(StructuredFieldReader structuredFieldReader,
CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
throws IOException {
@@ -537,7 +534,7 @@ public abstract class CharacterSetBuilder {
* font metric values
* @throws IOException if an I/O exception of some sort has occurred.
*/
- protected void processFontIndex(StructuredFieldReader structuredFieldReader,
+ private void processFontIndex(StructuredFieldReader structuredFieldReader,
CharacterSetOrientation cso, Map<String, String> codepage,
double metricNormalizationFactor)
throws IOException {
@@ -709,22 +706,23 @@ public abstract class CharacterSetBuilder {
return INSTANCE;
}
+ @Override
protected Map<String, String> loadCodePage(String codePage, String encoding,
- ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
-
+ AFPResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
// Create the HashMap to store code page information
Map<String, String> codePages = new HashMap<String, String>();
-
InputStream inputStream = null;
try {
- inputStream = openInputStream(accessor, codePage.trim(), eventProducer);
-
- StructuredFieldReader structuredFieldReader
- = new StructuredFieldReader(inputStream);
+ inputStream = super.openInputStream(accessor, codePage.trim(), eventProducer);
+ } catch (IOException e) {
+ eventProducer.codePageNotFound(this, e);
+ throw e;
+ }
+ try {
+ StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream);
byte[] data;
while ((data = structuredFieldReader.getNext(CHARACTER_TABLE_SF)) != null) {
int position = 0;
-
byte[] gcgiBytes = new byte[8];
byte[] charBytes = new byte[2];
// Read data, ignoring bytes 0 - 2
@@ -752,12 +750,9 @@ public abstract class CharacterSetBuilder {
}
}
}
- } catch (FileNotFoundException e) {
- eventProducer.codePageNotFound(this, e);
} finally {
- closeInputStream(inputStream);
+ super.closeInputStream(inputStream);
}
-
return codePages;
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetType.java b/src/java/org/apache/fop/afp/fonts/CharacterSetType.java
index 8eaaa089b..060d949ac 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetType.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetType.java
@@ -19,13 +19,39 @@
package org.apache.fop.afp.fonts;
+import org.apache.fop.afp.fonts.CharactersetEncoder.DefaultEncoder;
+import org.apache.fop.afp.fonts.CharactersetEncoder.EbcdicDoubleByteLineDataEncoder;
+
/**
* An enumeration of AFP characterset types.
*/
public enum CharacterSetType {
/** Double byte character sets; these do NOT have the shift-in;shift-out operators */
- DOUBLE_BYTE,
+ DOUBLE_BYTE {
+ @Override
+ CharactersetEncoder getEncoder(String encoding) {
+ return new DefaultEncoder(encoding, true);
+ }
+ },
/** Double byte character sets; these can have the shift-in;shift-out operators */
- DOUBLE_BYTE_LINE_DATA,
- SINGLE_BYTE;
+ DOUBLE_BYTE_LINE_DATA {
+ @Override
+ CharactersetEncoder getEncoder(String encoding) {
+ return new EbcdicDoubleByteLineDataEncoder(encoding);
+ }
+ },
+ SINGLE_BYTE {
+ @Override
+ CharactersetEncoder getEncoder(String encoding) {
+ return new DefaultEncoder(encoding, false);
+ }
+ };
+
+ /**
+ * Returns the character-set encoder
+ *
+ * @param encoding
+ * @return
+ */
+ abstract CharactersetEncoder getEncoder(String encoding);
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java b/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
index f101bdab4..983c308cd 100644
--- a/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
@@ -87,7 +87,7 @@ public abstract class CharactersetEncoder {
*/
public static EncodedChars encodeSBCS(CharSequence chars, String encoding)
throws CharacterCodingException {
- CharactersetEncoder encoder = newInstance(encoding, CharacterSetType.SINGLE_BYTE);
+ CharactersetEncoder encoder = CharacterSetType.SINGLE_BYTE.getEncoder(encoding);
return encoder.encode(chars);
}
@@ -97,8 +97,8 @@ public abstract class CharactersetEncoder {
* sequence it will return its EBCDIC code-point, however, the "Shift In - Shift Out" operators
* are removed from the sequence of bytes. These are only used in Line Data.
*/
- private static final class EbcdicDoubleByteLineDataEncoder extends CharactersetEncoder {
- private EbcdicDoubleByteLineDataEncoder(String encoding) {
+ static final class EbcdicDoubleByteLineDataEncoder extends CharactersetEncoder {
+ EbcdicDoubleByteLineDataEncoder(String encoding) {
super(encoding);
}
@Override
@@ -115,10 +115,10 @@ public abstract class CharactersetEncoder {
* the primary format for most Latin character sets. This can also be used for Unicode double-
* byte character sets (DBCS).
*/
- private static final class DefaultEncoder extends CharactersetEncoder {
+ static final class DefaultEncoder extends CharactersetEncoder {
private final boolean isDBCS;
- private DefaultEncoder(String encoding, boolean isDBCS) {
+ DefaultEncoder(String encoding, boolean isDBCS) {
super(encoding);
this.isDBCS = isDBCS;
}
@@ -130,24 +130,6 @@ public abstract class CharactersetEncoder {
}
/**
- * Returns an new instance of a {@link CharactersetEncoder}.
- *
- * @param encoding the encoding for the underlying character encoder
- * @param isEbcdicDBCS whether or not this wraps a double-byte EBCDIC code page.
- * @return the CharactersetEncoder
- */
- static CharactersetEncoder newInstance(String encoding, CharacterSetType charsetType) {
- switch (charsetType) {
- case DOUBLE_BYTE_LINE_DATA:
- return new EbcdicDoubleByteLineDataEncoder(encoding);
- case DOUBLE_BYTE:
- return new DefaultEncoder(encoding, true);
- default:
- return new DefaultEncoder(encoding, false);
- }
- }
-
- /**
* A container for encoded character bytes
*/
// CSOFF: FinalClass - disabling "final" modifier so that this class can be mocked
diff --git a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
index 4514eac5d..a81805bc5 100644
--- a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
+++ b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.lang.Character.UnicodeBlock;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -33,7 +35,7 @@ public class DoubleByteFont extends AbstractOutlineFont {
//See also http://unicode.org/reports/tr11/ which we've not closely looked at, yet
//TODO the Unicode block listed here is probably not complete (ex. Hiragana, Katakana etc.)
- private static final Set IDEOGRAPHIC = new java.util.HashSet();
+ private static final Set<UnicodeBlock> IDEOGRAPHIC = new HashSet<UnicodeBlock>();
static {
IDEOGRAPHIC.add(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS);
//IDEOGRAPHIC.add(Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT);//Java 1.5
@@ -45,10 +47,11 @@ public class DoubleByteFont extends AbstractOutlineFont {
/**
* Constructor for an double-byte outline font.
* @param name the name of the font
+ * @param embeddable whether or not this font is embeddable
* @param charSet the character set
*/
- public DoubleByteFont(String name, CharacterSet charSet) {
- super(name, charSet);
+ public DoubleByteFont(String name, boolean embeddable, CharacterSet charSet) {
+ super(name, embeddable, charSet);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
index f83c38621..7c2b68506 100644
--- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
@@ -20,7 +20,7 @@
package org.apache.fop.afp.fonts;
import org.apache.fop.afp.AFPEventProducer;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Typeface;
/**
@@ -42,7 +42,7 @@ public class FopCharacterSet extends CharacterSet {
*/
public FopCharacterSet(String codePage, String encoding, String name, Typeface charSet,
AFPEventProducer eventProducer) {
- super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, (ResourceAccessor) null,
+ super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, (AFPResourceAccessor) null,
eventProducer);
this.charSet = charSet;
}
diff --git a/src/java/org/apache/fop/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
index 01c605146..103d96eca 100644
--- a/src/java/org/apache/fop/afp/fonts/OutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
@@ -27,10 +27,11 @@ public class OutlineFont extends AbstractOutlineFont {
/**
* Construct outline font with specified name and character set.
* @param name font's name
+ * @param embeddable whether or not this font is embeddable
* @param charSet font's character set
*/
- public OutlineFont(String name, CharacterSet charSet) {
- super(name, charSet);
+ public OutlineFont(String name, boolean embeddable, CharacterSet charSet) {
+ super(name, embeddable, charSet);
}
}
diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java
index 30704b2b0..5c4c38dc5 100644
--- a/src/java/org/apache/fop/afp/fonts/RasterFont.java
+++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java
@@ -52,8 +52,8 @@ public class RasterFont extends AFPFont {
* @param name
* the name of the font
*/
- public RasterFont(String name) {
- super(name);
+ public RasterFont(String name, boolean embeddable) {
+ super(name, embeddable);
}
/**
@@ -76,7 +76,7 @@ public class RasterFont extends AFPFont {
public CharacterSet getCharacterSet(int sizeInMpt) {
Integer requestedSize = Integer.valueOf(sizeInMpt);
- CharacterSet csm = (CharacterSet) charSets.get(requestedSize);
+ CharacterSet csm = charSets.get(requestedSize);
double sizeInPt = sizeInMpt / 1000.0;
if (csm != null) {
@@ -85,7 +85,7 @@ public class RasterFont extends AFPFont {
if (substitutionCharSets != null) {
//Check first if a substitution has already been added
- csm = (CharacterSet) substitutionCharSets.get(requestedSize);
+ csm = substitutionCharSets.get(requestedSize);
}
if (csm == null && !charSets.isEmpty()) {
@@ -95,9 +95,9 @@ public class RasterFont extends AFPFont {
SortedMap<Integer, CharacterSet> smallerSizes = charSets.headMap(requestedSize);
SortedMap<Integer, CharacterSet> largerSizes = charSets.tailMap(requestedSize);
int smallerSize = smallerSizes.isEmpty() ? 0
- : ((Integer)smallerSizes.lastKey()).intValue();
+ : smallerSizes.lastKey().intValue();
int largerSize = largerSizes.isEmpty() ? Integer.MAX_VALUE
- : ((Integer)largerSizes.firstKey()).intValue();
+ : largerSizes.firstKey().intValue();
Integer fontSize;
if (!smallerSizes.isEmpty()
@@ -106,7 +106,7 @@ public class RasterFont extends AFPFont {
} else {
fontSize = Integer.valueOf(largerSize);
}
- csm = (CharacterSet) charSets.get(fontSize);
+ csm = charSets.get(fontSize);
if (csm != null) {
// Add the substitute mapping, so subsequent calls will
diff --git a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
index dc841bd40..9ab84a640 100644
--- a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
+++ b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java
@@ -26,16 +26,15 @@ import java.net.URI;
import org.apache.commons.io.IOUtils;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.afp.util.AFPResourceUtil;
-import org.apache.fop.afp.util.ResourceAccessor;
-
/**
* Encapsulates an included resource object that is loaded from an external file.
*/
public class IncludedResourceObject extends AbstractNamedAFPObject {
- private ResourceAccessor resourceAccessor;
+ private AFPResourceAccessor resourceAccessor;
private URI uri;
/**
@@ -45,7 +44,7 @@ public class IncludedResourceObject extends AbstractNamedAFPObject {
* @param uri the URI of the external file
*/
public IncludedResourceObject(String name,
- ResourceAccessor resourceAccessor, URI uri) {
+ AFPResourceAccessor resourceAccessor, URI uri) {
super(name);
this.resourceAccessor = resourceAccessor;
this.uri = uri;
diff --git a/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java
new file mode 100644
index 000000000..02691527e
--- /dev/null
+++ b/src/java/org/apache/fop/afp/util/AFPResourceAccessor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.afp.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+
+/**
+ * Defines an interface through which external resource objects can be accessed.
+ */
+public final class AFPResourceAccessor {
+
+ private final InternalResourceResolver resourceResolver;
+ private final String baseURI;
+
+ /**
+ * Constructor for resource to be accessed via the {@link org.apache.fop.apps.FOUserAgent}. This
+ * contructor takes a base URI for resolving font resource URIs. So, if fonts need to be
+ * accessed, you can set the {@link FontManager}'s base URI instead of the one on the
+ * {@link org.apache.fop.apps.FopFactory}.
+ *
+ * @param InternalResourceResolver resource resolver
+ * @param baseURI the custom base URI to resolve relative URIs against (may be null)
+ */
+ public AFPResourceAccessor(InternalResourceResolver resourceResolver, String baseURI) {
+ this.resourceResolver = resourceResolver;
+ this.baseURI = baseURI;
+ }
+
+ /**
+ * Constructor for resource to be accessed via the {@link org.apache.fop.apps.FOUserAgent}.
+ *
+ * @param InternalResourceResolver resource resolver
+ */
+ public AFPResourceAccessor(InternalResourceResolver resourceResolver) {
+ this(resourceResolver, null);
+ }
+
+ private URI getResourceURI(URI uri) {
+ if (baseURI == null) {
+ return uri;
+ }
+ try {
+ URI baseURI = InternalResourceResolver.getBaseURI(this.baseURI);
+ return baseURI.resolve(uri);
+ } catch (URISyntaxException use) {
+ return uri;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public InputStream createInputStream(URI uri) throws IOException {
+ return resourceResolver.getResource(getResourceURI(uri));
+ }
+}
diff --git a/src/java/org/apache/fop/afp/util/AFPResourceUtil.java b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
index 538f2b880..979376b3e 100644
--- a/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
+++ b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java
@@ -92,13 +92,10 @@ public final class AFPResourceUtil {
throws UnsupportedEncodingException {
//The first 8 bytes of the field data represent the resource name
byte[] nameBytes = new byte[8];
-
- byte[] fieldData = field.getData();
- if (fieldData.length < 8) {
- throw new IllegalArgumentException("Field data does not contain a resource name");
- }
- System.arraycopy(fieldData, 0, nameBytes, 0, 8);
- return new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
+ System.arraycopy(field.getData(), 0, nameBytes, 0, 8);
+ String asciiName;
+ asciiName = new String(nameBytes, AFPConstants.EBCIDIC_ENCODING);
+ return asciiName;
}
/**
@@ -131,13 +128,12 @@ public final class AFPResourceUtil {
public static void copyNamedResource(String name,
final InputStream in, final OutputStream out) throws IOException {
final MODCAParser parser = new MODCAParser(in);
- Collection<String> resourceNames = new java.util.HashSet<String>();
+ Collection resourceNames = new java.util.HashSet();
//Find matching "Begin" field
final UnparsedStructuredField fieldBegin;
while (true) {
- final UnparsedStructuredField field = parser.readNextStructuredField();
-
+ UnparsedStructuredField field = parser.readNextStructuredField();
if (field == null) {
throw new IOException("Requested resource '" + name
+ "' not found. Encountered resource names: " + resourceNames);
@@ -146,10 +142,8 @@ public final class AFPResourceUtil {
if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin
continue; //Not a "Begin" field
}
- final String resourceName = getResourceName(field);
-
+ String resourceName = getResourceName(field);
resourceNames.add(resourceName);
-
if (resourceName.equals(name)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Start of requested structured field found:\n"
@@ -176,35 +170,45 @@ public final class AFPResourceUtil {
if (wrapInResource) {
ResourceObject resourceObject = new ResourceObject(name) {
protected void writeContent(OutputStream os) throws IOException {
- copyNamedStructuredFields(name, fieldBegin, parser, out);
+ copyStructuredFields(name, fieldBegin, parser, out);
}
};
resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT);
resourceObject.writeToStream(out);
} else {
- copyNamedStructuredFields(name, fieldBegin, parser, out);
+ copyStructuredFields(name, fieldBegin, parser, out);
}
}
- private static void copyNamedStructuredFields(final String name,
- UnparsedStructuredField fieldBegin, MODCAParser parser,
- OutputStream out) throws IOException {
+ private static void copyStructuredFields(String name, UnparsedStructuredField fieldBegin,
+ MODCAParser parser, OutputStream out) throws IOException {
+ boolean inRequestedResource;
- UnparsedStructuredField field = fieldBegin;
+ //The "Begin" field first
+ out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
+ fieldBegin.writeTo(out);
+ UnparsedStructuredField field;
- while (true) {
+ //Then the rest of the fields until the corresponding "End" field
+ inRequestedResource = true;
+ do {
+ field = parser.readNextStructuredField();
if (field == null) {
- throw new IOException("Ending structured field not found for resource " + name);
+ break; //Unexpected EOF
}
- out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
- field.writeTo(out);
- if (field.getSfTypeCode() == TYPE_CODE_END
- && fieldBegin.getSfCategoryCode() == field.getSfCategoryCode()
- && name.equals(getResourceName(field))) {
- break;
+ if (field.getSfTypeCode() == TYPE_CODE_END) {
+ String resourceName = getResourceName(field);
+ if (resourceName.equals(name)) {
+ inRequestedResource = false; //Signal end of loop
+ }
}
- field = parser.readNextStructuredField();
+ out.write(MODCAParser.CARRIAGE_CONTROL_CHAR);
+ field.writeTo(out);
+ } while (inRequestedResource);
+ if (inRequestedResource) {
+ throw new IOException("Ending structured field not found for resource " + name);
}
}
+
}
diff --git a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java b/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
deleted file mode 100644
index 2872976b6..000000000
--- a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp.util;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.commons.io.IOUtils;
-
-import org.apache.fop.apps.FOUserAgent;
-
-/**
- * Default implementation of the {@link ResourceAccessor} interface for use inside FOP.
- */
-public class DefaultFOPResourceAccessor extends SimpleResourceAccessor {
-
- private FOUserAgent userAgent;
- private String categoryBaseURI;
-
- /**
- * Constructor for resource to be accessed via the {@link FOUserAgent}. This contructor
- * can take two base URIs: the category base URI is the one to use when differentiating between
- * normal resources (ex. images) and font resources. So, if fonts need to be accessed, you can
- * set the {@link org.apache.fop.fonts.FontManager}'s base URI instead of the one on the
- * {@link org.apache.fop.apps.FopFactory}.
- * @param userAgent the FO user agent
- * @param categoryBaseURI the category base URI (may be null)
- * @param baseURI the custom base URI to resolve relative URIs against (may be null)
- */
- public DefaultFOPResourceAccessor(FOUserAgent userAgent, String categoryBaseURI, URI baseURI) {
- super(baseURI);
- this.userAgent = userAgent;
- this.categoryBaseURI = categoryBaseURI;
- }
-
- /** {@inheritDoc} */
- public InputStream createInputStream(URI uri) throws IOException {
- //Step 1: resolve against local base URI --> URI
- URI resolved = resolveAgainstBase(uri);
-
- //Step 2: resolve against the user agent --> stream
- String base = (this.categoryBaseURI != null
- ? this.categoryBaseURI
- : this.userAgent.getBaseURL());
- Source src = userAgent.resolveURI(resolved.toASCIIString(), base);
-
- if (src == null) {
- throw new FileNotFoundException("Resource not found: " + uri.toASCIIString());
- } else if (src instanceof StreamSource) {
- StreamSource ss = (StreamSource)src;
- InputStream in = ss.getInputStream();
- if (in != null) {
- return in;
- }
- if (ss.getReader() != null) {
- //Don't support reader, retry using system ID below
- IOUtils.closeQuietly(ss.getReader());
- }
- }
- URL url = new URL(src.getSystemId());
- return url.openStream();
- }
-
-}
diff --git a/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java b/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
deleted file mode 100644
index 7a963928b..000000000
--- a/src/java/org/apache/fop/afp/util/SimpleResourceAccessor.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.afp.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-
-/**
- * Simple implementation of the {@link ResourceAccessor} interface for access relative to a
- * base URI.
- */
-public class SimpleResourceAccessor implements ResourceAccessor {
-
- private URI baseURI;
-
- /**
- * Creates a new simple resource accessor.
- * @param baseURI the base URI to resolve relative URIs against (may be null)
- */
- public SimpleResourceAccessor(URI baseURI) {
- this.baseURI = baseURI;
- }
-
- /**
- * Creates a new simple resource accessor.
- * @param baseDir the base directory to resolve relative filenames against (may be null)
- */
- public SimpleResourceAccessor(File baseDir) {
- this(baseDir != null ? baseDir.toURI() : null);
- }
-
- /**
- * Returns the base URI.
- * @return the base URI (or null if no base URI was set)
- */
- public URI getBaseURI() {
- return this.baseURI;
- }
-
- /**
- * Resolve the given URI against the baseURI.
- * @param uri the URI to resolve
- * @return the resolved URI
- */
- protected URI resolveAgainstBase(URI uri) {
- return (getBaseURI() != null ? getBaseURI().resolve(uri) : uri);
- }
-
- /** {@inheritDoc} */
- public InputStream createInputStream(URI uri) throws IOException {
- URI resolved = resolveAgainstBase(uri);
- URL url = resolved.toURL();
- return url.openStream();
- }
-
-}
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java b/src/java/org/apache/fop/apps/EnvironmentProfile.java
index c9d9ed179..c35219353 100644
--- a/src/java/org/apache/fop/hyphenation/HyphenationTreeResolver.java
+++ b/src/java/org/apache/fop/apps/EnvironmentProfile.java
@@ -17,22 +17,36 @@
/* $Id$ */
-package org.apache.fop.hyphenation;
+package org.apache.fop.apps;
-import javax.xml.transform.Source;
+import java.net.URI;
+
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.fonts.FontManager;
/**
- * <p>This interface is used to resolve relative URIs pointing to hyphenation tree files.</p>
+ * The environment profile represents the restrictions and allowances that FOP is
*/
-public interface HyphenationTreeResolver {
+public interface EnvironmentProfile {
+
+ /**
+ * Returns resource resolver for this environment.
+ *
+ * @return the resource resolver
+ */
+ ResourceResolver getResourceResolver();
/**
- * Called to resolve an URI to a Source instance. The base URI needed by the URIResolver's
- * resolve() method is defined to be implicitely available in this case. If the URI cannot
- * be resolved, null is returned.
- * @param href An href attribute, which may be relative or absolute.
- * @return A Source object, or null if the href could not resolved.
+ * Returns the font manager with restrictions/allowances set for this environment.
+ *
+ * @return the font manager
*/
- Source resolve(String href);
+ FontManager getFontManager();
+ /**
+ * The default base URI used for resolving URIs.
+ *
+ * @return the default base URI
+ */
+ URI getDefaultBaseURI();
}
diff --git a/src/java/org/apache/fop/apps/EnvironmentalProfileFactory.java b/src/java/org/apache/fop/apps/EnvironmentalProfileFactory.java
new file mode 100644
index 000000000..374074b8a
--- /dev/null
+++ b/src/java/org/apache/fop/apps/EnvironmentalProfileFactory.java
@@ -0,0 +1,113 @@
+/*
+ * 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.net.URI;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.FontCacheManager;
+import org.apache.fop.fonts.FontCacheManagerFactory;
+import org.apache.fop.fonts.FontDetector;
+import org.apache.fop.fonts.FontDetectorFactory;
+import org.apache.fop.fonts.FontManager;
+
+/**
+ * Creates an {@link EnvironmentProfile} that sets the environment in which a FOP instance is run.
+ */
+public final class EnvironmentalProfileFactory {
+
+ private EnvironmentalProfileFactory() {
+ };
+
+ /**
+ * Creates the default environment that FOP is invoked in. This default profile has no
+ * operational restrictions for FOP.
+ *
+ * @param defaultBaseUri the default base URI for resolving resource URIs
+ * @param resourceResolver the resource resolver
+ * @return the environment profile
+ */
+ public static EnvironmentProfile createDefault(URI defaultBaseUri,
+ ResourceResolver resourceResolver) {
+ return new Profile(defaultBaseUri, resourceResolver,
+ createFontManager(defaultBaseUri, resourceResolver,
+ FontDetectorFactory.createDefault(),
+ FontCacheManagerFactory.createDefault()));
+ }
+
+ /**
+ * Creates an IO-restricted environment for FOP by disabling some of the environment-specific
+ * functionality within FOP.
+ *
+ * @param defaultBaseUri the default base URI for resolving resource URIs
+ * @param resourceResolver the resource resolver
+ * @return the environment profile
+ */
+ public static EnvironmentProfile createRestrictedIO(URI defaultBaseUri,
+ ResourceResolver resourceResolver) {
+ return new Profile(defaultBaseUri, resourceResolver,
+ createFontManager(defaultBaseUri, resourceResolver,
+ FontDetectorFactory.createDisabled(),
+ FontCacheManagerFactory.createDisabled()));
+ }
+
+ private static final class Profile implements EnvironmentProfile {
+
+ private final ResourceResolver resourceResolver;
+
+ private final FontManager fontManager;
+
+ private final URI defaultBaseURI;
+
+ private Profile(URI defaultBaseURI, ResourceResolver resourceResolver,
+ FontManager fontManager) {
+ if (defaultBaseURI == null) {
+ throw new IllegalArgumentException("Default base URI must not be null");
+ }
+ if (resourceResolver == null) {
+ throw new IllegalArgumentException("URI Resolver must not be null");
+ }
+ this.defaultBaseURI = defaultBaseURI;
+ this.resourceResolver = resourceResolver;
+ this.fontManager = fontManager;
+ }
+
+ public ResourceResolver getResourceResolver() {
+ return resourceResolver;
+ }
+
+ public FontManager getFontManager() {
+ return fontManager;
+ }
+
+ public URI getDefaultBaseURI() {
+ return defaultBaseURI;
+ }
+ }
+
+ private static FontManager createFontManager(URI defaultBaseUri, ResourceResolver resourceResolver,
+ FontDetector fontDetector, FontCacheManager fontCacheManager) {
+ InternalResourceResolver internalResolver = ResourceResolverFactory.createInternalResourceResolver(
+ defaultBaseUri, resourceResolver);
+ return new FontManager(internalResolver, fontDetector, fontCacheManager);
+ }
+}
diff --git a/src/java/org/apache/fop/apps/FOURIResolver.java b/src/java/org/apache/fop/apps/FOURIResolver.java
deleted file mode 100644
index a1d7fd673..000000000
--- a/src/java/org/apache/fop/apps/FOURIResolver.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.apps;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
-
-import javax.xml.transform.Source;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.URIResolver;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.util.io.Base64EncodeStream;
-import org.apache.xmlgraphics.util.uri.CommonURIResolver;
-
-/**
- * Provides FOP specific URI resolution. This is the default URIResolver
- * {@link FOUserAgent} will use unless overridden.
- *
- * @see javax.xml.transform.URIResolver
- */
-public class FOURIResolver implements javax.xml.transform.URIResolver {
-
- // log
- private Log log = LogFactory.getLog("FOP");
-
- /** Common URIResolver */
- private CommonURIResolver commonURIResolver = new CommonURIResolver();
-
- /** A user settable URI Resolver */
- private URIResolver uriResolver = null;
-
- /** true if exceptions are to be thrown if the URIs cannot be resolved. */
- private boolean throwExceptions = false;
-
- /**
- * Checks if the given base URL is acceptable. It also normalizes the URL.
- * @param base the base URL to check
- * @return the normalized URL
- * @throws MalformedURLException if there's a problem with a file URL
- */
- public String checkBaseURL(String base) throws MalformedURLException {
- // replace back slash with forward slash to ensure windows file:/// URLS are supported
- base = base.replace('\\', '/');
- 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);
- if (dir.isDirectory()) {
- return dir.toURI().toASCIIString();
- } else {
- URI baseURI;
- try {
- baseURI = new URI(base);
- String scheme = baseURI.getScheme();
- boolean directoryExists = true;
- if ("file".equals(scheme)) {
- dir = FileUtils.toFile(baseURI.toURL());
- directoryExists = dir.isDirectory();
- }
- if (scheme == null || !directoryExists) {
- String message = "base " + base + " is not a valid directory";
- if (throwExceptions) {
- throw new MalformedURLException(message);
- }
- log.error(message);
- }
- return baseURI.toASCIIString();
- } catch (URISyntaxException e) {
- //TODO not ideal: our base URLs are actually base URIs.
- throw new MalformedURLException(e.getMessage());
- }
- }
- }
-
- /**
- * 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 e
- * the exception
- * @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)} This
- * resolver will allow URLs without a scheme, i.e. it assumes 'file:' as the
- * default scheme. It also allows relative URLs with scheme, e.g.
- * file:../../abc.jpg which is not strictly RFC compliant as long as the
- * scheme is the same as the scheme of the base URL. If the base URL is null
- * a 'file:' URL referencing the current directory is used as the base URL.
- * If the method is successful it will return a Source of type
- * {@link javax.xml.transform.stream.StreamSource} with its SystemID set to
- * the resolved URL used to open the underlying InputStream.
- *
- * @param href
- * An href attribute, which may be relative or absolute.
- * @param base
- * The base URI against which the first argument will be made
- * absolute if the absolute URI is required.
- * @return A {@link javax.xml.transform.Source} object, or null if the href
- * cannot be resolved.
- * @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 TransformerException {
- Source source = null;
-
- // data URLs can be quite long so evaluate early and don't try to build a File
- // (can lead to problems)
- source = commonURIResolver.resolve(href, base);
-
- // Custom uri resolution
- if (source == null && uriResolver != null) {
- source = uriResolver.resolve(href, base);
- }
-
- // Fallback to default resolution mechanism
- if (source == null) {
- URL absoluteURL = null;
- int hashPos = href.indexOf('#');
- String fileURL;
- String fragment;
- if (hashPos >= 0) {
- fileURL = href.substring(0, hashPos);
- fragment = href.substring(hashPos);
- } else {
- fileURL = href;
- fragment = null;
- }
- File file = new File(fileURL);
- if (file.canRead() && file.isFile()) {
- try {
- if (fragment != null) {
- absoluteURL = new URL(file.toURI().toURL().toExternalForm() + fragment);
- } else {
- absoluteURL = file.toURI().toURL();
- }
- } catch (MalformedURLException mfue) {
- handleException(mfue, "Could not convert filename '" + href
- + "' to URL", throwExceptions);
- }
- } else {
- // no base provided
- if (base == null) {
- // We don't have a valid file protocol based URL
- try {
- absoluteURL = new URL(href);
- } catch (MalformedURLException mue) {
- try {
- // the above failed, we give it another go in case
- // the href contains only a path then file: is
- // assumed
- absoluteURL = new URL("file:" + href);
- } catch (MalformedURLException mfue) {
- handleException(mfue, "Error with URL '" + href
- + "'", throwExceptions);
- }
- }
-
- // try and resolve from context of base
- } else {
- URL baseURL = null;
- try {
- baseURL = new URL(base);
- } catch (MalformedURLException mfue) {
- handleException(mfue, "Error with base URL '" + base
- + "'", throwExceptions);
- }
-
- /*
- * 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.
- */
- assert (baseURL != null);
- String scheme = baseURL.getProtocol() + ":";
- if (href.startsWith(scheme) && "file:".equals(scheme)) {
- href = href.substring(scheme.length());
- 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) {
- handleException(mfue, "Error with URL; base '" + base
- + "' " + "href '" + href + "'", throwExceptions);
- }
- }
- }
-
- 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 source;
- }
-
- /**
- * This method allows you to set special values on a URLConnection just
- * before the connect() method is called. Subclass FOURIResolver and
- * override this method to do things like adding the user name and password
- * for HTTP basic authentication.
- *
- * @param connection
- * the URLConnection instance
- * @param href
- * the original URI
- */
- protected void updateURLConnection(URLConnection connection, String href) {
- // nop
- }
-
- /**
- * This is a convenience method for users who want to override
- * updateURLConnection for HTTP basic authentication. Simply call it using
- * the right username and password.
- *
- * @param connection
- * the URLConnection to set up for HTTP basic authentication
- * @param username
- * the username
- * @param password
- * the password
- */
- protected void applyHttpBasicAuthentication(URLConnection connection,
- String username, String password) {
- String combined = username + ":" + password;
- try {
- ByteArrayOutputStream baout = new ByteArrayOutputStream(combined
- .length() * 2);
- Base64EncodeStream base64 = new Base64EncodeStream(baout);
- // TODO Not sure what charset/encoding can be used with basic
- // authentication
- base64.write(combined.getBytes("UTF-8"));
- base64.close();
- connection.setRequestProperty("Authorization", "Basic "
- + new String(baout.toByteArray(), "UTF-8"));
- } catch (IOException e) {
- // won't happen. We're operating in-memory.
- throw new RuntimeException(
- "Error during base64 encodation of username/password");
- }
- }
-
- /**
- * Sets the custom URI Resolver. It is used for resolving factory-level URIs like
- * hyphenation patterns and as backup for URI resolution performed during a
- * rendering run.
- *
- * @param resolver
- * the new URI resolver
- */
- public void setCustomURIResolver(URIResolver resolver) {
- this.uriResolver = resolver;
- }
-
- /**
- * Returns the custom URI Resolver.
- *
- * @return the URI Resolver or null, if none is set
- */
- public URIResolver getCustomURIResolver() {
- return this.uriResolver;
- }
-
- /**
- * @param throwExceptions
- * Whether or not to throw exceptions on resolution error
- */
- public void setThrowExceptions(boolean throwExceptions) {
- this.throwExceptions = throwExceptions;
- }
-}
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
index 035b6f1a1..488b62474 100644
--- a/src/java/org/apache/fop/apps/FOUserAgent.java
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -21,18 +21,22 @@ package org.apache.fop.apps;
// Java
import java.io.File;
-import java.net.MalformedURLException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URISyntaxException;
import java.util.Date;
import java.util.Map;
import javax.xml.transform.Source;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.URIResolver;
+import javax.xml.transform.stream.StreamSource;
+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.xmlgraphics.image.loader.ImageContext;
+import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
import org.apache.xmlgraphics.util.UnitConv;
@@ -41,17 +45,27 @@ import org.apache.fop.Version;
import org.apache.fop.accessibility.Accessibility;
import org.apache.fop.accessibility.DummyStructureTreeEventHandler;
import org.apache.fop.accessibility.StructureTreeEventHandler;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.events.DefaultEventBroadcaster;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.FOPEventListenerProxy;
import org.apache.fop.events.LoggingEventListener;
+import org.apache.fop.fo.ElementMappingRegistry;
import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.layoutmgr.LayoutManagerMaker;
+import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
+import org.apache.fop.render.RendererConfigOption;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.util.ColorSpaceCache;
+import org.apache.fop.util.ContentHandlerFactoryRegistry;
/**
* This is the user agent for FOP.
@@ -75,24 +89,13 @@ import org.apache.fop.render.intermediate.IFDocumentHandler;
*/
public class FOUserAgent {
- /** Defines the default target resolution (72dpi) for FOP */
- 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 base = null;
+ private final FopFactory factory;
- /** A user settable URI Resolver */
- private URIResolver uriResolver = null;
+ private final InternalResourceResolver resourceResolver;
- private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+ private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
private Map rendererOptions = new java.util.HashMap();
private File outputFile = null;
private IFDocumentHandler documentHandlerOverride = null;
@@ -131,7 +134,7 @@ public class FOUserAgent {
private ImageSessionContext imageSessionContext = new AbstractImageSessionContext() {
public ImageContext getParentContext() {
- return getFactory();
+ return factory;
}
public float getTargetResolution() {
@@ -148,21 +151,59 @@ public class FOUserAgent {
* Main constructor. <b>This constructor should not be called directly. Please use the
* methods from FopFactory to construct FOUserAgent instances!</b>
* @param factory the factory that provides environment-level information
+ * @param resourceResolver the resolver used to acquire resources
* @see org.apache.fop.apps.FopFactory
*/
- public FOUserAgent(FopFactory factory) {
- if (factory == null) {
- throw new NullPointerException("The factory parameter must not be null");
- }
+ FOUserAgent(FopFactory factory, InternalResourceResolver resourceResolver) {
this.factory = factory;
- setBaseURL(factory.getBaseURL());
+ this.resourceResolver = resourceResolver;
setTargetResolution(factory.getTargetResolution());
setAccessibility(factory.isAccessibilityEnabled());
}
- /** @return the associated FopFactory instance */
- public FopFactory getFactory() {
- return this.factory;
+ /**
+ * Returns a new {@link Fop} instance. Use this factory method if your output type
+ * requires an output stream and you want to configure this very rendering run,
+ * i.e. if you want to set some metadata like the title and author of the document
+ * you want to render. In that case, create a new {@link FOUserAgent} instance
+ * using {@link #newFOUserAgent()}.
+ * <p>
+ * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
+ * use the constants defined in {@link MimeConstants}.
+ * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
+ * @param stream the output stream
+ * @return the new Fop instance
+ * @throws FOPException when the constructor fails
+ */
+ public Fop newFop(String outputFormat, OutputStream stream) throws FOPException {
+ return new Fop(outputFormat, this, stream);
+ }
+
+
+ /**
+ * Returns a new {@link Fop} instance. Use this factory method if you want to configure this
+ * very rendering run, i.e. if you want to set some metadata like the title and author of the
+ * document you want to render. In that case, create a new {@link FOUserAgent}
+ * instance using {@link #newFOUserAgent()}.
+ * <p>
+ * MIME types are used to select the output format (ex. "application/pdf" for PDF). You can
+ * use the constants defined in {@link MimeConstants}.
+ * @param outputFormat the MIME type of the output format to use (ex. "application/pdf").
+ * @return the new Fop instance
+ * @throws FOPException when the constructor fails
+ */
+ public Fop newFop(String outputFormat) throws FOPException {
+ return newFop(outputFormat, null);
+ }
+
+
+ /**
+ * Returns the resource resolver.
+ *
+ * @return the resource resolver
+ */
+ public InternalResourceResolver getResourceResolver() {
+ return resourceResolver;
}
// ---------------------------------------------- rendering-run dependent stuff
@@ -177,7 +218,6 @@ public class FOUserAgent {
setStructureTreeEventHandler(documentHandler.getStructureTreeEventHandler());
}
this.documentHandlerOverride = documentHandler;
-
}
/**
@@ -345,48 +385,13 @@ public class FOUserAgent {
}
/**
- * Sets the base URL.
- * @param baseUrl base URL
- */
- public void setBaseURL(String baseUrl) {
- this.base = baseUrl;
- }
-
- /**
- * Sets font base URL.
- * @param fontBaseUrl font base URL
- * @deprecated Use {@link org.apache.fop.fonts.FontManager#setFontBaseURL(String)} instead.
- */
- public void setFontBaseURL(String fontBaseUrl) {
- try {
- getFactory().getFontManager().setFontBaseURL(fontBaseUrl);
- } catch (MalformedURLException e) {
- throw new IllegalArgumentException(e.getMessage());
- }
- }
-
- /**
- * Returns the base URL.
- * @return the base URL
- */
- public String getBaseURL() {
- return this.base;
- }
-
- /**
- * Sets the URI Resolver.
- * @param resolver the new URI resolver
- */
- public void setURIResolver(URIResolver resolver) {
- this.uriResolver = resolver;
- }
-
- /**
- * Returns the URI Resolver.
- * @return the URI Resolver
- */
- public URIResolver getURIResolver() {
- return this.uriResolver;
+ * Gets the renderer options given an interface representing renderer configuration options.
+ *
+ * @param option the renderer option
+ * @return the value
+ */
+ public Object getRendererOption(RendererConfigOption option) {
+ return rendererOptions.get(option.getName());
}
/**
@@ -396,39 +401,20 @@ public class FOUserAgent {
* @param uri URI to access
* @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) {
- return resolveURI(uri, getBaseURL());
- }
-
- /**
- * Attempts to resolve the given URI.
- * Will use the configured resolver and if not successful fall back
- * to the default resolver.
- * @param href URI to access
- * @param base 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 href, String base) {
- Source source = null;
- //RFC 2397 data URLs don't need to be resolved, just decode them through FOP's default
- //URIResolver.
- boolean bypassURIResolution = href.startsWith("data:");
- if (!bypassURIResolution && uriResolver != null) {
- try {
- source = uriResolver.resolve(href, base);
- } catch (TransformerException te) {
- log.error("Attempt to resolve URI '" + href + "' failed: ", te);
- }
- }
- if (source == null) {
- // URI Resolver not configured or returned null, use default resolver from the factory
- source = getFactory().resolveURI(href, base);
+ public StreamSource resolveURI(String uri) {
+ // TODO: What do we want to do when resources aren't found??? We also need to remove this
+ // method entirely
+ try {
+ // Have to do this so we can resolve data URIs
+ StreamSource src = new StreamSource(resourceResolver.getResource(uri));
+ src.setSystemId(uri);
+ return src;
+ } catch (URISyntaxException use) {
+ return null;
+ } catch (IOException ioe) {
+ return null;
}
- return source;
}
/**
@@ -498,29 +484,18 @@ public class FOUserAgent {
// (convenience access to FopFactory methods)
/**
- * Returns the font base URL.
- * @return the font base URL
- * @deprecated Use {@link org.apache.fop.fonts.FontManager#getFontBaseURL()} instead.
- * This method is not used by FOP.
- */
- public String getFontBaseURL() {
- String fontBase = getFactory().getFontManager().getFontBaseURL();
- return fontBase != null ? fontBase : getBaseURL();
- }
-
- /**
* Returns the conversion factor from pixel units to millimeters. This
* depends on the desired source resolution.
* @return float conversion factor
* @see #getSourceResolution()
*/
public float getSourcePixelUnitToMillimeter() {
- return getFactory().getSourcePixelUnitToMillimeter();
+ return factory.getSourcePixelUnitToMillimeter();
}
/** @return the resolution for resolution-dependant input */
public float getSourceResolution() {
- return getFactory().getSourceResolution();
+ return factory.getSourceResolution();
}
/**
@@ -531,7 +506,7 @@ public class FOUserAgent {
* @see FopFactory#getPageHeight()
*/
public String getPageHeight() {
- return getFactory().getPageHeight();
+ return factory.getPageHeight();
}
/**
@@ -542,7 +517,7 @@ public class FOUserAgent {
* @see FopFactory#getPageWidth()
*/
public String getPageWidth() {
- return getFactory().getPageWidth();
+ return factory.getPageWidth();
}
/**
@@ -551,7 +526,7 @@ public class FOUserAgent {
* @see FopFactory#validateStrictly()
*/
public boolean validateStrictly() {
- return getFactory().validateStrictly();
+ return factory.validateStrictly();
}
/**
@@ -560,21 +535,21 @@ public class FOUserAgent {
* @see FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()
*/
public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
- return getFactory().isBreakIndentInheritanceOnReferenceAreaBoundary();
+ return factory.isBreakIndentInheritanceOnReferenceAreaBoundary();
}
/**
* @return the RendererFactory
*/
public RendererFactory getRendererFactory() {
- return getFactory().getRendererFactory();
+ return factory.getRendererFactory();
}
/**
* @return the XML handler registry
*/
public XMLHandlerRegistry getXMLHandlerRegistry() {
- return getFactory().getXMLHandlerRegistry();
+ return factory.getXMLHandlerRegistry();
}
/**
@@ -663,12 +638,53 @@ public class FOUserAgent {
}
/**
- * Control whether complex script features should be enabled
+ * Returns the renderer configuration object for a particular MIME type.
*
- * @param useComplexScriptFeatures true if FOP is to use complex script features
+ * @param mimeType the config MIME type
+ * @param configCreator the parser for creating the config for the first run of parsing.
+ * @return the renderer configuration object
+ * @throws FOPException if an error occurs when creating the config object
*/
- public void setComplexScriptFeaturesEnabled(boolean useComplexScriptFeatures) {
- factory.setComplexScriptFeaturesEnabled ( useComplexScriptFeatures );
+ public RendererConfig getRendererConfig(String mimeType, RendererConfigParser configCreator)
+ throws FOPException {
+ return factory.getRendererConfig(this, getRendererConfiguration(mimeType), configCreator);
+ }
+
+ /**
+ * Returns a {@link Configuration} object for which contains renderer configuration for a given
+ * MIME type.
+ *
+ * @param mimeType the renderer configuration MIME type
+ * @return the configuration object
+ */
+ public Configuration getRendererConfiguration(String mimeType) {
+ Configuration cfg = getUserConfig();
+ String type = "renderer";
+ String mime = "mime";
+ if (cfg == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("userconfig is null");
+ }
+ return null;
+ }
+
+ Configuration userConfig = null;
+
+ Configuration[] cfgs = cfg.getChild(type + "s").getChildren(type);
+ for (int i = 0; i < cfgs.length; ++i) {
+ Configuration child = cfgs[i];
+ try {
+ if (child.getAttribute(mime).equals(mimeType)) {
+ userConfig = child;
+ break;
+ }
+ } catch (ConfigurationException e) {
+ // silently pass over configurations without mime type
+ }
+ }
+ log.debug((userConfig == null ? "No u" : "U")
+ + "ser configuration found for MIME type " + mimeType);
+ return userConfig;
}
/**
@@ -714,5 +730,69 @@ public class FOUserAgent {
public StructureTreeEventHandler getStructureTreeEventHandler() {
return this.structureTreeEventHandler;
}
+
+ /** @see FopFactory#getLayoutManagerMakerOverride() */
+ public LayoutManagerMaker getLayoutManagerMakerOverride() {
+ return factory.getLayoutManagerMakerOverride();
+ }
+
+ /** @see FopFactory#getContentHandlerFactoryRegistry() */
+ public ContentHandlerFactoryRegistry getContentHandlerFactoryRegistry() {
+ return factory.getContentHandlerFactoryRegistry();
+ }
+
+ /** @see FopFactory#getImageManager() */
+ public ImageManager getImageManager() {
+ return factory.getImageManager();
+ }
+
+ /** @see FopFactory#getElementMappingRegistry() */
+ public ElementMappingRegistry getElementMappingRegistry() {
+ return factory.getElementMappingRegistry();
+ }
+
+ /** @see FopFactory#getFontManager() */
+ public FontManager getFontManager() {
+ return factory.getFontManager();
+ }
+
+ /**
+ * Indicates whether a namespace URI is on the ignored list.
+ * @param namespaceURI the namespace URI
+ * @return true if the namespace is ignored by FOP
+ */
+ public boolean isNamespaceIgnored(String namespaceURI) {
+ return factory.isNamespaceIgnored(namespaceURI);
+ }
+
+ /**
+ * Is the user configuration to be validated?
+ * @return if the user configuration should be validated
+ */
+ public boolean validateUserConfigStrictly() {
+ return factory.validateUserConfigStrictly();
+ }
+
+ /**
+ * Get the user configuration.
+ * @return the user configuration
+ */
+ public Configuration getUserConfig() {
+ return factory.getUserConfig();
+ }
+
+ /** @return the image handler registry */
+ public ImageHandlerRegistry getImageHandlerRegistry() {
+ return factory.getImageHandlerRegistry();
+ }
+
+ /** TODO: javadoc*/
+ public ColorSpaceCache getColorSpaceCache() {
+ return factory.getColorSpaceCache();
+ }
+
+ public Map<String, String> getHyphPatNames() {
+ return factory.getHyphPatNames();
+ }
}
diff --git a/src/java/org/apache/fop/apps/Fop.java b/src/java/org/apache/fop/apps/Fop.java
index 0527ea290..fc82ac1cb 100644
--- a/src/java/org/apache/fop/apps/Fop.java
+++ b/src/java/org/apache/fop/apps/Fop.java
@@ -66,12 +66,12 @@ public class Fop {
* @throws FOPException if setting up the DefaultHandler fails
*/
Fop(String outputFormat, FOUserAgent ua, OutputStream stream) throws FOPException {
+ if (ua == null) {
+ throw new FOPException("Cannot create a new Fop instance without a User Agent.");
+ }
this.outputFormat = outputFormat;
foUserAgent = ua;
- if (foUserAgent == null) {
- foUserAgent = FopFactory.newInstance().newFOUserAgent();
- }
this.stream = stream;
diff --git a/src/java/org/apache/fop/apps/FopConfParser.java b/src/java/org/apache/fop/apps/FopConfParser.java
new file mode 100644
index 000000000..bf39a53f0
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FopConfParser.java
@@ -0,0 +1,348 @@
+/*
+ * 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.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+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.xmlgraphics.image.loader.spi.ImageImplRegistry;
+import org.apache.xmlgraphics.image.loader.util.Penalty;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.FontManagerConfigurator;
+import org.apache.fop.hyphenation.HyphenationTreeCache;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * Parses the FOP configuration file and returns a {@link FopFactoryBuilder} which builds a
+ * {@link FopFactory}.
+ */
+public class FopConfParser {
+
+ private static final String PREFER_RENDERER = "prefer-renderer";
+
+ private final Log log = LogFactory.getLog(FopConfParser.class);
+
+ private final FopFactoryBuilder fopFactoryBuilder;
+
+ /**
+ * Constructor that takes the FOP conf in the form of an {@link InputStream}. A default base URI
+ * must be given as a fall-back mechanism for URI resolution.
+ *
+ * @param fopConfStream the fop conf input stream
+ * @param enviro the profile of the FOP deployment environment
+ * @throws SAXException if a SAX error was thrown parsing the FOP conf
+ * @throws IOException if an I/O error is thrown while parsing the FOP conf
+ */
+ public FopConfParser(InputStream fopConfStream, EnvironmentProfile enviro)
+ throws SAXException, IOException {
+ DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
+ Configuration cfg;
+ try {
+ cfg = cfgBuilder.build(fopConfStream);
+ } catch (ConfigurationException e) {
+ throw new FOPException(e);
+ }
+ // The default base URI is taken from the directory in which the fopConf resides
+ fopFactoryBuilder = new FopFactoryBuilder(enviro).setConfiguration(cfg);
+ configure(enviro.getDefaultBaseURI(), enviro.getResourceResolver(), cfg);
+ }
+
+ /**
+ * Constructor that takes the FOP conf in the form of an {@link InputStream}. A default base URI
+ * must be given as a fall-back mechanism for URI resolution.
+ *
+ * @param fopConfStream the fop conf input stream
+ * @param defaultBaseURI the default base URI
+ * @param resourceResolver the URI resolver
+ * @throws SAXException if a SAX error was thrown parsing the FOP conf
+ * @throws IOException if an I/O error is thrown while parsing the FOP conf
+ */
+ public FopConfParser(InputStream fopConfStream, URI defaultBaseURI,
+ ResourceResolver resourceResolver) throws SAXException, IOException {
+ this(fopConfStream, EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
+ }
+
+ /**
+ * Constructor that takes the FOP conf in the form of an {@link InputStream}. A default base URI
+ * must be given as a fall-back mechanism for URI resolution. The default URI resolvers is used.
+ *
+ * @param fopConfStream the fop conf input stream
+ * @param defaultBaseURI the default base URI
+ * @throws SAXException if a SAX error was thrown parsing the FOP conf
+ * @throws IOException if an I/O error is thrown while parsing the FOP conf
+ */
+ public FopConfParser(InputStream fopConfStream, URI defaultBaseURI) throws SAXException,
+ IOException {
+ this(fopConfStream, defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver());
+ }
+
+ /**
+ * Constructor that takes the FOP conf and uses the default URI resolver.
+ *
+ * @param fopConfFile the FOP conf file
+ * @throws SAXException if a SAX error was thrown parsing the FOP conf
+ * @throws IOException if an I/O error is thrown while parsing the FOP conf
+ */
+ public FopConfParser(File fopConfFile) throws SAXException, IOException {
+ this(fopConfFile, ResourceResolverFactory.createDefaultResourceResolver());
+ }
+
+ /**
+ * Constructor that parses the FOP conf and uses the URI resolver given.
+ *
+ * @param fopConfFile the FOP conf file
+ * @param resourceResolver the URI resolver
+ * @throws SAXException if a SAX error was thrown parsing the FOP conf
+ * @throws IOException if an I/O error is thrown while parsing the FOP conf
+ */
+ public FopConfParser(File fopConfFile, ResourceResolver resourceResolver)
+ throws SAXException, IOException {
+ this(new FileInputStream(fopConfFile),
+ fopConfFile.getAbsoluteFile().getParentFile().toURI(), resourceResolver);
+ }
+
+ private void configure(final URI defaultBaseURI, final ResourceResolver resourceResolver,
+ Configuration cfg) throws FOPException {
+ if (log.isDebugEnabled()) {
+ log.debug("Initializing FopFactory Configuration");
+ }
+
+ // TODO: This makes this variable both strict FO and user-config validation, is that right?
+ boolean strict = false;
+ // strict fo validation
+ if (cfg.getChild("strict-validation", false) != null) {
+ try {
+ strict = cfg.getChild("strict-validation").getValueAsBoolean();
+ fopFactoryBuilder.setStrictUserConfigValidation(strict);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, false);
+ }
+ }
+
+ if (cfg.getChild("accessibility", false) != null) {
+ try {
+ fopFactoryBuilder.setAccessibility(cfg.getChild("accessibility").getValueAsBoolean());
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, false);
+ }
+ }
+
+ // base definitions for relative path resolution
+ if (cfg.getChild("base", false) != null) {
+ try {
+ URI confUri = InternalResourceResolver.getBaseURI(cfg.getChild("base").getValue(null));
+ fopFactoryBuilder.setBaseURI(defaultBaseURI.resolve(confUri));
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(log, use, strict);
+ }
+ }
+
+ // renderer options
+ if (cfg.getChild("source-resolution", false) != null) {
+ float srcRes = cfg.getChild("source-resolution").getValueAsFloat(
+ FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION);
+ fopFactoryBuilder.setSourceResolution(srcRes);
+ if (log.isDebugEnabled()) {
+ log.debug("source-resolution set to: " + srcRes + "dpi");
+ }
+ }
+ if (cfg.getChild("target-resolution", false) != null) {
+ float targetRes = cfg.getChild("target-resolution").getValueAsFloat(
+ FopFactoryConfig.DEFAULT_TARGET_RESOLUTION);
+ fopFactoryBuilder.setTargetResolution(targetRes);
+ if (log.isDebugEnabled()) {
+ log.debug("target-resolution set to: " + targetRes + "dpi");
+ }
+ }
+ if (cfg.getChild("break-indent-inheritance", false) != null) {
+ try {
+ fopFactoryBuilder.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) {
+ String pageHeight = pageConfig.getAttribute("height",
+ FopFactoryConfig.DEFAULT_PAGE_HEIGHT);
+ fopFactoryBuilder.setPageHeight(pageHeight);
+ if (log.isInfoEnabled()) {
+ log.info("Default page-height set to: " + pageHeight);
+ }
+ }
+ if (pageConfig.getAttribute("width", null) != null) {
+ String pageWidth = pageConfig.getAttribute("width",
+ FopFactoryConfig.DEFAULT_PAGE_WIDTH);
+ fopFactoryBuilder.setPageWidth(pageWidth);
+ if (log.isInfoEnabled()) {
+ log.info("Default page-width set to: " + pageWidth);
+ }
+ }
+
+ if (cfg.getChild("complex-scripts") != null) {
+ Configuration csConfig = cfg.getChild("complex-scripts");
+ fopFactoryBuilder.setComplexScriptFeatures(!csConfig.getAttributeAsBoolean("disabled",
+ false));
+ }
+
+ setHyphPatNames(cfg, fopFactoryBuilder, strict);
+
+ // prefer Renderer over IFDocumentHandler
+ if (cfg.getChild(PREFER_RENDERER, false) != null) {
+ try {
+ fopFactoryBuilder.setPreferRenderer(
+ cfg.getChild(PREFER_RENDERER).getValueAsBoolean());
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ }
+
+ // configure font manager
+ new FontManagerConfigurator(cfg, fopFactoryBuilder.getBaseURI(), resourceResolver).configure(
+ fopFactoryBuilder.getFontManager(), strict);
+
+ // configure image loader framework
+ configureImageLoading(cfg.getChild("image-loading", false), strict);
+ }
+
+ private void setHyphPatNames(Configuration cfg, FopFactoryBuilder builder, boolean strict)
+ throws FOPException {
+ Configuration[] hyphPatConfig = cfg.getChildren("hyphenation-pattern");
+ if (hyphPatConfig.length != 0) {
+ Map<String, String> hyphPatNames = new HashMap<String, String>();
+ for (int i = 0; i < hyphPatConfig.length; ++i) {
+ String lang;
+ String country;
+ String filename;
+ StringBuffer error = new StringBuffer();
+ String location = hyphPatConfig[i].getLocation();
+
+ lang = hyphPatConfig[i].getAttribute("lang", null);
+ if (lang == null) {
+ addError("The lang attribute of a hyphenation-pattern configuration"
+ + " element must exist (" + location + ")", error);
+ } else if (!lang.matches("[a-zA-Z]{2}")) {
+ addError("The lang attribute of a hyphenation-pattern configuration"
+ + " element must consist of exactly two letters ("
+ + location + ")", error);
+ }
+ lang = lang.toLowerCase(Locale.getDefault());
+
+ country = hyphPatConfig[i].getAttribute("country", null);
+ if ("".equals(country)) {
+ country = null;
+ }
+ if (country != null) {
+ if (!country.matches("[a-zA-Z]{2}")) {
+ addError("The country attribute of a hyphenation-pattern configuration"
+ + " element must consist of exactly two letters ("
+ + location + ")", error);
+ }
+ country = country.toUpperCase(Locale.getDefault());
+ }
+
+ filename = hyphPatConfig[i].getValue(null);
+ if (filename == null) {
+ addError("The value of a hyphenation-pattern configuration"
+ + " element may not be empty (" + location + ")", error);
+ }
+
+ if (error.length() != 0) {
+ LogUtil.handleError(log, error.toString(), strict);
+ continue;
+ }
+
+ String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
+ hyphPatNames.put(llccKey, filename);
+ if (log.isDebugEnabled()) {
+ log.debug("Using hyphenation pattern filename " + filename
+ + " for lang=\"" + lang + "\""
+ + (country != null ? ", country=\"" + country + "\"" : ""));
+ }
+ }
+ builder.setHyphPatNames(hyphPatNames);
+ }
+ }
+
+ private static void addError(String message, StringBuffer error) {
+ if (error.length() != 0) {
+ error.append(". ");
+ }
+ error.append(message);
+ }
+
+ private void configureImageLoading(Configuration parent, boolean strict) throws FOPException {
+ if (parent == null) {
+ return;
+ }
+ ImageImplRegistry registry = fopFactoryBuilder.getImageManager().getRegistry();
+ Configuration[] penalties = parent.getChildren("penalty");
+ try {
+ for (int i = 0, c = penalties.length; i < c; i++) {
+ Configuration penaltyCfg = penalties[i];
+ String className = penaltyCfg.getAttribute("class");
+ String value = penaltyCfg.getAttribute("value");
+ Penalty p = null;
+ if (value.toUpperCase(Locale.getDefault()).startsWith("INF")) {
+ p = Penalty.INFINITE_PENALTY;
+ } else {
+ try {
+ p = Penalty.toPenalty(Integer.parseInt(value));
+ } catch (NumberFormatException nfe) {
+ LogUtil.handleException(log, nfe, strict);
+ }
+ }
+ if (p != null) {
+ registry.setAdditionalPenalty(className, p);
+ }
+ }
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ }
+
+ /**
+ * Returns the {@link FopFactoryBuilder}.
+ *
+ * @return the object for configuring the {@link FopFactory}
+ */
+ public FopFactoryBuilder getFopFactoryBuilder() {
+ return fopFactoryBuilder;
+ }
+}
diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java
index 18c84a036..ec7266957 100644
--- a/src/java/org/apache/fop/apps/FopFactory.java
+++ b/src/java/org/apache/fop/apps/FopFactory.java
@@ -21,19 +21,13 @@ package org.apache.fop.apps;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
-import java.net.MalformedURLException;
import java.net.URI;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.Source;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.URIResolver;
-
import org.xml.sax.SAXException;
import org.apache.avalon.framework.configuration.Configuration;
@@ -44,13 +38,15 @@ import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.util.UnitConv;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fo.ElementMapping;
import org.apache.fop.fo.ElementMappingRegistry;
-import org.apache.fop.fonts.FontCache;
import org.apache.fop.fonts.FontManager;
-import org.apache.fop.hyphenation.HyphenationTreeResolver;
import org.apache.fop.layoutmgr.LayoutManagerMaker;
import org.apache.fop.render.ImageHandlerRegistry;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.RendererFactory;
import org.apache.fop.render.XMLHandlerRegistry;
import org.apache.fop.util.ColorSpaceCache;
@@ -59,57 +55,49 @@ import org.apache.fop.util.ContentHandlerFactoryRegistry;
/**
* Factory class which instantiates new Fop and FOUserAgent instances. This
* class also holds environmental information and configuration used by FOP.
- * Information that may potentially be different for each rendering run can be
+ * Information that may potentially be different for each renderingq run can be
* found and managed in the FOUserAgent.
*/
-public class FopFactory implements ImageContext {
+public final class FopFactory implements ImageContext {
/** logger instance */
private static Log log = LogFactory.getLog(FopFactory.class);
/** Factory for Renderers and FOEventHandlers */
- private RendererFactory rendererFactory;
+ private final RendererFactory rendererFactory;
/** Registry for XML handlers */
- private XMLHandlerRegistry xmlHandlers;
+ private final XMLHandlerRegistry xmlHandlers;
/** Registry for image handlers */
- private ImageHandlerRegistry imageHandlers;
+ private final ImageHandlerRegistry imageHandlers;
/** The registry for ElementMapping instances */
- private ElementMappingRegistry elementMappingRegistry;
+ private final ElementMappingRegistry elementMappingRegistry;
/** The registry for ContentHandlerFactory instance */
- private ContentHandlerFactoryRegistry contentHandlerFactoryRegistry
- = new ContentHandlerFactoryRegistry();
-
- /** The resolver for user-supplied hyphenation patterns */
- private HyphenationTreeResolver hyphResolver = null;
+ private final ContentHandlerFactoryRegistry contentHandlerFactoryRegistry
+ = new ContentHandlerFactoryRegistry();
- private ColorSpaceCache colorSpaceCache = null;
+ private final ColorSpaceCache colorSpaceCache;
- /** Image manager for loading and caching image objects */
- private ImageManager imageManager;
+ private final FopFactoryConfig config;
- /** Font manager for font substitution, autodetection and caching **/
- private FontManager fontManager;
+ private final InternalResourceResolver resolver;
- /** Configuration layer used to configure fop */
- private FopFactoryConfigurator config = null;
+ private final Map<String, RendererConfig> rendererConfig;
- /**
- * The base URL for all URL resolutions, especially for
- * external-graphics.
- */
- private String base = null;
-
- /**
- * Controls if accessibility is turned on or off
- */
- private boolean accessibility = false;
-
- /** The base URL for all hyphen URL resolutions. */
- private String hyphenBase = null;
+ private FopFactory(FopFactoryConfig config) {
+ this.config = config;
+ this.resolver = ResourceResolverFactory.createInternalResourceResolver(config.getBaseURI(),
+ config.getResourceResolver());
+ this.elementMappingRegistry = new ElementMappingRegistry(this);
+ this.colorSpaceCache = new ColorSpaceCache(resolver);
+ this.rendererFactory = new RendererFactory(config.preferRenderer());
+ this.xmlHandlers = new XMLHandlerRegistry();
+ this.imageHandlers = new ImageHandlerRegistry();
+ rendererConfig = new HashMap<String, RendererConfig>();
+ }
/**
* Map of configured names of hyphenation pattern file names: ll_CC => name
@@ -121,73 +109,52 @@ public class FopFactory implements ImageContext {
* input XSL violates that FO's content model. This is the default
* behavior for FOP. However, this flag, if set, provides the user the
* ability for FOP to halt on all content model violations if desired.
+ * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object.
+ *
+ * @param config the fop configuration
+ * @return the requested FopFactory instance.
*/
- private boolean strictFOValidation = FopFactoryConfigurator.DEFAULT_STRICT_FO_VALIDATION;
+ public static FopFactory newInstance(FopFactoryConfig config) {
+ return new FopFactory(config);
+ }
/**
- * FOP will validate the contents of the user configuration strictly
- * (e.g. base-urls and font urls/paths).
+ * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object that
+ * is created when the fopConf is parsed.
+ *
+ * @param fopConf the fop conf configuration file to parse
+ * @return the requested FopFactory instance.
+ * @throws IOException
+ * @throws SAXException
*/
- private boolean strictUserConfigValidation
- = FopFactoryConfigurator.DEFAULT_STRICT_USERCONFIG_VALIDATION;
-
- /** Source resolution in dpi */
- private float sourceResolution = FopFactoryConfigurator.DEFAULT_SOURCE_RESOLUTION;
-
- /** Target resolution in dpi */
- private float targetResolution = FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
-
- /** Page height */
- private String pageHeight = FopFactoryConfigurator.DEFAULT_PAGE_HEIGHT;
-
- /** Page width */
- private String pageWidth = FopFactoryConfigurator.DEFAULT_PAGE_WIDTH;
-
- /** Complex scripts support enabled */
- private boolean useComplexScriptFeatures
- = FopFactoryConfigurator.DEFAULT_COMPLEX_SCRIPT_FEATURES;
-
- /** @see #setBreakIndentInheritanceOnReferenceAreaBoundary(boolean) */
- private boolean breakIndentInheritanceOnReferenceAreaBoundary
- = FopFactoryConfigurator.DEFAULT_BREAK_INDENT_INHERITANCE;
-
- /** Optional overriding LayoutManagerMaker */
- private LayoutManagerMaker lmMakerOverride = null;
-
- private Set<String> ignoredNamespaces;
-
- private FOURIResolver foURIResolver;
+ public static FopFactory newInstance(File fopConf) throws SAXException, IOException {
+ return new FopConfParser(fopConf).getFopFactoryBuilder().build();
+ }
/**
- * Main constructor.
+ * Returns a new FopFactory instance that is configured only by the default configuration
+ * parameters.
+ *
+ * @param baseURI the base URI to resolve resource URIs against
+ * @return the requested FopFactory instance.
*/
- protected FopFactory() {
- this.config = new FopFactoryConfigurator(this);
- this.elementMappingRegistry = new ElementMappingRegistry(this);
- this.foURIResolver = new FOURIResolver(validateUserConfigStrictly());
- this.fontManager = new FontManager() {
-
- /** {@inheritDoc} */
- @Override
- public void setFontBaseURL(String fontBase) throws MalformedURLException {
- super.setFontBaseURL(getFOURIResolver().checkBaseURL(fontBase));
- }
-
- };
- this.colorSpaceCache = new ColorSpaceCache(foURIResolver);
- this.imageManager = new ImageManager(this);
- this.rendererFactory = new RendererFactory();
- this.xmlHandlers = new XMLHandlerRegistry();
- this.imageHandlers = new ImageHandlerRegistry();
- this.ignoredNamespaces = new java.util.HashSet<String>();
+ public static FopFactory newInstance(URI baseURI) {
+ return new FopFactoryBuilder(baseURI).build();
}
/**
- * Returns a new FopFactory instance.
+ * Returns a new FopFactory instance that is configured using the {@link FopFactoryConfig} object that
+ * is created when the fopConf is parsed.
+ *
+ * @param baseURI the base URI to resolve resource URIs against
+ * @param confStream the fop conf configuration stream to parse
* @return the requested FopFactory instance.
+ * @throws SAXException
+ * @throws IOException
*/
- public static FopFactory newInstance() {
- return new FopFactory();
+ public static FopFactory newInstance(URI baseURI, InputStream confStream) throws SAXException,
+ IOException {
+ return new FopConfParser(confStream, baseURI).getFopFactoryBuilder().build();
}
/**
@@ -198,34 +165,12 @@ public class FopFactory implements ImageContext {
* @throws FOPException
*/
public FOUserAgent newFOUserAgent() {
- FOUserAgent userAgent = new FOUserAgent(this);
+ FOUserAgent userAgent = new FOUserAgent(this, resolver);
return userAgent;
}
- /**
- * Sets accessibility support.
- *
- * @param value <code>true</code> to enable accessibility, <code>false</code> otherwise
- */
- void setAccessibility(boolean value) {
- this.accessibility = value;
- }
-
- boolean isAccessibilityEnabled() {
- return accessibility;
- }
-
- /**
- * Sets complex script support.
- * @param value <code>true</code> to enable complex script features,
- * <code>false</code> otherwise
- */
- void setComplexScriptFeaturesEnabled(boolean value) {
- this.useComplexScriptFeatures = value;
- }
-
boolean isComplexScriptFeaturesEnabled() {
- return useComplexScriptFeatures;
+ return config.isComplexScriptFeaturesEnabled();
}
/**
@@ -239,7 +184,7 @@ public class FopFactory implements ImageContext {
* @throws FOPException when the constructor fails
*/
public Fop newFop(String outputFormat) throws FOPException {
- return newFop(outputFormat, newFOUserAgent());
+ return newFOUserAgent().newFop(outputFormat);
}
/**
@@ -256,7 +201,7 @@ public class FopFactory implements ImageContext {
* @throws FOPException when the constructor fails
*/
public Fop newFop(String outputFormat, FOUserAgent userAgent) throws FOPException {
- return newFop(outputFormat, userAgent, null);
+ return userAgent.newFop(outputFormat, null);
}
/**
@@ -271,7 +216,7 @@ public class FopFactory implements ImageContext {
* @throws FOPException when the constructor fails
*/
public Fop newFop(String outputFormat, OutputStream stream) throws FOPException {
- return newFop(outputFormat, newFOUserAgent(), stream);
+ return newFOUserAgent().newFop(outputFormat, stream);
}
/**
@@ -290,11 +235,8 @@ public class FopFactory implements ImageContext {
* @throws FOPException when the constructor fails
*/
public Fop newFop(String outputFormat, FOUserAgent userAgent, OutputStream stream)
- throws FOPException {
- if (userAgent == null) {
- throw new NullPointerException("The userAgent parameter must not be null!");
- }
- return new Fop(outputFormat, userAgent, stream);
+ throws FOPException {
+ return userAgent.newFop(outputFormat, stream);
}
/**
@@ -343,11 +285,28 @@ public class FopFactory implements ImageContext {
}
/**
- * Returns the image manager.
- * @return the image manager
- */
- public ImageManager getImageManager() {
- return this.imageManager;
+ * Returns the renderer configuration object for a specific renderer given the parser and
+ * configuration to read. The renderer config is cached such that the {@link Configuration} is
+ * only parsed once per renderer, per FopFactory instance.
+ *
+ * @param userAgent the user agent
+ * @param cfg the configuration to be parsed
+ * @param configCreator the parser that creates the config object
+ * @return the config object
+ * @throws FOPException when an error occurs while creating the configuration object
+ */
+ public RendererConfig getRendererConfig(FOUserAgent userAgent, Configuration cfg,
+ RendererConfigParser configCreator) throws FOPException {
+ RendererConfig config = rendererConfig.get(configCreator.getMimeType());
+ if (config == null) {
+ try {
+ config = configCreator.build(userAgent, cfg);
+ rendererConfig.put(configCreator.getMimeType(), config);
+ } catch (Exception e) {
+ throw new FOPException(e);
+ }
+ }
+ return config;
}
/**
@@ -359,143 +318,32 @@ public class FopFactory implements ImageContext {
}
/**
- * Sets an explicit LayoutManagerMaker instance which overrides the one
- * defined by the AreaTreeHandler.
- * @param lmMaker the LayoutManagerMaker instance
- */
- public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
- this.lmMakerOverride = lmMaker;
- }
-
- /**
- * Returns the overriding LayoutManagerMaker instance, if any.
- * @return the overriding LayoutManagerMaker or null
- */
- public LayoutManagerMaker getLayoutManagerMakerOverride() {
- return this.lmMakerOverride;
- }
-
- /**
- * Sets the base URL.
- * @param base the base URL
- * @throws MalformedURLException if there's a problem with a file URL
- */
- public void setBaseURL(String base) throws MalformedURLException {
- this.base = foURIResolver.checkBaseURL(base);
- }
-
- /**
- * Returns the base URL.
- * @return the base URL
- */
- public String getBaseURL() {
- return this.base;
- }
-
- /**
- * Sets the font base URL.
- * @param fontBase font base URL
- * @throws MalformedURLException if there's a problem with a file URL
- * @deprecated use getFontManager().setFontBaseURL(fontBase) instead
+ * Returns whether accessibility is enabled.
+ * @return true if accessibility is enabled
*/
- @Deprecated
- public void setFontBaseURL(String fontBase) throws MalformedURLException {
- getFontManager().setFontBaseURL(fontBase);
- }
-
- /**
- * @return the font base URL
- * @deprecated use getFontManager().setFontBaseURL(fontBase) instead
- */
- @Deprecated
- public String getFontBaseURL() {
- return getFontManager().getFontBaseURL();
- }
-
- /** @return the hyphen base URL */
- public String getHyphenBaseURL() {
- return this.hyphenBase;
- }
-
- /**
- * Sets the hyphen base URL.
- * @param hyphenBase hythen base URL
- * @throws MalformedURLException if there's a problem with a file URL
- * */
- public void setHyphenBaseURL(final String hyphenBase) throws MalformedURLException {
- if (hyphenBase != null) {
- setHyphenationTreeResolver(
- new HyphenationTreeResolver() {
- public Source resolve(String href) {
- return resolveURI(href, hyphenBase);
- }
- });
- }
- this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase);
- }
-
- /**
- * @return the hyphPatNames
- */
- public Map getHyphPatNames() {
- return hyphPatNames;
- }
-
- /**
- * @param hyphPatNames the hyphPatNames to set
- */
- public void setHyphPatNames(Map hyphPatNames) {
- if (hyphPatNames == null) {
- hyphPatNames = new HashMap();
- }
- this.hyphPatNames = hyphPatNames;
- }
-
- /**
- * 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.
- * @param uriResolver the new URI resolver
- */
- public void setURIResolver(URIResolver uriResolver) {
- foURIResolver.setCustomURIResolver(uriResolver);
+ boolean isAccessibilityEnabled() {
+ return config.isAccessibilityEnabled();
}
/**
- * Returns the URI Resolver.
- * @return the URI Resolver
+ * Returns the image manager.
+ * @return the image manager
*/
- public URIResolver getURIResolver() {
- return foURIResolver;
+ public ImageManager getImageManager() {
+ return config.getImageManager();
}
/**
- * Returns the FO URI Resolver.
- * @return the FO URI Resolver
+ * Returns the overriding LayoutManagerMaker instance, if any.
+ * @return the overriding LayoutManagerMaker or null
*/
- public FOURIResolver getFOURIResolver() {
- return foURIResolver;
- }
-
- /** @return the HyphenationTreeResolver for resolving user-supplied hyphenation patterns. */
- public HyphenationTreeResolver getHyphenationTreeResolver() {
- return this.hyphResolver;
+ public LayoutManagerMaker getLayoutManagerMakerOverride() {
+ return config.getLayoutManagerMakerOverride();
}
- /**
- * Sets the HyphenationTreeResolver to be used for resolving user-supplied hyphenation files.
- * @param hyphResolver the HyphenationTreeResolver instance
- */
- public void setHyphenationTreeResolver(HyphenationTreeResolver hyphResolver) {
- this.hyphResolver = hyphResolver;
- }
- /**
- * Activates strict XSL content model validation for FOP
- * Default is false (FOP will continue processing where it can)
- * @param validateStrictly true to turn on strict validation
- */
- public void setStrictValidation(boolean validateStrictly) {
- this.strictFOValidation = validateStrictly;
+ public Map<String, String> getHyphPatNames() {
+ return config.getHyphPatNames();
}
/**
@@ -503,7 +351,7 @@ public class FopFactory implements ImageContext {
* @return true of strict validation turned on, false otherwise
*/
public boolean validateStrictly() {
- return strictFOValidation;
+ return config.validateStrictly();
}
/**
@@ -511,48 +359,12 @@ public class FopFactory implements ImageContext {
* boundaries (for more info, see the javadoc for the relative member variable)
*/
public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
- return breakIndentInheritanceOnReferenceAreaBoundary;
- }
-
- /**
- * Controls whether to enable a feature that breaks indent inheritance when crossing
- * reference area boundaries.
- * <p>
- * This flag controls whether FOP will enable special code that breaks property
- * inheritance for start-indent and end-indent when the evaluation of the inherited
- * value would cross a reference area. This is described under
- * http://wiki.apache.org/xmlgraphics-fop/IndentInheritance as is intended to
- * improve interoperability with commercial FO implementations and to produce
- * results that are more in line with the expectation of unexperienced FO users.
- * Note: Enabling this features violates the XSL specification!
- * @param value true to enable the feature
- */
- public void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value) {
- this.breakIndentInheritanceOnReferenceAreaBoundary = value;
- }
-
- /**
- * @return true if kerning on base 14 fonts is enabled
- * @deprecated use getFontManager().isBase14KerningEnabled() instead
- */
- @Deprecated
- public boolean isBase14KerningEnabled() {
- return getFontManager().isBase14KerningEnabled();
- }
-
- /**
- * Controls whether kerning is activated on base 14 fonts.
- * @param value true if kerning should be activated
- * @deprecated use getFontManager().setBase14KerningEnabled(boolean) instead
- */
- @Deprecated
- public void setBase14KerningEnabled(boolean value) {
- getFontManager().setBase14KerningEnabled(value);
+ return config.isBreakIndentInheritanceOnReferenceAreaBoundary();
}
- /** @return the resolution for resolution-dependant input */
+ /** @return the resolution for resolution-dependent input */
public float getSourceResolution() {
- return this.sourceResolution;
+ return config.getSourceResolution();
}
/**
@@ -565,22 +377,9 @@ public class FopFactory implements ImageContext {
return UnitConv.IN2MM / getSourceResolution();
}
- /**
- * Sets the source resolution in dpi. This value is used to interpret the pixel size
- * of source documents like SVG images and bitmap images without resolution information.
- * @param dpi resolution in dpi
- */
- public void setSourceResolution(float dpi) {
- this.sourceResolution = dpi;
- if (log.isDebugEnabled()) {
- log.debug("source-resolution set to: " + sourceResolution
- + "dpi (px2mm=" + getSourcePixelUnitToMillimeter() + ")");
- }
- }
-
/** @return the resolution for resolution-dependant output */
public float getTargetResolution() {
- return this.targetResolution;
+ return config.getTargetResolution();
}
/**
@@ -590,25 +389,7 @@ public class FopFactory implements ImageContext {
* @see #getTargetResolution()
*/
public float getTargetPixelUnitToMillimeter() {
- return UnitConv.IN2MM / this.targetResolution;
- }
-
- /**
- * Sets the source resolution in dpi. This value is used to interpret the pixel size
- * of source documents like SVG images and bitmap images without resolution information.
- * @param dpi resolution in dpi
- */
- public void setTargetResolution(float dpi) {
- this.targetResolution = dpi;
- }
-
- /**
- * Sets the source resolution in dpi. This value is used to interpret the pixel size
- * of source documents like SVG images and bitmap images without resolution information.
- * @param dpi resolution in dpi
- */
- public void setSourceResolution(int dpi) {
- setSourceResolution((float)dpi);
+ return 25.4f / getTargetResolution();
}
/**
@@ -618,20 +399,7 @@ public class FopFactory implements ImageContext {
* @return the page-height, as a String
*/
public String getPageHeight() {
- return this.pageHeight;
- }
-
- /**
- * Sets the page-height to use as fallback, in case
- * page-height="auto"
- *
- * @param pageHeight page-height as a String
- */
- public void setPageHeight(String pageHeight) {
- this.pageHeight = pageHeight;
- if (log.isDebugEnabled()) {
- log.debug("Default page-height set to: " + pageHeight);
- }
+ return config.getPageHeight();
}
/**
@@ -641,40 +409,7 @@ public class FopFactory implements ImageContext {
* @return the page-width, as a String
*/
public String getPageWidth() {
- return this.pageWidth;
- }
-
- /**
- * Sets the page-width to use as fallback, in case
- * page-width="auto"
- *
- * @param pageWidth page-width as a String
- */
- public void setPageWidth(String pageWidth) {
- this.pageWidth = pageWidth;
- if (log.isDebugEnabled()) {
- log.debug("Default page-width set to: " + pageWidth);
- }
- }
-
- /**
- * Adds a namespace to the set of ignored namespaces.
- * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
- * namespace is in the ignored set.
- * @param namespaceURI the namespace URI
- */
- public void ignoreNamespace(String namespaceURI) {
- this.ignoredNamespaces.add(namespaceURI);
- }
-
- /**
- * Adds a collection of namespaces to the set of ignored namespaces.
- * If FOP encounters a namespace which it cannot handle, it issues a warning except if this
- * namespace is in the ignored set.
- * @param namespaceURIs the namespace URIs
- */
- public void ignoreNamespaces(Collection<String> namespaceURIs) {
- this.ignoredNamespaces.addAll(namespaceURIs);
+ return config.getPageWidth();
}
/**
@@ -683,55 +418,17 @@ public class FopFactory implements ImageContext {
* @return true if the namespace is ignored by FOP
*/
public boolean isNamespaceIgnored(String namespaceURI) {
- return this.ignoredNamespaces.contains(namespaceURI);
+ return config.isNamespaceIgnored(namespaceURI);
}
/** @return the set of namespaces that are ignored by FOP */
public Set<String> getIgnoredNamespace() {
- return Collections.unmodifiableSet(this.ignoredNamespaces);
+ return config.getIgnoredNamespaces();
}
//------------------------------------------- Configuration stuff
/**
- * 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 {
- config.setUserConfig(userConfigFile);
- }
-
- /**
- * 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 {
- config.setUserConfig(uri);
- }
-
- /**
- * Set the user configuration.
- * @param userConfig configuration
- * @throws FOPException if a configuration problem occurs
- */
- public void setUserConfig(Configuration userConfig) throws FOPException {
- config.setUserConfig(userConfig);
- }
-
- /**
- * Set the base URI for the user configuration
- * Useful for programmatic configurations
- * @param baseURI the base URI
- */
- public void setUserConfigBaseURI(URI baseURI) {
- config.setBaseURI(baseURI);
- }
-
- /**
* Get the user configuration.
* @return the user configuration
*/
@@ -741,79 +438,20 @@ public class FopFactory implements ImageContext {
/**
* Is the user configuration to be validated?
- * @param strictUserConfigValidation strict user config validation
- */
- public void setStrictUserConfigValidation(boolean strictUserConfigValidation) {
- this.strictUserConfigValidation = strictUserConfigValidation;
- this.foURIResolver.setThrowExceptions(strictUserConfigValidation);
- }
-
- /**
- * Is the user configuration to be validated?
* @return if the user configuration should be validated
*/
public boolean validateUserConfigStrictly() {
- return this.strictUserConfigValidation;
+ return config.validateUserConfigStrictly();
}
//------------------------------------------- Font related stuff
/**
- * Whether or not to cache results of font triplet detection/auto-config
- * @param useCache use cache or not
- * @deprecated use getFontManager().setUseCache(boolean) instead
- */
- @Deprecated
- public void setUseCache(boolean useCache) {
- getFontManager().setUseCache(useCache);
- }
-
- /**
- * Cache results of font triplet detection/auto-config?
- * @return whether this factory is uses the cache
- * @deprecated use getFontManager().useCache() instead
- */
- @Deprecated
- public boolean useCache() {
- return getFontManager().useCache();
- }
-
- /**
- * Returns the font cache instance used by this factory.
- * @return the font cache
- * @deprecated use getFontManager().getFontCache() instead
- */
- @Deprecated
- public FontCache getFontCache() {
- return getFontManager().getFontCache();
- }
-
- /**
* Returns the font manager.
* @return the font manager
*/
public FontManager getFontManager() {
- return this.fontManager;
- }
-
- /**
- * Attempts to resolve the given URI.
- * Will use the configured resolver and if not successful fall back
- * to the default resolver.
- * @param href URI to access
- * @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 href, String baseUri) {
- Source source = null;
- try {
- source = foURIResolver.resolve(href, baseUri);
- } catch (TransformerException e) {
- log.error("Attempt to resolve URI '" + href + "' failed: ", e);
- }
- return source;
+ return config.getFontManager();
}
/**
@@ -825,5 +463,4 @@ public class FopFactory implements ImageContext {
public ColorSpaceCache getColorSpaceCache() {
return this.colorSpaceCache;
}
-
}
diff --git a/src/java/org/apache/fop/apps/FopFactoryBuilder.java b/src/java/org/apache/fop/apps/FopFactoryBuilder.java
new file mode 100644
index 000000000..44c44c119
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FopFactoryBuilder.java
@@ -0,0 +1,648 @@
+/*
+ * 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.net.URI;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.xmlgraphics.image.loader.ImageContext;
+import org.apache.xmlgraphics.image.loader.ImageManager;
+
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.layoutmgr.LayoutManagerMaker;
+
+/**
+ * This is the builder class for {@link FopFactory}. Setters can be chained to
+ * make building a {@link FopFactory} object more concise and intuitive e.g.
+ *
+ * <pre>
+ * {@code
+ * FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(<URI>)
+ * .setURIResolver(<URIResolver>)
+ * .setPageHeight(<String>)
+ * .setPageWidth(<String>)
+ * .setStrictUserConfigValidation(<boolean>)
+ * ... etc ...
+ * FopFactory fopFactory = fopFactoryBuilder.build();
+ * }
+ * </pre>
+ */
+public final class FopFactoryBuilder {
+
+ private final FopFactoryConfig config;
+
+ private FopFactoryConfigBuilder fopFactoryConfigBuilder;
+
+ /**
+ * A builder class for {@link FopFactory} which can be used for setting configuration. This is
+ * a helper constructor that uses the default URI resolver implementation that FOP packages
+ * provide ({@link DefaultResourceResolver}).
+ *
+ * @param defaultBaseURI the default base URI for resolving URIs against
+ */
+ public FopFactoryBuilder(URI defaultBaseURI) {
+ this(defaultBaseURI, ResourceResolverFactory.createDefaultResourceResolver());
+ }
+
+ /**
+ * A builder class for {@link FopFactory} which can be used for setting configuration.
+ *
+ * @param defaultBaseURI the default base URI for resolving URIs against
+ * @param resourceResolver the URI resolver
+ */
+ public FopFactoryBuilder(URI defaultBaseURI, ResourceResolver resourceResolver) {
+ this(EnvironmentalProfileFactory.createDefault(defaultBaseURI, resourceResolver));
+ }
+
+ /**
+ * A builder class for {@link FopFactory} which can be used for setting configuration.
+ *
+ * @param enviro the profile of the FOP deployment environment
+ */
+ public FopFactoryBuilder(EnvironmentProfile enviro) {
+ config = new FopFactoryConfigImpl(enviro);
+ fopFactoryConfigBuilder = new ActiveFopFactoryConfigBuilder((FopFactoryConfigImpl) config);
+ }
+
+ /**
+ * Returns the {@link FopFactoryConfig} which is needed to get an instance of
+ * {@link FopFactory}.
+ *
+ * @return build the {@link FopFactoryConfig}
+ * @deprecated Exposing the {@link FopFactoryConfig} is only to maintain backwards compatibility
+ */
+ public FopFactoryConfig buildConfig() {
+ fopFactoryConfigBuilder = CompletedFopFactoryConfigBuilder.INSTANCE;
+ return config;
+ }
+
+ /**
+ * Builds an instance of the the {@link FopFactory}.
+ *
+ * @return the FopFactory instance
+ */
+ public FopFactory build() {
+ return FopFactory.newInstance(buildConfig());
+ }
+
+ /**
+ * Gets the base URI used to resolve all URIs within FOP.
+ *
+ * @return the base URI
+ */
+ URI getBaseURI() {
+ return config.getBaseURI();
+ }
+
+ /**
+ * Returns the {@link FontManager} used for managing the fonts within FOP.
+ *
+ * @return the font managing object
+ */
+ public FontManager getFontManager() {
+ return config.getFontManager();
+ }
+
+ /**
+ * Return the {@link ImageManager} used for handling images through out FOP.
+ *
+ * @return the image manager
+ */
+ public ImageManager getImageManager() {
+ return config.getImageManager();
+ }
+
+ /**
+ * Sets whether to include accessibility features in document creation.
+ *
+ * @param enableAccessibility true to set accessibility on
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setAccessibility(boolean enableAccessibility) {
+ fopFactoryConfigBuilder.setAccessibility(enableAccessibility);
+ return this;
+ }
+
+ /**
+ * Sets the {@link LayoutManagerMaker} so that users can configure how FOP creates
+ * {@link LayoutManager}s.
+ *
+ * @param lmMaker he layout manager maker
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setLayoutManagerMakerOverride(
+ LayoutManagerMaker lmMaker) {
+ fopFactoryConfigBuilder.setLayoutManagerMakerOverride(lmMaker);
+ return this;
+ }
+
+ /**
+ * Sets the base URI, this will be used for resolving all URIs given to FOP.
+ *
+ * @param baseURI the base URI
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setBaseURI(URI baseURI) {
+ fopFactoryConfigBuilder.setBaseURI(baseURI);
+ return this;
+ }
+
+ /**
+ * Sets whether to perform strict validation on the FO used.
+ *
+ * @param validateStrictly true if the FO is to be strictly validated
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setStrictFOValidation(boolean validateStrictly) {
+ fopFactoryConfigBuilder.setStrictFOValidation(validateStrictly);
+ return this;
+ }
+
+ /**
+ * Sets whether to perform strict alidation on the user-configuration.
+ *
+ * @param validateStrictly true if the fop conf is to be strictly validated
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setStrictUserConfigValidation(
+ boolean validateStrictly) {
+ fopFactoryConfigBuilder.setStrictUserConfigValidation(validateStrictly);
+ return this;
+ }
+
+ /**
+ * Sets whether the indent inheritance should be broken when crossing reference area boundaries.
+ *
+ * @param value true to break inheritance when crossing reference area boundaries
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setBreakIndentInheritanceOnReferenceAreaBoundary(
+ boolean value) {
+ fopFactoryConfigBuilder.setBreakIndentInheritanceOnReferenceAreaBoundary(value);
+ return this;
+ }
+
+ /**
+ * Sets the resolution of resolution-dependent input.
+ *
+ * @param dpi the source resolution
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setSourceResolution(float dpi) {
+ fopFactoryConfigBuilder.setSourceResolution(dpi);
+ return this;
+ }
+
+ /**
+ * Sets the resolution of resolution-dependent output.
+ *
+ * @param dpi the target resolution
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setTargetResolution(float dpi) {
+ fopFactoryConfigBuilder.setTargetResolution(dpi);
+ return this;
+ }
+
+ /**
+ * Sets the page height of the paginated output.
+ *
+ * @param pageHeight the page height
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setPageHeight(String pageHeight) {
+ fopFactoryConfigBuilder.setPageHeight(pageHeight);
+ return this;
+ }
+
+ /**
+ * Sets the page width of the paginated output.
+ *
+ * @param pageWidth the page width
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setPageWidth(String pageWidth) {
+ fopFactoryConfigBuilder.setPageWidth(pageWidth);
+ return this;
+ }
+
+ /**
+ * FOP will ignore the specified XML element namespace.
+ *
+ * @param namespaceURI the namespace URI to ignore
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder ignoreNamespace(String namespaceURI) {
+ fopFactoryConfigBuilder.ignoreNamespace(namespaceURI);
+ return this;
+ }
+
+ /**
+ * FOP will ignore the colletion of XML element namespaces.
+ *
+ * @param namespaceURIs a collection of namespace URIs to ignore
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder ignoreNamespaces(Collection<String> namespaceURIs) {
+ fopFactoryConfigBuilder.ignoreNamespaces(namespaceURIs);
+ return this;
+ }
+
+ /**
+ * Sets the Avalon configuration if a FOP conf is used.
+ *
+ * @param cfg the fop conf configuration
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setConfiguration(Configuration cfg) {
+ fopFactoryConfigBuilder.setConfiguration(cfg);
+ return this;
+ }
+
+ /**
+ * Sets whether to chose a {@link Renderer} in preference to an
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler}.
+ *
+ * @see {@link RendererFactory}
+ * @param preferRenderer true to prefer {@link Renderer}
+ * @return <code>this</code>
+ */
+ public FopFactoryBuilder setPreferRenderer(boolean preferRenderer) {
+ fopFactoryConfigBuilder.setPreferRenderer(preferRenderer);
+ return this;
+ }
+
+ public FopFactoryBuilder setComplexScriptFeatures(boolean csf) {
+ fopFactoryConfigBuilder.setComplexScriptFeaturesEnabled(csf);
+ return this;
+ }
+
+ public FopFactoryBuilder setHyphPatNames(Map<String, String> hyphPatNames) {
+ fopFactoryConfigBuilder.setHyphPatNames(hyphPatNames);
+ return this;
+ }
+
+ public static class FopFactoryConfigImpl implements FopFactoryConfig {
+
+ private final EnvironmentProfile enviro;
+
+ private final ImageManager imageManager;
+
+ private boolean accessibility;
+
+ private LayoutManagerMaker layoutManagerMaker;
+
+ private URI baseURI;
+
+ private boolean hasStrictFOValidation = true;
+
+ private boolean hasStrictUserValidation = FopFactoryConfig.DEFAULT_STRICT_USERCONFIG_VALIDATION;
+
+ private boolean breakIndentInheritanceOnReferenceBoundary
+ = FopFactoryConfig.DEFAULT_BREAK_INDENT_INHERITANCE;
+
+ private float sourceResolution = FopFactoryConfig.DEFAULT_SOURCE_RESOLUTION;
+
+ private float targetResolution = FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
+
+ private String pageHeight = FopFactoryConfig.DEFAULT_PAGE_HEIGHT;
+
+ private String pageWidth = FopFactoryConfig.DEFAULT_PAGE_WIDTH;
+
+ private Set<String> ignoredNamespaces = new HashSet<String>();
+
+ private Configuration cfg;
+
+ private boolean preferRenderer;
+
+ private boolean isComplexScript = true;
+
+ private Map<String, String> hyphPatNames;
+
+ private static final class ImageContextImpl implements ImageContext {
+
+ private final FopFactoryConfig config;
+
+ ImageContextImpl(FopFactoryConfig config) {
+ this.config = config;
+ }
+
+ public float getSourceResolution() {
+ return config.getSourceResolution();
+ }
+ }
+
+ FopFactoryConfigImpl(EnvironmentProfile enviro) {
+ this.enviro = enviro;
+ this.baseURI = enviro.getDefaultBaseURI();
+ this.imageManager = new ImageManager(new ImageContextImpl(this));
+ }
+
+ /** {@inheritDoc} */
+ public boolean isAccessibilityEnabled() {
+ return accessibility;
+ }
+
+ /** {@inheritDoc} */
+ public LayoutManagerMaker getLayoutManagerMakerOverride() {
+ return layoutManagerMaker;
+ }
+
+ /** {@inheritDoc} */
+ public ResourceResolver getResourceResolver() {
+ return enviro.getResourceResolver();
+ }
+
+ /** {@inheritDoc} */
+ public URI getBaseURI() {
+ return baseURI;
+ }
+
+ /** {@inheritDoc} */
+ public boolean validateStrictly() {
+ return hasStrictFOValidation;
+ }
+
+ /** {@inheritDoc} */
+ public boolean validateUserConfigStrictly() {
+ return hasStrictUserValidation;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isBreakIndentInheritanceOnReferenceAreaBoundary() {
+ return breakIndentInheritanceOnReferenceBoundary;
+ }
+
+ /** {@inheritDoc} */
+ public float getSourceResolution() {
+ return sourceResolution;
+ }
+
+ /** {@inheritDoc} */
+ public float getTargetResolution() {
+ return targetResolution;
+ }
+
+ /** {@inheritDoc} */
+ public String getPageHeight() {
+ return pageHeight;
+ }
+
+ /** {@inheritDoc} */
+ public String getPageWidth() {
+ return pageWidth;
+ }
+
+ /** {@inheritDoc} */
+ public Set<String> getIgnoredNamespaces() {
+ return Collections.unmodifiableSet(ignoredNamespaces);
+ }
+
+ /** {@inheritDoc} */
+ public boolean isNamespaceIgnored(String namespace) {
+ return ignoredNamespaces.contains(namespace);
+ }
+
+ /** {@inheritDoc} */
+ public Configuration getUserConfig() {
+ return cfg;
+ }
+
+ /** {@inheritDoc} */
+ public boolean preferRenderer() {
+ return preferRenderer;
+ }
+
+ /** {@inheritDoc} */
+ public FontManager getFontManager() {
+ return enviro.getFontManager();
+ }
+
+ /** {@inheritDoc} */
+ public ImageManager getImageManager() {
+ return imageManager;
+ }
+
+ public boolean isComplexScriptFeaturesEnabled() {
+ return isComplexScript;
+ }
+
+ public Map<String, String> getHyphPatNames() {
+ return hyphPatNames;
+ }
+ }
+
+ private interface FopFactoryConfigBuilder {
+
+ void setAccessibility(boolean enableAccessibility);
+
+ void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker);
+
+ void setBaseURI(URI baseURI);
+
+ void setStrictFOValidation(boolean validateStrictly);
+
+ void setStrictUserConfigValidation(boolean validateStrictly);
+
+ void setBreakIndentInheritanceOnReferenceAreaBoundary(boolean value);
+
+ void setSourceResolution(float dpi);
+
+ void setTargetResolution(float dpi);
+
+ void setPageHeight(String pageHeight);
+
+ void setPageWidth(String pageWidth);
+
+ void ignoreNamespace(String namespaceURI);
+
+ void ignoreNamespaces(Collection<String> namespaceURIs);
+
+ void setConfiguration(Configuration cfg);
+
+ void setPreferRenderer(boolean preferRenderer);
+
+ void setComplexScriptFeaturesEnabled(boolean csf);
+
+ void setHyphPatNames(Map<String, String> hyphPatNames);
+ }
+
+ private static final class CompletedFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
+
+ private static final CompletedFopFactoryConfigBuilder INSTANCE
+ = new CompletedFopFactoryConfigBuilder();
+
+ private void throwIllegalStateException() {
+ throw new IllegalStateException("The final FOP Factory configuration has already been built");
+ }
+
+ public void setAccessibility(boolean enableAccessibility) {
+ throwIllegalStateException();
+ }
+
+ public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
+ throwIllegalStateException();
+
+ }
+
+ public void setBaseURI(URI baseURI) {
+ throwIllegalStateException();
+ }
+
+ public void setStrictFOValidation(boolean validateStrictly) {
+ throwIllegalStateException();
+ }
+
+ public void setStrictUserConfigValidation(boolean validateStrictly) {
+ throwIllegalStateException();
+ }
+
+ public void setBreakIndentInheritanceOnReferenceAreaBoundary(
+ boolean value) {
+ throwIllegalStateException();
+ }
+
+ public void setSourceResolution(float dpi) {
+ throwIllegalStateException();
+ }
+
+ public void setTargetResolution(float dpi) {
+ throwIllegalStateException();
+ }
+
+ public void setPageHeight(String pageHeight) {
+ throwIllegalStateException();
+ }
+
+ public void setPageWidth(String pageWidth) {
+ throwIllegalStateException();
+ }
+
+ public void ignoreNamespace(String namespaceURI) {
+ throwIllegalStateException();
+ }
+
+ public void ignoreNamespaces(Collection<String> namespaceURIs) {
+ throwIllegalStateException();
+ }
+
+ public void setConfiguration(Configuration cfg) {
+ throwIllegalStateException();
+ }
+
+ public void setPreferRenderer(boolean preferRenderer) {
+ throwIllegalStateException();
+ }
+
+ public void setComplexScriptFeaturesEnabled(boolean csf) {
+ throwIllegalStateException();
+ }
+
+ public void setHyphPatNames(Map<String, String> hyphPatNames) {
+ throwIllegalStateException();
+ }
+
+ }
+
+ private static final class ActiveFopFactoryConfigBuilder implements FopFactoryConfigBuilder {
+
+ private final FopFactoryConfigImpl config;
+
+ private ActiveFopFactoryConfigBuilder(FopFactoryConfigImpl config) {
+ this.config = config;
+ }
+
+ public void setAccessibility(boolean enableAccessibility) {
+ config.accessibility = enableAccessibility;
+ }
+
+ public void setLayoutManagerMakerOverride(LayoutManagerMaker lmMaker) {
+ config.layoutManagerMaker = lmMaker;
+ }
+
+ public void setBaseURI(URI baseURI) {
+ config.baseURI = baseURI;
+ }
+
+ public void setStrictFOValidation(boolean validateStrictly) {
+ config.hasStrictFOValidation = validateStrictly;
+ }
+
+ public void setStrictUserConfigValidation(
+ boolean validateStrictly) {
+ config.hasStrictUserValidation = validateStrictly;
+ }
+
+ public void setBreakIndentInheritanceOnReferenceAreaBoundary(
+ boolean value) {
+ config.breakIndentInheritanceOnReferenceBoundary = value;
+ }
+
+ public void setSourceResolution(float dpi) {
+ config.sourceResolution = dpi;
+ }
+
+ public void setTargetResolution(float dpi) {
+ config.targetResolution = dpi;
+ }
+
+ public void setPageHeight(String pageHeight) {
+ config.pageHeight = pageHeight;
+ }
+
+ public void setPageWidth(String pageWidth) {
+ config.pageWidth = pageWidth;
+ }
+
+ public void ignoreNamespace(String namespaceURI) {
+ config.ignoredNamespaces.add(namespaceURI);
+ }
+
+ public void ignoreNamespaces(
+ Collection<String> namespaceURIs) {
+ config.ignoredNamespaces.addAll(namespaceURIs);
+ }
+
+ public void setConfiguration(Configuration cfg) {
+ config.cfg = cfg;
+ }
+
+ public void setPreferRenderer(boolean preferRenderer) {
+ config.preferRenderer = preferRenderer;
+ }
+
+ public void setComplexScriptFeaturesEnabled(boolean csf) {
+ config.isComplexScript = csf;
+ }
+
+ public void setHyphPatNames(Map<String, String> hyphPatNames) {
+ config.hyphPatNames = hyphPatNames;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/apps/FopFactoryConfig.java b/src/java/org/apache/fop/apps/FopFactoryConfig.java
new file mode 100644
index 000000000..1ef958fae
--- /dev/null
+++ b/src/java/org/apache/fop/apps/FopFactoryConfig.java
@@ -0,0 +1,130 @@
+/*
+ * 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.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.xmlgraphics.image.loader.ImageManager;
+
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.layoutmgr.LayoutManagerMaker;
+
+/**
+ * The configuration data for a {@link FopFactory} instance.
+ */
+public interface FopFactoryConfig {
+
+ /** Defines if FOP should use an alternative rule to determine text indents */
+ boolean DEFAULT_BREAK_INDENT_INHERITANCE = false;
+
+ /** Defines if FOP should validate the user config strictly */
+ boolean DEFAULT_STRICT_USERCONFIG_VALIDATION = true;
+
+ /** Defines if FOP should use strict validation for FO and user config */
+ boolean DEFAULT_STRICT_FO_VALIDATION = true;
+
+ /** Defines the default page-width */
+ String DEFAULT_PAGE_WIDTH = "8.26in";
+
+ /** Defines the default page-height */
+ String DEFAULT_PAGE_HEIGHT = "11in";
+
+ /** Defines the default source resolution (72dpi) for FOP */
+ float DEFAULT_SOURCE_RESOLUTION = 72.0f; //dpi
+
+ /** Defines the default target resolution (72dpi) for FOP */
+ float DEFAULT_TARGET_RESOLUTION = 72.0f; //dpi
+
+ /**
+ * Whether accessibility features are switched on.
+ *
+ * @return true if accessibility features have been requested
+ */
+ boolean isAccessibilityEnabled();
+
+ /** @see {@link FopFactory#getLayoutManagerMakerOverride()} */
+ LayoutManagerMaker getLayoutManagerMakerOverride();
+
+ /**
+ * The URI resolver used through-out FOP for controlling all file access.
+ *
+ * @return the URI resolver
+ */
+ ResourceResolver getResourceResolver();
+
+ /**
+ * The base URI from which URIs are resolved against.
+ *
+ * @return the base URI
+ */
+ URI getBaseURI();
+
+ /** @see {@link FopFactory#validateStrictly()} */
+ boolean validateStrictly();
+
+ /** @see {@link FopFactory#validateUserConfigStrictly()} */
+ boolean validateUserConfigStrictly();
+
+ /** @see {@link FopFactory#isBreakIndentInheritanceOnReferenceAreaBoundary()} */
+ boolean isBreakIndentInheritanceOnReferenceAreaBoundary();
+
+ /** @see {@link FopFactory#getSourceResolution()} */
+ float getSourceResolution();
+
+ /** @see {@link FopFactory#getTargetResolution()} */
+ float getTargetResolution();
+
+ /** @see {@link FopFactory#getPageHeight()} */
+ String getPageHeight();
+
+ /** @see {@link FopFactory#getPageWidth()} */
+ String getPageWidth();
+
+ /** @see {@link FopFactory#getIgnoredNamespace()} */
+ Set<String> getIgnoredNamespaces();
+
+ /** @see {@link FopFactory#isNamespaceIgnored(String)} */
+ boolean isNamespaceIgnored(String namespace);
+
+ /**
+ * Returns the Avalon {@link Configuration} object.
+ *
+ * @return the Avalon config object
+ */
+ Configuration getUserConfig();
+
+ /** @see {@link org.apache.fop.render.RendererFactory#isRendererPreferred()} */
+ boolean preferRenderer();
+
+ /** @see {@link FopFactory#getFontManager()} */
+ FontManager getFontManager();
+
+ /** @see {@link FopFactory#getImageManager()} */
+ ImageManager getImageManager();
+
+ boolean isComplexScriptFeaturesEnabled();
+
+ Map<String, String> getHyphPatNames();
+}
diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java
deleted file mode 100644
index c1555a7e7..000000000
--- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.apps;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-
-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.xmlgraphics.image.GraphicsConstants;
-import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry;
-import org.apache.xmlgraphics.image.loader.util.Penalty;
-
-import org.apache.fop.fonts.FontManagerConfigurator;
-import org.apache.fop.hyphenation.HyphenationTreeCache;
-import org.apache.fop.util.LogUtil;
-
-/**
- * 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 = GraphicsConstants.DEFAULT_DPI; //dpi
-
- /** Defines the default target resolution (72dpi) for FOP */
- public static final float DEFAULT_TARGET_RESOLUTION = GraphicsConstants.DEFAULT_DPI; //dpi
-
- /** Defines the default complex script support */
- public static final boolean DEFAULT_COMPLEX_SCRIPT_FEATURES = true;
-
- private static final String PREFER_RENDERER = "prefer-renderer";
-
- /** logger instance */
- private final Log log = LogFactory.getLog(FopFactoryConfigurator.class);
-
- /** Fop factory */
- private FopFactory factory = null;
-
- /** Fop factory configuration */
- private Configuration cfg = null;
-
- /** The base URI of the configuration file **/
- private URI baseURI = 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 { // CSOK: MethodLength
- // 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();
- if (log.isDebugEnabled()) {
- log.debug("Initializing FopFactory Configuration"
- + "with " + (strict ? "strict" : "permissive") + " validation");
- }
-
- if (cfg.getChild("accessibility", false) != null) {
- try {
- this.factory.setAccessibility(
- cfg.getChild("accessibility").getValueAsBoolean());
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- }
- }
-
- // 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) {
- String path = cfg.getChild("base").getValue(null);
- if (baseURI != null) {
- path = baseURI.resolve(path).normalize().toString();
- }
- try {
- factory.setBaseURL(path);
- } catch (MalformedURLException mfue) {
- LogUtil.handleException(log, mfue, strict);
- }
- }
- if (cfg.getChild("hyphenation-base", false) != null) {
- String path = cfg.getChild("hyphenation-base").getValue(null);
- if (baseURI != null) {
- path = baseURI.resolve(path).normalize().toString();
- }
- try {
- factory.setHyphenBaseURL(path);
- } catch (MalformedURLException mfue) {
- LogUtil.handleException(log, mfue, strict);
- }
- }
-
- /**
- * Read configuration elements hyphenation-pattern,
- * construct a map ll_CC => filename, and set it on the factory
- */
- Configuration[] hyphPatConfig = cfg.getChildren("hyphenation-pattern");
- if (hyphPatConfig.length != 0) {
- Map/*<String,String>*/ hyphPatNames = new HashMap/*<String,String>*/();
- for (int i = 0; i < hyphPatConfig.length; ++i) {
- String lang;
- String country;
- String filename;
- StringBuffer error = new StringBuffer();
- String location = hyphPatConfig[i].getLocation();
-
- lang = hyphPatConfig[i].getAttribute("lang", null);
- if (lang == null) {
- addError("The lang attribute of a hyphenation-pattern configuration"
- + " element must exist (" + location + ")", error);
- } else if (!lang.matches("[a-zA-Z]{2}")) {
- addError("The lang attribute of a hyphenation-pattern configuration"
- + " element must consist of exactly two letters ("
- + location + ")", error);
- }
- lang = lang.toLowerCase();
-
- country = hyphPatConfig[i].getAttribute("country", null);
- if ("".equals(country)) {
- country = null;
- }
- if (country != null) {
- if (!country.matches("[a-zA-Z]{2}")) {
- addError("The country attribute of a hyphenation-pattern configuration"
- + " element must consist of exactly two letters ("
- + location + ")", error);
- }
- country = country.toUpperCase();
- }
-
- filename = hyphPatConfig[i].getValue(null);
- if (filename == null) {
- addError("The value of a hyphenation-pattern configuration"
- + " element may not be empty (" + location + ")", error);
- }
-
- if (error.length() != 0) {
- LogUtil.handleError(log, error.toString(), strict);
- continue;
- }
-
- String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
- hyphPatNames.put(llccKey, filename);
- if (log.isDebugEnabled()) {
- log.debug("Using hyphenation pattern filename " + filename
- + " for lang=\"" + lang + "\""
- + (country != null ? ", country=\"" + country + "\"" : ""));
- }
- }
- factory.setHyphPatNames(hyphPatNames);
- }
-
- // 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());
- }
- }
-
- // prefer Renderer over IFDocumentHandler
- if (cfg.getChild(PREFER_RENDERER, false) != null) {
- try {
- factory.getRendererFactory().setRendererPreferred(
- cfg.getChild(PREFER_RENDERER).getValueAsBoolean());
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- }
- }
-
- // configure complex script support
- Configuration csConfig = cfg.getChild("complex-scripts");
- if (csConfig != null) {
- this.factory.setComplexScriptFeaturesEnabled
- (!csConfig.getAttributeAsBoolean ( "disabled", false ));
- }
-
- // configure font manager
- new FontManagerConfigurator(cfg, baseURI).configure(factory.getFontManager(), strict);
-
- // configure image loader framework
- configureImageLoading(cfg.getChild("image-loading", false), strict);
- }
-
- private static void addError(String message, StringBuffer error) {
- if (error.length() != 0) {
- error.append(". ");
- }
- error.append(message);
- }
-
- private void configureImageLoading(Configuration parent, boolean strict) throws FOPException {
- if (parent == null) {
- return;
- }
- ImageImplRegistry registry = factory.getImageManager().getRegistry();
- Configuration[] penalties = parent.getChildren("penalty");
- try {
- for (int i = 0, c = penalties.length; i < c; i++) {
- Configuration penaltyCfg = penalties[i];
- String className = penaltyCfg.getAttribute("class");
- String value = penaltyCfg.getAttribute("value");
- Penalty p = null;
- if (value.toUpperCase().startsWith("INF")) {
- p = Penalty.INFINITE_PENALTY;
- } else {
- try {
- p = Penalty.toPenalty(Integer.parseInt(value));
- } catch (NumberFormatException nfe) {
- LogUtil.handleException(log, nfe, strict);
- }
- }
- if (p != null) {
- registry.setAdditionalPenalty(className, p);
- }
- }
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, 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;
- setBaseURI();
- configure(this.factory);
- }
-
- /**
- * Get the avalon user configuration.
- * @return the user configuration
- */
- public Configuration getUserConfig() {
- return this.cfg;
- }
-
- /**
- * @return the baseURI
- */
- public URI getBaseURI() {
- return baseURI;
- }
-
- /**
- * @param baseURI the baseURI to set
- */
- public void setBaseURI(URI baseURI) {
- this.baseURI = baseURI;
- }
-
- private void setBaseURI() throws FOPException {
- String loc = cfg.getLocation();
- try {
- if (loc != null && loc.startsWith("file:")) {
- baseURI = new URI(loc);
- baseURI = baseURI.resolve(".").normalize();
- }
- if (baseURI == null) {
- baseURI = new File(System.getProperty("user.dir")).toURI();
- }
- } catch (URISyntaxException e) {
- throw new FOPException(e);
- }
- }
-
-}
diff --git a/src/java/org/apache/fop/apps/MimeConstants.java b/src/java/org/apache/fop/apps/MimeConstants.java
index 851690db1..75b05c8b7 100644
--- a/src/java/org/apache/fop/apps/MimeConstants.java
+++ b/src/java/org/apache/fop/apps/MimeConstants.java
@@ -32,4 +32,6 @@ public interface MimeConstants extends org.apache.xmlgraphics.util.MimeConstants
String MIME_FOP_AREA_TREE = "application/X-fop-areatree";
/** Apache FOP's intermediate format XML */
String MIME_FOP_IF = "application/X-fop-intermediate-format";
+ /** Bitmap images */
+ String MIME_BITMAP = "image/x-bitmap";
}
diff --git a/src/java/org/apache/fop/apps/io/InternalResourceResolver.java b/src/java/org/apache/fop/apps/io/InternalResourceResolver.java
new file mode 100644
index 000000000..4d664c8f5
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/InternalResourceResolver.java
@@ -0,0 +1,153 @@
+/*
+ * 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.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.xmlgraphics.util.uri.DataURIResolver;
+
+/**
+ * This object holds the base URI from which to resolve URIs against as well as the resolver for
+ * resource acquisition. It also does some URI sanitization of common URI syntactical errors. This
+ * class takes in a {@link org.apache.fop.apps.io.ResourceResolver} and delegates all relevant
+ * URIs to it.
+ */
+public class InternalResourceResolver {
+ private final URI baseUri;
+ private final ResourceResolver resourceResolver;
+ private final DataURIResolver dataSchemeResolver = new DataURIResolver();
+
+ /**
+ * @param baseUri the base URI from which to resolve relative URIs
+ * @param resourceResolver the resolver to delegate to
+ */
+ InternalResourceResolver(URI baseUri, ResourceResolver resourceResolver) {
+ this.baseUri = baseUri;
+ this.resourceResolver = resourceResolver;
+ }
+
+ /**
+ * Returns the base URI from which to resolve all URIs against.
+ *
+ * @return the base URI
+ */
+ public URI getBaseURI() {
+ return baseUri;
+ }
+
+ /**
+ * Retrieve a resource given a URI in String form. This also does some syntactical sanitaion on
+ * the URI.
+ *
+ * @param stringUri the URI in String form
+ * @return the resource
+ * @throws IOException if an I/O error occurred
+ * @throws URISyntaxException if the URI syntax was invalid
+ */
+ public Resource getResource(String stringUri) throws IOException, URISyntaxException {
+ if (stringUri.startsWith("data:")) {
+ return new Resource(resolveDataURI(stringUri));
+ }
+ return getResource(cleanURI(stringUri));
+ }
+
+ /**
+ * Retrieve a resource given a URI in String form.
+ *
+ * @param uri the resource URI
+ * @return the resource
+ * @throws IOException if an I/O error occurred
+ */
+ public Resource getResource(URI uri) throws IOException {
+ if (uri.getScheme() != null && uri.getScheme().startsWith("data")) {
+ return new Resource(resolveDataURI(uri.toASCIIString()));
+ }
+ return resourceResolver.getResource(resolveFromBase(uri));
+ }
+
+ /**
+ * Returns the OutputStream for a given URI.
+ *
+ * @param uri the URI for the inteded stream
+ * @return the output stream
+ * @throws IOException if an I/O error occurrred
+ */
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ return resourceResolver.getOutputStream(resolveFromBase(uri));
+ }
+
+ /**
+ * Resolves a URI against the base URI.
+ *
+ * @param uri the URI that requires resolution
+ * @return the resolved URI
+ */
+ public URI resolveFromBase(URI uri) {
+ return baseUri.resolve(uri);
+ }
+
+ /**
+ * Performs some sanitation for some of the most common URI syntax mistakes.
+ *
+ * @param uriStr the URI in String form
+ * @return a valid URI
+ * @throws URISyntaxException if the given String was too erroneous to validate
+ */
+ public static URI cleanURI(String uriStr) throws URISyntaxException {
+ // replace back slash with forward slash to ensure windows file:/// URLS are supported
+ if (uriStr == null) {
+ return null;
+ }
+ String fixedUri = uriStr.replace('\\', '/');
+ fixedUri = fixedUri.replace(" ", "%20");
+ URI baseURI = new URI(fixedUri);
+ return baseURI;
+ }
+
+ /**
+ * Performs some sanitation for some of the most common URI syntax mistakes but returns a
+ * directory URI rather than a file URI.
+ *
+ * @param base the directory URI in String form
+ * @return the directory URI
+ * @throws URISyntaxException if the given String was too erroneous to validate
+ */
+ public static URI getBaseURI(String base) throws URISyntaxException {
+ String path = base + (base.endsWith("/") ? "" : "/");
+ return cleanURI(path);
+ }
+
+ private InputStream resolveDataURI(String dataURI) {
+ try {
+ Source src = dataSchemeResolver.resolve(dataURI, "");
+ return src == null ? null : ((StreamSource) src).getInputStream();
+ } catch (TransformerException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/DefaultFontResolver.java b/src/java/org/apache/fop/apps/io/Resource.java
index 0642537c4..0a8b8c22a 100644
--- a/src/java/org/apache/fop/render/DefaultFontResolver.java
+++ b/src/java/org/apache/fop/apps/io/Resource.java
@@ -17,36 +17,43 @@
/* $Id$ */
-package org.apache.fop.render;
+package org.apache.fop.apps.io;
-import javax.xml.transform.Source;
-
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fonts.FontResolver;
+import java.io.FilterInputStream;
+import java.io.InputStream;
/**
- * Default FontResolver implementation which uses the FOUserAgent to resolve font URIs.
+ * This class represents a resolved resource. The type property is used by FOP to identify the resource
+ * content.
+ *
*/
-public class DefaultFontResolver implements FontResolver {
+public class Resource extends FilterInputStream {
- private FOUserAgent userAgent;
+ private final String type;
/**
- * Main constructor.
- * @param userAgent the user agent
+ * @param type resource type
+ * @param inputStream input stream of the resource
*/
- public DefaultFontResolver(FOUserAgent userAgent) {
- this.userAgent = userAgent;
+ public Resource(String type, InputStream inputStream) {
+ super(inputStream);
+ this.type = type;
}
- /** {@inheritDoc} */
- public Source resolve(String href) {
- return userAgent.resolveURI(href, userAgent.getFactory().getFontManager().getFontBaseURL());
+ /**
+ * Constructs a resource of 'unknown' type.
+ *
+ * @param inputStream input stream of the resource
+ */
+ public Resource(InputStream inputStream) {
+ this("unknown", inputStream);
}
- /** {@inheritDoc} */
- public boolean isComplexScriptFeaturesEnabled() {
- return userAgent.isComplexScriptFeaturesEnabled();
+ /**
+ * @return the resource type
+ */
+ public String getType() {
+ return this.type;
}
}
diff --git a/src/java/org/apache/fop/apps/io/ResourceResolver.java b/src/java/org/apache/fop/apps/io/ResourceResolver.java
new file mode 100644
index 000000000..a3a9cf0c3
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/ResourceResolver.java
@@ -0,0 +1,51 @@
+/*
+ * 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.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+
+/**
+ * Implementations of this resource resolver allow FOP users to control the URI resolution
+ * mechanism. All resource and output stream acquisition goes through this when its implementation
+ * is given to the {@link org.apache.fop.apps.EnvironmentProfile}.
+ */
+public interface ResourceResolver {
+
+ /**
+ * Get a resource given the URI pointing to said resource.
+ *
+ * @param uri the resource URI
+ * @return the resource
+ * @throws IOException if an I/O error occured during resource acquisition
+ */
+ Resource getResource(URI uri) throws IOException;
+
+ /**
+ * Gets an output stream of a given URI.
+ *
+ * @param uri the output stream URI
+ * @return the output stream
+ * @throws IOException if an I/O error occured while creating an output stream
+ */
+ OutputStream getOutputStream(URI uri) throws IOException;
+
+}
diff --git a/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
new file mode 100644
index 000000000..2c8300fb9
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/ResourceResolverFactory.java
@@ -0,0 +1,276 @@
+/*
+ * 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.io;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A factory class for {@link ResourceResolver}s.
+ */
+public final class ResourceResolverFactory {
+
+ private ResourceResolverFactory() {
+ }
+
+ /**
+ * Returns the default resource resolver, this is most basic resolver which can be used when
+ * no there are no I/O or file access restrictions.
+ *
+ * @return the default resource resolver
+ */
+ public static ResourceResolver createDefaultResourceResolver() {
+ return DefaultResourceResolver.INSTANCE;
+ }
+
+ /**
+ * A helper merthod that creates an internal resource resolver using the default resover:
+ * {@link ResourceResolverFactory#createDefaultResourceResolver()}.
+ *
+ * @param baseURI the base URI from which to resolve URIs
+ * @return the default internal resource resolver
+ */
+ public static InternalResourceResolver createDefaultInternalResourceResolver(URI baseURI) {
+ return new InternalResourceResolver(baseURI, createDefaultResourceResolver());
+ }
+
+ /**
+ * Creates an interal resource resolver given a base URI and a resource resolver.
+ *
+ * @param baseURI the base URI from which to resolve URIs
+ * @param resolver the resource resolver
+ * @return the internal resource resolver
+ */
+ public static InternalResourceResolver createInternalResourceResolver(URI baseURI,
+ ResourceResolver resolver) {
+ return new InternalResourceResolver(baseURI, resolver);
+ }
+
+ /**
+ * Creates a temporary-resource-schema aware resource resolver. Temporary resource URIs are
+ * created by {@link TempResourceURIGenerator}.
+ *
+ * @param tempResourceResolver the temporary-resource-schema resolver to use
+ * @param defaultResourceResolver the default resource resolver to use
+ * @return the ressource resolver
+ */
+ public static ResourceResolver createTempAwareResourceResolver(
+ TempResourceResolver tempResourceResolver,
+ ResourceResolver defaultResourceResolver) {
+ return new TempAwareResourceResolver(tempResourceResolver, defaultResourceResolver);
+ }
+
+ public static SchemaAwareResourceResolverBuilder createSchemaAwareResourceResolverBuilder(
+ ResourceResolver defaultResolver) {
+ return new SchemaAwareResourceResolverBuilderImpl(defaultResolver);
+ }
+
+ private static final class DefaultResourceResolver implements ResourceResolver {
+
+ private static final ResourceResolver INSTANCE = new DefaultResourceResolver();
+
+ private final TempAwareResourceResolver delegate;
+
+ private DefaultResourceResolver() {
+ delegate = new TempAwareResourceResolver(new DefaultTempResourceResolver(),
+ new NormalResourceResolver());
+ }
+
+ public Resource getResource(URI uri) throws IOException {
+ return delegate.getResource(uri);
+ }
+
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ return delegate.getOutputStream(uri);
+ }
+
+ }
+
+ private static final class TempAwareResourceResolver implements ResourceResolver {
+
+ private final TempResourceResolver tempResourceResolver;
+
+ private final ResourceResolver defaultResourceResolver;
+
+ public TempAwareResourceResolver(TempResourceResolver tempResourceHandler,
+ ResourceResolver defaultResourceResolver) {
+ this.tempResourceResolver = tempResourceHandler;
+ this.defaultResourceResolver = defaultResourceResolver;
+ }
+
+ private static boolean isTempUri(URI uri) {
+ return TempResourceURIGenerator.isTempUri(uri);
+ }
+
+ public Resource getResource(URI uri) throws IOException {
+ if (isTempUri(uri)) {
+ return tempResourceResolver.getResource(uri.getPath());
+ } else {
+ return defaultResourceResolver.getResource(uri);
+ }
+ }
+
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ if (isTempUri(uri)) {
+ return tempResourceResolver.getOutputStream(uri.getPath());
+ } else {
+ return defaultResourceResolver.getOutputStream(uri);
+ }
+ }
+
+ }
+
+ private static class DefaultTempResourceResolver implements TempResourceResolver {
+ private static File getTempFile(String path) throws IOException {
+ File file = new File(System.getProperty("java.io.tmpdir"), path);
+ file.deleteOnExit();
+ return file;
+ }
+
+ public Resource getResource(String id) throws IOException {
+ return new Resource(getTempFile(id).toURI().toURL().openStream());
+ }
+
+ public OutputStream getOutputStream(String id) throws IOException {
+ File file = getTempFile(id);
+ if (file.createNewFile()) {
+ return new FileOutputStream(file);
+ } else {
+ throw new IOException("Filed to create temporary file: " + id);
+ }
+ }
+ }
+
+ private static class NormalResourceResolver implements ResourceResolver {
+ public Resource getResource(URI uri) throws IOException {
+ return new Resource(uri.toURL().openStream());
+ }
+
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ return new FileOutputStream(new File(uri));
+ }
+ }
+
+ private static final class SchemaAwareResourceResolver implements ResourceResolver {
+
+ private final Map<String, ResourceResolver> schemaHandlingResourceResolvers;
+
+ private final ResourceResolver defaultResolver;
+
+ private SchemaAwareResourceResolver(
+ Map<String, ResourceResolver> schemaHandlingResourceResolvers,
+ ResourceResolver defaultResolver) {
+ this.schemaHandlingResourceResolvers = schemaHandlingResourceResolvers;
+ this.defaultResolver = defaultResolver;
+ }
+
+ private ResourceResolver getResourceResolverForSchema(URI uri) {
+ String schema = uri.getScheme();
+ if (schemaHandlingResourceResolvers.containsKey(schema)) {
+ return schemaHandlingResourceResolvers.get(schema);
+ } else {
+ return defaultResolver;
+ }
+ }
+
+ public Resource getResource(URI uri) throws IOException {
+ return getResourceResolverForSchema(uri).getResource(uri);
+ }
+
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ return getResourceResolverForSchema(uri).getOutputStream(uri);
+ }
+ }
+
+ public interface SchemaAwareResourceResolverBuilder {
+
+ void registerResourceResolverForSchema(String schema, ResourceResolver resourceResolver);
+
+ ResourceResolver build();
+ }
+
+ private static final class CompletedSchemaAwareResourceResolverBuilder
+ implements SchemaAwareResourceResolverBuilder {
+
+ private static final SchemaAwareResourceResolverBuilder INSTANCE
+ = new CompletedSchemaAwareResourceResolverBuilder();
+
+ public ResourceResolver build() {
+ throw new IllegalStateException("Resource resolver already built");
+ }
+
+ public void registerResourceResolverForSchema(String schema,
+ ResourceResolver resourceResolver) {
+ throw new IllegalStateException("Resource resolver already built");
+ }
+ }
+
+ private static final class ActiveSchemaAwareResourceResolverBuilder
+ implements SchemaAwareResourceResolverBuilder {
+
+ private final Map<String, ResourceResolver> schemaHandlingResourceResolvers
+ = new HashMap<String, ResourceResolver>();
+
+ private final ResourceResolver defaultResolver;
+
+ private ActiveSchemaAwareResourceResolverBuilder(ResourceResolver defaultResolver) {
+ this.defaultResolver = defaultResolver;
+ }
+
+ public void registerResourceResolverForSchema(String schema,
+ ResourceResolver resourceResolver) {
+ schemaHandlingResourceResolvers.put(schema, resourceResolver);
+ }
+
+ public ResourceResolver build() {
+ return new SchemaAwareResourceResolver(
+ Collections.unmodifiableMap(schemaHandlingResourceResolvers), defaultResolver);
+ }
+
+ }
+
+ private static final class SchemaAwareResourceResolverBuilderImpl
+ implements SchemaAwareResourceResolverBuilder {
+
+ private SchemaAwareResourceResolverBuilder delegate;
+
+ private SchemaAwareResourceResolverBuilderImpl(ResourceResolver defaultResolver) {
+ this.delegate = new ActiveSchemaAwareResourceResolverBuilder(defaultResolver);
+ }
+
+ public void registerResourceResolverForSchema(String schema,
+ ResourceResolver resourceResolver) {
+ delegate.registerResourceResolverForSchema(schema, resourceResolver);
+ }
+
+ public ResourceResolver build() {
+ ResourceResolver resourceResolver = delegate.build();
+ delegate = CompletedSchemaAwareResourceResolverBuilder.INSTANCE;
+ return resourceResolver;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/apps/io/TempResourceResolver.java b/src/java/org/apache/fop/apps/io/TempResourceResolver.java
new file mode 100644
index 000000000..b17630a1d
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/TempResourceResolver.java
@@ -0,0 +1,48 @@
+/*
+ * 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.io;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Implementations of this interface resolve URIs for temporary files used by FOP. The temporary-
+ * resource URI scheme comes from {@link TempResourceURIGenerator#TMP_SCHEMA}.
+ */
+public interface TempResourceResolver {
+
+ /**
+ * Get a temporary-resource given the URI pointing to said resource.
+ *
+ * @param uri the resource URI
+ * @return the resource
+ * @throws IOException if an I/O error occured during resource acquisition
+ */
+ Resource getResource(String id) throws IOException;
+
+ /**
+ * Gets an temporary-output stream of a given URI.
+ *
+ * @param uri the output stream URI
+ * @return the output stream
+ * @throws IOException if an I/O error occured while creating an output stream
+ */
+ OutputStream getOutputStream(String id) throws IOException;
+}
diff --git a/src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java b/src/java/org/apache/fop/apps/io/TempResourceURIGenerator.java
new file mode 100644
index 000000000..8e6c3606c
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/TempResourceURIGenerator.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.
+ */
+
+package org.apache.fop.apps.io;
+
+import java.net.URI;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Creates a URI for any temporary resource used within FOP.
+ */
+public final class TempResourceURIGenerator {
+
+ public static final String TMP_SCHEMA = "tmp";
+
+ private final String tempURIPrefix;
+
+ private final AtomicLong counter;
+
+ /**
+ * @param uriPrefix a prefix used to name the unique URI
+ */
+ public TempResourceURIGenerator(String uriPrefix) {
+ counter = new AtomicLong();
+ tempURIPrefix = URI.create(TMP_SCHEMA + ":///" + uriPrefix).toASCIIString();
+ }
+
+ /**
+ * Generate a unique URI for a temporary resource
+ * @return the URI
+ */
+ public URI generate() {
+ return URI.create(tempURIPrefix + getUniqueId());
+ }
+
+ private String getUniqueId() {
+ return Long.toHexString(counter.getAndIncrement());
+ }
+
+ public static boolean isTempUri(URI uri) {
+ return TMP_SCHEMA.equals(uri.getScheme());
+ }
+}
diff --git a/src/java/org/apache/fop/apps/io/package.html b/src/java/org/apache/fop/apps/io/package.html
new file mode 100644
index 000000000..d631dc998
--- /dev/null
+++ b/src/java/org/apache/fop/apps/io/package.html
@@ -0,0 +1,6 @@
+<HTML>
+<TITLE>org.apache.fop.io Package</TITLE>
+<BODY>
+<P>Classes that control all IO in FOP.</P>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/src/java/org/apache/fop/area/AreaTreeHandler.java b/src/java/org/apache/fop/area/AreaTreeHandler.java
index c87a728e6..71d22f6d9 100644
--- a/src/java/org/apache/fop/area/AreaTreeHandler.java
+++ b/src/java/org/apache/fop/area/AreaTreeHandler.java
@@ -104,7 +104,7 @@ public class AreaTreeHandler extends FOEventHandler {
setupModel(userAgent, outputFormat, stream);
- this.lmMaker = userAgent.getFactory().getLayoutManagerMakerOverride();
+ this.lmMaker = userAgent.getLayoutManagerMakerOverride();
if (lmMaker == null) {
lmMaker = new LayoutManagerMapping();
}
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java
index ebb35f9bf..e965d15fc 100644
--- a/src/java/org/apache/fop/area/AreaTreeParser.java
+++ b/src/java/org/apache/fop/area/AreaTreeParser.java
@@ -132,7 +132,7 @@ public class AreaTreeParser {
*/
public ContentHandler getContentHandler(AreaTreeModel treeModel, FOUserAgent userAgent) {
ElementMappingRegistry elementMappingRegistry
- = userAgent.getFactory().getElementMappingRegistry();
+ = userAgent.getElementMappingRegistry();
return new Handler(treeModel, userAgent, elementMappingRegistry);
}
@@ -292,7 +292,7 @@ public class AreaTreeParser {
}
} else {
ContentHandlerFactoryRegistry registry
- = userAgent.getFactory().getContentHandlerFactoryRegistry();
+ = userAgent.getContentHandlerFactoryRegistry();
ContentHandlerFactory factory = registry.getFactory(uri);
if (factory != null) {
delegate = factory.createContentHandler();
@@ -1102,7 +1102,7 @@ public class AreaTreeParser {
bkg.setURL(uri);
try {
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
ImageSessionContext sessionContext
= userAgent.getImageSessionContext();
ImageInfo info = manager.getImageInfo(uri, sessionContext);
diff --git a/src/java/org/apache/fop/area/CachedRenderPagesModel.java b/src/java/org/apache/fop/area/CachedRenderPagesModel.java
index 288884a55..fcc82cdd3 100644
--- a/src/java/org/apache/fop/area/CachedRenderPagesModel.java
+++ b/src/java/org/apache/fop/area/CachedRenderPagesModel.java
@@ -21,13 +21,12 @@ package org.apache.fop.area;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
+import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -36,9 +35,9 @@ import org.xml.sax.SAXException;
import org.apache.commons.io.IOUtils;
-import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.io.TempResourceURIGenerator;
import org.apache.fop.fonts.FontInfo;
/**
@@ -49,10 +48,12 @@ import org.apache.fop.fonts.FontInfo;
*/
public class CachedRenderPagesModel extends RenderPagesModel {
- private Map<PageViewport, String> pageMap = new HashMap<PageViewport, String>();
+ private Map<PageViewport, URI> pageMap = new HashMap<PageViewport, URI>();
/** Base directory to save temporary file in, typically points to the user's temp dir. */
- protected File baseDir;
+ private final URI tempBaseURI;
+ private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+ = new TempResourceURIGenerator("cached-pages");
/**
* Main Constructor
@@ -65,8 +66,7 @@ public class CachedRenderPagesModel extends RenderPagesModel {
public CachedRenderPagesModel (FOUserAgent userAgent, String outputFormat,
FontInfo fontInfo, OutputStream stream) throws FOPException {
super(userAgent, outputFormat, fontInfo, stream);
- //TODO: Avoid System.getProperty()?
- this.baseDir = new File(System.getProperty("java.io.tmpdir"));
+ tempBaseURI = TEMP_URI_GENERATOR.generate();
}
/** {@inheritDoc} */
@@ -78,27 +78,19 @@ public class CachedRenderPagesModel extends RenderPagesModel {
if (pageViewport != newpage) {
try {
// load page from cache
- String name = pageMap.get(pageViewport);
- File tempFile = new File(baseDir, name);
- log.debug("Loading page from: " + tempFile);
- ObjectInputStream in = new ObjectInputStream(
- new BufferedInputStream(
- new FileInputStream(tempFile)));
+ URI tempURI = pageMap.get(pageViewport);
+ log.debug("Loading page from: " + tempURI);
+ InputStream inStream = renderer.getUserAgent().getResourceResolver().getResource(tempURI);
+ ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(inStream));
try {
pageViewport.loadPage(in);
} finally {
+ IOUtils.closeQuietly(inStream);
IOUtils.closeQuietly(in);
}
- if (!tempFile.delete()) {
- ResourceEventProducer eventProducer
- = ResourceEventProducer.Provider.get(
- renderer.getUserAgent().getEventBroadcaster());
- eventProducer.cannotDeleteTempFile(this, tempFile);
- }
pageMap.remove(pageViewport);
} catch (Exception e) {
- AreaEventProducer eventProducer
- = AreaEventProducer.Provider.get(
+ AreaEventProducer eventProducer = AreaEventProducer.Provider.get(
renderer.getUserAgent().getEventBroadcaster());
eventProducer.pageLoadError(this, pageViewport.getPageNumberString(), e);
}
@@ -131,18 +123,17 @@ public class CachedRenderPagesModel extends RenderPagesModel {
// save page to cache
ObjectOutputStream tempstream;
String fname = "fop-page-" + page.getPageIndex() + ".ser";
- File tempFile = new File(baseDir, fname);
- tempFile.deleteOnExit();
- tempstream = new ObjectOutputStream(new BufferedOutputStream(
- new FileOutputStream(tempFile)));
+ URI tempURI = tempBaseURI.resolve(fname);
+ OutputStream outStream = renderer.getUserAgent().getResourceResolver().getOutputStream(tempURI);
+ tempstream = new ObjectOutputStream(new BufferedOutputStream(outStream));
try {
page.savePage(tempstream);
} finally {
IOUtils.closeQuietly(tempstream);
}
- pageMap.put(page, fname);
+ pageMap.put(page, tempURI);
if (log.isDebugEnabled()) {
- log.debug("Page saved to temporary file: " + tempFile);
+ log.debug("Page saved to temporary file: " + tempURI);
}
} catch (IOException ioe) {
AreaEventProducer eventProducer
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index 7d5752d6d..aa402aa6a 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -39,9 +39,10 @@ import org.apache.fop.Version;
import org.apache.fop.accessibility.Accessibility;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.fonts.FontManager;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFEncryptionManager;
import org.apache.fop.pdf.PDFEncryptionParams;
@@ -51,7 +52,7 @@ import org.apache.fop.render.awt.AWTRenderer;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFSerializer;
-import org.apache.fop.render.pdf.PDFConfigurationConstants;
+import org.apache.fop.render.pdf.PDFEncryptionOption;
import org.apache.fop.render.print.PagesMode;
import org.apache.fop.render.print.PrintRenderer;
import org.apache.fop.render.xml.XMLRenderer;
@@ -116,12 +117,14 @@ public class CommandLineOptions {
private Map renderingOptions = new java.util.HashMap();
/* target resolution (for the user agent) */
private int targetResolution = 0;
+
+ private boolean strictValidation = true;
/* control memory-conservation policy */
private boolean conserveMemoryPolicy = false;
/* true if a complex script features are enabled */
private boolean useComplexScriptFeatures = true;
- private FopFactory factory = FopFactory.newInstance();
+ private FopFactory factory;
private FOUserAgent foUserAgent;
private InputHandler inputHandler;
@@ -183,9 +186,10 @@ public class CommandLineOptions {
addXSLTParameter("fop-output-format", getOutputFormat());
addXSLTParameter("fop-version", Version.getVersion());
foUserAgent.setConserveMemoryPolicy(conserveMemoryPolicy);
- if (!useComplexScriptFeatures) {
- foUserAgent.setComplexScriptFeaturesEnabled(false);
- }
+ // TODO: Handle this!!
+ //if (!useComplexScriptFeatures) {
+ // foUserAgent.setComplexScriptFeaturesEnabled(false);
+ //}
} else {
return false;
}
@@ -225,9 +229,7 @@ public class CommandLineOptions {
} else if (MimeConstants.MIME_FOP_IF.equals(outputmode)
&& mimicRenderer != null) {
// render from FO to Intermediate Format
- IFSerializer serializer = new IFSerializer();
- serializer.setContext(new IFContext(foUserAgent));
-
+ IFSerializer serializer = new IFSerializer(new IFContext(foUserAgent));
IFDocumentHandler targetHandler
= foUserAgent.getRendererFactory().createDocumentHandler(
foUserAgent, mimicRenderer);
@@ -288,7 +290,7 @@ public class CommandLineOptions {
} else if (args[i].equals("-d")) {
setLogOption("debug", "debug");
} else if (args[i].equals("-r")) {
- factory.setStrictValidation(false);
+ strictValidation = false;
} else if (args[i].equals("-conserve")) {
conserveMemoryPolicy = true;
} else if (args[i].equals("-flush")) {
@@ -819,15 +821,14 @@ public class CommandLineOptions {
}
private PDFEncryptionParams getPDFEncryptionParams() throws FOPException {
- PDFEncryptionParams params = (PDFEncryptionParams)renderingOptions.get(
- PDFConfigurationConstants.ENCRYPTION_PARAMS);
+ PDFEncryptionParams params = (PDFEncryptionParams) renderingOptions.get(PDFEncryptionOption.ENCRYPTION_PARAMS);
if (params == null) {
if (!PDFEncryptionManager.checkAvailableAlgorithms()) {
throw new FOPException("PDF encryption requested but it is not available."
+ " Please make sure MD5 and RC4 algorithms are available.");
}
params = new PDFEncryptionParams();
- renderingOptions.put(PDFConfigurationConstants.ENCRYPTION_PARAMS, params);
+ renderingOptions.put(PDFEncryptionOption.ENCRYPTION_PARAMS, params);
}
return params;
}
@@ -860,7 +861,7 @@ public class CommandLineOptions {
throw new FOPException("You must specify a PDF profile");
} else {
String profile = args[i + 1];
- PDFAMode pdfAMode = PDFAMode.valueOf(profile);
+ PDFAMode pdfAMode = PDFAMode.getValueOf(profile);
if (pdfAMode != null && pdfAMode != PDFAMode.DISABLED) {
if (renderingOptions.get("pdf-a-mode") != null) {
throw new FOPException("PDF/A mode already set");
@@ -868,7 +869,7 @@ public class CommandLineOptions {
renderingOptions.put("pdf-a-mode", pdfAMode.getName());
return 1;
} else {
- PDFXMode pdfXMode = PDFXMode.valueOf(profile);
+ PDFXMode pdfXMode = PDFXMode.getValueOf(profile);
if (pdfXMode != null && pdfXMode != PDFXMode.DISABLED) {
if (renderingOptions.get("pdf-x-mode") != null) {
throw new FOPException("PDF/X mode already set");
@@ -1027,14 +1028,19 @@ public class CommandLineOptions {
* @throws IOException
*/
private void setUserConfig() throws FOPException, IOException {
+ FopFactoryBuilder fopFactoryBuilder;
if (userConfigFile == null) {
- return;
- }
- try {
- factory.setUserConfig(userConfigFile);
- } catch (SAXException e) {
- throw new FOPException(e);
+ fopFactoryBuilder = new FopFactoryBuilder(new File(".").toURI());
+ } else {
+ try {
+ fopFactoryBuilder = new FopConfParser(userConfigFile).getFopFactoryBuilder();
+ } catch (SAXException e) {
+ throw new FOPException(e);
+ }
+ fopFactoryBuilder.setStrictFOValidation(strictValidation);
+ fopFactoryBuilder.setComplexScriptFeatures(useComplexScriptFeatures);
}
+ factory = fopFactoryBuilder.build();
}
/**
@@ -1390,13 +1396,7 @@ public class CommandLineOptions {
}
private void flushCache() throws FOPException {
- FontManager fontManager = factory.getFontManager();
- File cacheFile = fontManager.getCacheFile();
- if (!fontManager.deleteCache()) {
- System.err.println("Failed to flush the font cache file '"
- + cacheFile + "'.");
- System.exit(1);
- }
+ factory.getFontManager().deleteCache();
}
}
diff --git a/src/java/org/apache/fop/cli/IFInputHandler.java b/src/java/org/apache/fop/cli/IFInputHandler.java
index 6b4031a27..f01252cb2 100644
--- a/src/java/org/apache/fop/cli/IFInputHandler.java
+++ b/src/java/org/apache/fop/cli/IFInputHandler.java
@@ -62,7 +62,7 @@ public class IFInputHandler extends InputHandler {
public void renderTo(FOUserAgent userAgent, String outputFormat, OutputStream out)
throws FOPException {
IFDocumentHandler documentHandler
- = userAgent.getFactory().getRendererFactory().createDocumentHandler(
+ = userAgent.getRendererFactory().createDocumentHandler(
userAgent, outputFormat);
try {
documentHandler.setResult(new StreamResult(out));
diff --git a/src/java/org/apache/fop/cli/InputHandler.java b/src/java/org/apache/fop/cli/InputHandler.java
index 5054f12e1..3320c0b1f 100644
--- a/src/java/org/apache/fop/cli/InputHandler.java
+++ b/src/java/org/apache/fop/cli/InputHandler.java
@@ -51,7 +51,6 @@ import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
-import org.apache.fop.apps.FopFactory;
import org.apache.fop.render.awt.viewer.Renderable;
/**
@@ -103,25 +102,11 @@ public class InputHandler implements ErrorListener, Renderable {
public void renderTo(FOUserAgent userAgent, String outputFormat, OutputStream out)
throws FOPException {
- FopFactory factory = userAgent.getFactory();
Fop fop;
if (out != null) {
- fop = factory.newFop(outputFormat, userAgent, out);
+ fop = userAgent.newFop(outputFormat, out);
} else {
- fop = factory.newFop(outputFormat, userAgent);
- }
-
- // if base URL was not explicitly set in FOUserAgent, obtain here
- if (fop.getUserAgent().getBaseURL() == null && sourcefile != null) {
- String baseURL = null;
-
- try {
- baseURL = new File(sourcefile.getAbsolutePath())
- .getParentFile().toURI().toURL().toExternalForm();
- } catch (Exception e) {
- baseURL = "";
- }
- fop.getUserAgent().setBaseURL(baseURL);
+ fop = userAgent.newFop(outputFormat);
}
// Resulting SAX events (the generated FO) must be piped through to FOP
diff --git a/src/java/org/apache/fop/fo/FOTreeBuilder.java b/src/java/org/apache/fop/fo/FOTreeBuilder.java
index e312a8038..9040c464a 100644
--- a/src/java/org/apache/fop/fo/FOTreeBuilder.java
+++ b/src/java/org/apache/fop/fo/FOTreeBuilder.java
@@ -99,7 +99,7 @@ public class FOTreeBuilder extends DefaultHandler {
throws FOPException {
this.userAgent = foUserAgent;
- this.elementMappingRegistry = userAgent.getFactory().getElementMappingRegistry();
+ this.elementMappingRegistry = userAgent.getElementMappingRegistry();
//This creates either an AreaTreeHandler and ultimately a Renderer, or
//one of the RTF-, MIF- etc. Handlers.
foEventHandler = foUserAgent.getRendererFactory().createFOEventHandler(
diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java
index 0852c6e29..c9e9250f0 100644
--- a/src/java/org/apache/fop/fo/PropertyList.java
+++ b/src/java/org/apache/fop/fo/PropertyList.java
@@ -27,7 +27,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.util.QName;
-import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.expr.PropertyException;
import org.apache.fop.fo.properties.CommonAbsolutePosition;
import org.apache.fop.fo.properties.CommonAural;
@@ -308,7 +308,7 @@ public abstract class PropertyList {
String attributeNS;
String attributeName;
String attributeValue;
- FopFactory factory = getFObj().getUserAgent().getFactory();
+ FOUserAgent userAgent = getFObj().getUserAgent();
for (int i = 0; i < attributes.getLength(); i++) {
/* convert all attributes with the same namespace as the fo element
* the "xml:lang" and "xml:base" properties are special cases */
@@ -319,8 +319,8 @@ public abstract class PropertyList {
|| "xml:lang".equals(attributeName)
|| "xml:base".equals(attributeName)) {
convertAttributeToProperty(attributes, attributeName, attributeValue);
- } else if (!factory.isNamespaceIgnored(attributeNS)) {
- ElementMapping mapping = factory.getElementMappingRegistry().getElementMapping(
+ } else if (!userAgent.isNamespaceIgnored(attributeNS)) {
+ ElementMapping mapping = userAgent.getElementMappingRegistry().getElementMapping(
attributeNS);
QName attr = new QName(attributeNS, attributeName);
if (mapping != null) {
diff --git a/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java b/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java
index 72cf19bc7..577efcdf4 100644
--- a/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java
+++ b/src/java/org/apache/fop/fo/extensions/svg/SVGElement.java
@@ -23,7 +23,7 @@ package org.apache.fop.fo.extensions.svg;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import java.net.URL;
+import java.net.URI;
import org.w3c.dom.Element;
@@ -71,12 +71,10 @@ public class SVGElement extends SVGObj {
/* if width and height are zero, get the bounds of the content. */
try {
- URL baseURL = new URL(getUserAgent().getBaseURL() == null
- ? new java.io.File("").toURI().toURL().toExternalForm()
- : getUserAgent().getBaseURL());
- if (baseURL != null) {
+ URI baseUri = getUserAgent().getResourceResolver().getBaseURI();
+ if (baseUri != null) {
SVGOMDocument svgdoc = (SVGOMDocument)doc;
- svgdoc.setURLObject(baseURL);
+ svgdoc.setURLObject(baseUri.toURL());
//The following line should not be called to leave FOP compatible to Batik 1.6.
//svgdoc.setDocumentURI(baseURL.toString());
}
diff --git a/src/java/org/apache/fop/fo/flow/ExternalGraphic.java b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
index 0dd8ed9f8..dc8584abc 100644
--- a/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
+++ b/src/java/org/apache/fop/fo/flow/ExternalGraphic.java
@@ -75,7 +75,7 @@ public class ExternalGraphic extends AbstractGraphics {
//Additional processing: obtain the image's intrinsic size and baseline information
url = URISpecification.getURL(src);
FOUserAgent userAgent = getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
ImageInfo info = null;
try {
info = manager.getImageInfo(url, userAgent.getImageSessionContext());
diff --git a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
index 050da71bb..f7053f8ee 100644
--- a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
+++ b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
@@ -426,7 +426,7 @@ public class CommonBorderPaddingBackground {
String uri = URISpecification.getURL(newInstance.backgroundImage);
FObj fobj = pList.getFObj();
FOUserAgent userAgent = pList.getFObj().getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
ImageSessionContext sessionContext = userAgent.getImageSessionContext();
ImageInfo info;
try {
diff --git a/src/java/org/apache/fop/fonts/CIDFont.java b/src/java/org/apache/fop/fonts/CIDFont.java
index 8f468f7a4..82213dd65 100644
--- a/src/java/org/apache/fop/fonts/CIDFont.java
+++ b/src/java/org/apache/fop/fonts/CIDFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.fonts;
+import org.apache.fop.apps.io.InternalResourceResolver;
+
//Java
/**
@@ -29,6 +31,13 @@ public abstract class CIDFont extends CustomFont {
/** Contains the character widths for all characters in the font */
protected int[] width = null;
+ /**
+ * @param resourceResolver the URI resolver for controlling file access
+ */
+ public CIDFont(InternalResourceResolver resourceResolver) {
+ super(resourceResolver);
+ }
+
// ---- Required ----
/**
* Returns the type of the CID font.
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index 89f515205..70961a55c 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -20,13 +20,15 @@
package org.apache.fop.fonts;
import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.Source;
+import org.apache.fop.apps.io.InternalResourceResolver;
/**
@@ -35,27 +37,27 @@ import javax.xml.transform.Source;
public abstract class CustomFont extends Typeface
implements FontDescriptor, MutableFont {
- private String fontName = null;
- private String fullName = null;
- private Set<String> familyNames = null;
- private String fontSubName = null;
- private String embedFileName = null;
- private String embedResourceName = null;
- private FontResolver resolver = null;
+ private String fontName;
+ private String fullName;
+ private Set<String> familyNames;
+ private String fontSubName;
+ private URI embedFileURI;
+ private String embedResourceName;
+ private final InternalResourceResolver resourceResolver;
private EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
- private int capHeight = 0;
- private int xHeight = 0;
- private int ascender = 0;
- private int descender = 0;
+ private int capHeight;
+ private int xHeight;
+ private int ascender;
+ private int descender;
private int[] fontBBox = {0, 0, 0, 0};
private int flags = 4;
- private int weight = 0; //0 means unknown weight
- private int stemV = 0;
- private int italicAngle = 0;
- private int missingWidth = 0;
+ private int weight; //0 means unknown weight
+ private int stemV;
+ private int italicAngle;
+ private int missingWidth;
private FontType fontType = FontType.TYPE1;
- private int firstChar = 0;
+ private int firstChar;
private int lastChar = 255;
private Map<Integer, Map<Integer, Integer>> kerning;
@@ -63,6 +65,12 @@ public abstract class CustomFont extends Typeface
private boolean useKerning = true;
private boolean useAdvanced = true;
+ /**
+ * @param resourceResolver the URI resource resolver for controlling file access
+ */
+ public CustomFont(InternalResourceResolver resourceResolver) {
+ this.resourceResolver = resourceResolver;
+ }
/** the character map, mapping Unicode ranges to glyph indices. */
protected CMapSegment[] cmap;
@@ -107,15 +115,16 @@ public abstract class CustomFont extends Typeface
}
/**
- * Returns an URI representing an embeddable font file. The URI will often
- * be a filename or an URL.
+ * Returns an URI representing an embeddable font file.
+ *
* @return URI to an embeddable font file or null if not available.
*/
- public String getEmbedFileName() {
- return embedFileName;
+ public URI getEmbedFileURI() {
+ return embedFileURI;
}
/**
+
* Returns the embedding mode for this font.
* @return embedding mode
*/
@@ -124,20 +133,13 @@ public abstract class CustomFont extends Typeface
}
/**
- * Returns a Source representing an embeddable font file.
- * @return Source for an embeddable font file
+ * Returns an {@link InputStream} representing an embeddable font file.
+ *
+ * @return {@link InputStream} for an embeddable font file
* @throws IOException if embedFileName is not null but Source is not found
*/
- public Source getEmbedFileSource() throws IOException {
- Source result = null;
- if (resolver != null && embedFileName != null) {
- result = resolver.resolve(embedFileName);
- if (result == null) {
- throw new IOException("Unable to resolve Source '"
- + embedFileName + "' for embedded font");
- }
- }
- return result;
+ public InputStream getInputStream() throws IOException {
+ return resourceResolver.getResource(embedFileURI);
}
/**
@@ -335,8 +337,8 @@ public abstract class CustomFont extends Typeface
/**
* {@inheritDoc}
*/
- public void setEmbedFileName(String path) {
- this.embedFileName = path;
+ public void setEmbedURI(URI path) {
+ this.embedFileURI = path;
}
/**
@@ -463,14 +465,6 @@ public abstract class CustomFont extends Typeface
this.useAdvanced = enabled;
}
- /**
- * Sets the font resolver. Needed for URI resolution.
- * @param resolver the font resolver
- */
- public void setResolver(FontResolver resolver) {
- this.resolver = resolver;
- }
-
/** {@inheritDoc} */
public void putKerningEntry(Integer key, Map<Integer, Integer> value) {
if (kerning == null) {
diff --git a/src/java/org/apache/fop/fonts/CustomFontCollection.java b/src/java/org/apache/fop/fonts/CustomFontCollection.java
index fc8c947e4..35231e224 100644
--- a/src/java/org/apache/fop/fonts/CustomFontCollection.java
+++ b/src/java/org/apache/fop/fonts/CustomFontCollection.java
@@ -21,13 +21,16 @@ package org.apache.fop.fonts;
import java.util.List;
+import org.apache.fop.apps.io.InternalResourceResolver;
+
/**
* Sets up a set of custom (embedded) fonts
*/
public class CustomFontCollection implements FontCollection {
- private FontResolver fontResolver;
private final List<EmbedFontInfo> embedFontInfoList;
+ private final InternalResourceResolver uriResolver;
+ private final boolean useComplexScripts;
/**
* Main constructor.
@@ -35,14 +38,11 @@ public class CustomFontCollection implements FontCollection {
* @param customFonts the list of custom fonts
* @param useComplexScriptFeatures true if complex script features enabled
*/
- public CustomFontCollection(FontResolver fontResolver,
- List<EmbedFontInfo> customFonts, boolean useComplexScriptFeatures) {
- this.fontResolver = fontResolver;
- if (this.fontResolver == null) {
- //Ensure that we have minimal font resolution capabilities
- this.fontResolver = FontManager.createMinimalFontResolver(useComplexScriptFeatures);
- }
+ public CustomFontCollection(InternalResourceResolver fontResolver,
+ List<EmbedFontInfo> customFonts, boolean useComplexScriptFeatures) {
+ this.uriResolver = fontResolver;
this.embedFontInfoList = customFonts;
+ this.useComplexScripts = useComplexScriptFeatures;
}
/** {@inheritDoc} */
@@ -52,22 +52,14 @@ public class CustomFontCollection implements FontCollection {
}
String internalName = null;
- //FontReader reader = null;
for (int i = 0; i < embedFontInfoList.size(); i++) {
EmbedFontInfo embedFontInfo = embedFontInfoList.get(i);
- //String metricsFile = configFontInfo.getMetricsFile();
internalName = "F" + num;
num++;
- /*
- reader = new FontReader(metricsFile);
- reader.useKerning(configFontInfo.getKerning());
- reader.setFontEmbedPath(configFontInfo.getEmbedFile());
- fontInfo.addMetrics(internalName, reader.getFont());
- */
- LazyFont font = new LazyFont(embedFontInfo, this.fontResolver);
+ LazyFont font = new LazyFont(embedFontInfo, this.uriResolver, useComplexScripts);
fontInfo.addMetrics(internalName, font);
List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfig.java b/src/java/org/apache/fop/fonts/DefaultFontConfig.java
new file mode 100644
index 000000000..6c5cebb42
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/DefaultFontConfig.java
@@ -0,0 +1,343 @@
+/*
+ * 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.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.events.EventProducer;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * The font configuration data for the more generic fonts such as TTF and Type1, that are used by
+ * most the renderers.
+ */
+public final class DefaultFontConfig implements FontConfig {
+
+ private static final Log log = LogFactory.getLog(DefaultFontConfig.class);
+
+ private final List<Directory> directories = new ArrayList<Directory>();
+
+ private final List<Font> fonts = new ArrayList<Font>();
+
+ private final List<String> referencedFontFamilies = new ArrayList<String>();
+
+ private final boolean autoDetectFonts;
+
+ private DefaultFontConfig(boolean autoDetectFonts) {
+ this.autoDetectFonts = autoDetectFonts;
+ }
+
+ /**
+ * Parses the morge generic font information.
+ */
+ public static final class DefaultFontConfigParser implements FontConfig.FontConfigParser {
+ /**
+ * Parses the font configuration and return the configuration object.
+ *
+ * @param cfg the configuration data
+ * @param strict whether or not to enforce strict validation
+ * @return the font configuration object
+ * @throws FOPException if an error occurs when creating the configuration object
+ */
+ public DefaultFontConfig parse(Configuration cfg, boolean strict) throws FOPException {
+ return new ParserHelper(cfg, strict).instance;
+ }
+
+ /** {@inheritDoc} */
+ public FontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
+ EventProducer eventProducer) throws FOPException {
+ return parse(cfg, strict);
+ }
+ }
+
+ private static final class ParserHelper {
+
+ private boolean strict;
+
+ private Configuration fontInfoCfg;
+
+ private DefaultFontConfig instance;
+
+ private ParserHelper(Configuration cfg, boolean strict) throws FOPException {
+ if (cfg == null || cfg.getChild("fonts", false) == null) {
+ instance = null;
+ } else {
+ this.strict = strict;
+ this.fontInfoCfg = cfg.getChild("fonts", false);
+ instance = new DefaultFontConfig(cfg.getChild("auto-detect", false) != null);
+ parse();
+ }
+ }
+
+ private void parse() throws FOPException {
+ parseFonts();
+ parseReferencedFonts();
+ parseDirectories();
+ }
+
+ private void parseFonts() throws FOPException {
+ for (Configuration fontCfg : fontInfoCfg.getChildren("font")) {
+ String embed = fontCfg.getAttribute("embed-url", null);
+ if (embed == null) {
+ LogUtil.handleError(log, "Font configuration without embed-url attribute",
+ strict);
+ continue;
+ }
+ Font font = new Font(fontCfg.getAttribute("metrics-url", null), embed,
+ fontCfg.getAttribute("sub-font", null), fontCfg.getAttributeAsBoolean(
+ "kerning", true), fontCfg.getAttributeAsBoolean("advanced", true),
+ fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName()),
+ fontCfg.getAttribute("embedding-mode", EncodingMode.AUTO.getName()));
+ instance.fonts.add(font);
+ boolean hasTriplets = false;
+ for (Configuration tripletCfg : fontCfg.getChildren("font-triplet")) {
+ FontTriplet fontTriplet = getFontTriplet(tripletCfg, strict);
+ font.tripletList.add(fontTriplet);
+ hasTriplets = true;
+ }
+ // no font triplet info
+ if (!hasTriplets) {
+ LogUtil.handleError(log, "font without font-triplet", strict);
+ }
+ }
+ }
+
+ private void parseReferencedFonts() throws FOPException {
+ Configuration referencedFontsCfg = fontInfoCfg.getChild("referenced-fonts", false);
+ if (referencedFontsCfg != null) {
+ for (Configuration match : referencedFontsCfg.getChildren("match")) {
+ try {
+ instance.referencedFontFamilies.add(match.getAttribute("font-family"));
+ } catch (ConfigurationException ce) {
+ LogUtil.handleException(log, ce, strict);
+ continue;
+ }
+ }
+ }
+ }
+
+ private void parseDirectories() throws FOPException {
+ for (Configuration directoriesCfg : fontInfoCfg.getChildren("directory")) {
+ boolean recursive = directoriesCfg.getAttributeAsBoolean("recursive", false);
+ String directory;
+ try {
+ directory = directoriesCfg.getValue();
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, strict);
+ continue;
+ }
+ if (directory == null) {
+ LogUtil.handleException(log,
+ new FOPException("directory defined without value"), strict);
+ continue;
+ }
+ instance.directories.add(new Directory(directory, recursive));
+ }
+ }
+
+ /**
+ * Creates a new FontTriplet given a triple Configuration
+ *
+ * @param tripletCfg a triplet configuration
+ * @return a font triplet font key
+ * @throws FOPException thrown if a FOP exception occurs
+ */
+ private FontTriplet getFontTriplet(Configuration tripletCfg, boolean strict)
+ throws FOPException {
+ try {
+ String name = tripletCfg.getAttribute("name");
+ if (name == null) {
+ LogUtil.handleError(log, "font-triplet without name", strict);
+ return null;
+ }
+ String weightStr = tripletCfg.getAttribute("weight");
+ if (weightStr == null) {
+ LogUtil.handleError(log, "font-triplet without weight", strict);
+ return null;
+ }
+ int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr));
+ String style = tripletCfg.getAttribute("style");
+ if (style == null) {
+ LogUtil.handleError(log, "font-triplet without style", strict);
+ return null;
+ } else {
+ style = FontUtil.stripWhiteSpace(style);
+ }
+ return FontInfo.createFontKey(name, style, weight);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(log, e, strict);
+ }
+ return null;
+ }
+
+ }
+
+ /**
+ * Returns the list of fonts that were parsed.
+ * @return a list of fonts
+ */
+ public List<Font> getFonts() {
+ return Collections.unmodifiableList(fonts);
+ }
+
+ /**
+ * Returns a list of directories that were parsed.
+ * @return a list of directories
+ */
+ public List<Directory> getDirectories() {
+ return Collections.unmodifiableList(directories);
+ }
+
+ /**
+ * Returns a list of referenced font families.
+ * @return the referenced font families
+ */
+ public List<String> getReferencedFontFamily() {
+ return Collections.unmodifiableList(referencedFontFamilies);
+ }
+
+ /**
+ * Whether or not to enable auto-detecting of fonts in the system.
+ * @return true to enable auto-detect
+ */
+ public boolean isAutoDetectFonts() {
+ return autoDetectFonts;
+ }
+
+ /**
+ * The directory to find fonts within.
+ */
+ public static final class Directory {
+
+ private final String directory;
+
+ private final boolean recursive;
+
+ private Directory(String directory, boolean recurse) {
+ this.directory = directory;
+ this.recursive = recurse;
+ }
+
+ /**
+ * Returns a String representing the directory to find fonts within.
+ * @return the directory
+ */
+ public String getDirectory() {
+ return directory;
+ }
+
+ /**
+ * Returns whether or not to recurse through the directory when finding fonts.
+ * @return true to recurse through the directory and sub-directories
+ */
+ public boolean isRecursive() {
+ return recursive;
+ }
+ }
+
+ /**
+ * Represents a font object within the FOP conf.
+ */
+ public static final class Font {
+
+ private final String metrics;
+
+ private final String embedUri;
+
+ private final String subFont;
+
+ private final boolean kerning;
+
+ private final boolean advanced;
+
+ private final String encodingMode;
+
+ private final String embeddingMode;
+
+ public String getEncodingMode() {
+ return encodingMode;
+ }
+
+ private final List<FontTriplet> tripletList = new ArrayList<FontTriplet>();
+
+ public List<FontTriplet> getTripletList() {
+ return Collections.unmodifiableList(tripletList);
+ }
+
+ private Font(String metrics, String embed, String subFont, boolean kerning,
+ boolean advanced, String encodingMode, String embeddingMode) {
+ this.metrics = metrics;
+ this.embedUri = embed;
+ this.subFont = subFont;
+ this.kerning = kerning;
+ this.advanced = advanced;
+ this.encodingMode = encodingMode;
+ this.embeddingMode = embeddingMode;
+ }
+
+ /**
+ * Whether or not to allow kerning of glyphs.
+ * @return true to allow glyph kerning
+ */
+ public boolean isKerning() {
+ return kerning;
+ }
+
+ public boolean isAdvanced() {
+ return advanced;
+ }
+
+ /**
+ * Gets the String representing the metrics file.
+ * @return the metrics file
+ */
+ public String getMetrics() {
+ return metrics;
+ }
+
+ /**
+ * Gets the URI of the font to embed.
+ * @return the font URI
+ */
+ public String getEmbedURI() {
+ return embedUri;
+ }
+
+ /**
+ * Gets the sub font within, for example, a TTC.
+ * @return the sub font name
+ */
+ public String getSubFont() {
+ return subFont;
+ }
+
+ public String getEmbeddingMode() {
+ return embeddingMode;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java b/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
new file mode 100644
index 000000000..2c60cf4bf
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/DefaultFontConfigurator.java
@@ -0,0 +1,186 @@
+/*
+ * 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.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.fonts.DefaultFontConfig.Directory;
+import org.apache.fop.fonts.autodetect.FontFileFinder;
+import org.apache.fop.fonts.autodetect.FontInfoFinder;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * The default configurator for fonts. This configurator can configure the more generic fonts used
+ * by the renderers i.e. TTF, Type1 etc...
+ */
+public class DefaultFontConfigurator implements FontConfigurator<EmbedFontInfo> {
+ /** logger instance */
+ protected static final Log log = LogFactory.getLog(DefaultFontConfigurator.class);
+
+ private final FontManager fontManager;
+ private final InternalResourceResolver resourceResolver;
+ private final FontEventListener listener;
+ private final boolean strict;
+
+ /**
+ * Main constructor
+ * @param fontInfoConfig the configuration object
+ * @param fontManager the font manager
+ * @param listener the font event listener
+ * @param strict true if an Exception should be thrown if an error is found.
+ */
+ public DefaultFontConfigurator(FontManager fontManager, FontEventListener listener, boolean strict) {
+ this.fontManager = fontManager;
+ this.resourceResolver = fontManager.getResourceResolver();
+ this.listener = listener;
+ this.strict = strict;
+ }
+
+ /**
+ * Initializes font info settings from the user configuration
+ * @throws FOPException if an exception occurs while processing the configuration
+ */
+ public List<EmbedFontInfo> configure(FontConfig fontInfoConfig) throws FOPException {
+ List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
+ if (fontInfoConfig != null) {
+ assert fontInfoConfig instanceof DefaultFontConfig;
+ DefaultFontConfig adobeFontInfoConfig = (DefaultFontConfig) fontInfoConfig;
+ long start = 0;
+ if (log.isDebugEnabled()) {
+ log.debug("Starting font configuration...");
+ start = System.currentTimeMillis();
+ }
+ FontAdder fontAdder = new FontAdder(fontManager, resourceResolver, listener);
+ // native o/s search (autodetect) configuration
+ fontManager.autoDetectFonts(adobeFontInfoConfig.isAutoDetectFonts(), fontAdder, strict,
+ listener, fontInfoList);
+ // Add configured directories to FontInfo list
+ addDirectories(adobeFontInfoConfig, fontAdder, fontInfoList);
+ // Add configured fonts to FontInfo
+ FontCache fontCache = fontManager.getFontCache();
+ try {
+ addFonts(adobeFontInfoConfig, fontCache, fontInfoList);
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(log, use, strict);
+ }
+ // Update referenced fonts (fonts which are not to be embedded)
+ fontManager.updateReferencedFonts(fontInfoList);
+ // Renderer-specific referenced fonts
+ List<String> referencedFonts = adobeFontInfoConfig.getReferencedFontFamily();
+ if (referencedFonts.size() > 0) {
+ FontTriplet.Matcher matcher = FontManagerConfigurator.createFontsMatcher(
+ referencedFonts, strict);
+ fontManager.updateReferencedFonts(fontInfoList, matcher);
+ }
+ // Update font cache if it has changed
+ fontManager.saveCache();
+ if (log.isDebugEnabled()) {
+ log.debug("Finished font configuration in "
+ + (System.currentTimeMillis() - start) + "ms");
+ }
+ }
+ return Collections.unmodifiableList(fontInfoList);
+ }
+
+ private void addDirectories(DefaultFontConfig fontInfoConfig, FontAdder fontAdder,
+ List<EmbedFontInfo> fontInfoList) throws FOPException {
+ // directory (multiple font) configuration
+ List<Directory> directories = fontInfoConfig.getDirectories();
+ for (Directory directory : directories) {
+ // add fonts found in directory
+ FontFileFinder fontFileFinder = new FontFileFinder(directory.isRecursive() ? -1 : 1, listener);
+ List<URL> fontURLList;
+ try {
+ fontURLList = fontFileFinder.find(directory.getDirectory());
+ fontAdder.add(fontURLList, fontInfoList);
+ } catch (IOException e) {
+ LogUtil.handleException(log, e, strict);
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(log, use, strict);
+ }
+ }
+ }
+
+ private void addFonts(DefaultFontConfig fontInfoConfig, FontCache fontCache,
+ List<EmbedFontInfo> fontInfoList) throws FOPException, URISyntaxException {
+ // font file (singular) configuration
+ List<DefaultFontConfig.Font> fonts = fontInfoConfig.getFonts();
+ for (DefaultFontConfig.Font font : fonts) {
+ EmbedFontInfo embedFontInfo = getFontInfo(font, fontCache);
+ if (embedFontInfo != null) {
+ fontInfoList.add(embedFontInfo);
+ }
+ }
+ }
+
+ private EmbedFontInfo getFontInfo(DefaultFontConfig.Font font, FontCache fontCache)
+ throws FOPException, URISyntaxException {
+ String embed = font.getEmbedURI();
+ String metrics = font.getMetrics();
+ String subFont = font.getSubFont();
+ URI metricsUri = metrics == null ? null : InternalResourceResolver.cleanURI(metrics);
+ URI embedUri = InternalResourceResolver.cleanURI(embed);
+
+ List<FontTriplet> tripletList = font.getTripletList();
+
+ // no font triplet info
+ if (tripletList.size() == 0) {
+ URI fontUri = resourceResolver.resolveFromBase(embedUri);
+ FontInfoFinder finder = new FontInfoFinder();
+ finder.setEventListener(listener);
+ EmbedFontInfo[] infos = finder.find(fontUri, resourceResolver, fontCache);
+ return infos[0]; //When subFont is set, only one font is returned
+ }
+ EncodingMode encodingMode = EncodingMode.getValue(font.getEncodingMode());
+ EmbeddingMode embeddingMode = EmbeddingMode.getValue(font.getEmbeddingMode());
+ EmbedFontInfo embedFontInfo = new EmbedFontInfo(metricsUri, font.isKerning(),
+ font.isAdvanced(), tripletList, embedUri, subFont, encodingMode, embeddingMode);
+ if (fontCache != null) {
+ if (!fontCache.containsFont(embedFontInfo)) {
+ fontCache.addFont(embedFontInfo, resourceResolver);
+ }
+ }
+
+ if (log.isDebugEnabled()) {
+ URI embedFile = embedFontInfo.getEmbedURI();
+ log.debug("Adding font " + (embedFile != null ? embedFile + ", " : "")
+ + "metrics URI " + embedFontInfo.getMetricsURI());
+ for (int j = 0; j < tripletList.size(); ++j) {
+ FontTriplet triplet = tripletList.get(j);
+ log.debug(" Font triplet "
+ + triplet.getName() + ", "
+ + triplet.getStyle() + ", "
+ + triplet.getWeight());
+ }
+ }
+ return embedFontInfo;
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
index 64bd200be..5af3fc5ba 100644
--- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java
+++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
@@ -21,6 +21,7 @@ package org.apache.fop.fonts;
import java.io.IOException;
import java.io.Serializable;
+import java.net.URI;
import java.util.List;
/**
@@ -33,62 +34,66 @@ public class EmbedFontInfo implements Serializable {
/** Serialization Version UID */
private static final long serialVersionUID = 8755432068669997369L;
- /** filename of the metrics file */
- protected String metricsFile;
- /** filename of the main font file */
- protected String embedFile;
+ protected final URI metricsURI;
+ protected final URI embedURI;
/** false, to disable kerning */
- protected boolean kerning;
+ protected final boolean kerning;
/** false, to disable advanced typographic features */
- protected boolean advanced;
+ protected final boolean advanced;
/** the requested encoding mode for the font */
- protected EncodingMode encodingMode = EncodingMode.AUTO;
+ private final EncodingMode encodingMode;
/** the requested embedding mode for this font */
- protected EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
+ private final EmbeddingMode embeddingMode;
/** the PostScript name of the font */
- protected String postScriptName = null;
+ protected String postScriptName;
/** the sub-fontname of the font (used for TrueType Collections, null otherwise) */
- protected String subFontName = null;
+ protected String subFontName;
/** the list of associated font triplets */
- private List<FontTriplet> fontTriplets = null;
+ private List<FontTriplet> fontTriplets;
private transient boolean embedded = true;
/**
* Main constructor
- * @param metricsFile path to the xml file containing font metrics
- * @param kerning true if kerning should be enabled
+ * @param metricsURI the URI of the XML resource containing font metrics
+ * @param kerning True if kerning should be enabled
* @param advanced true if advanced typography features should be enabled
- * @param fontTriplets list of font triplets to associate with this font
- * @param embedFile path to the embeddable font file (may be null)
+ * @param fontTriplets List of font triplets to associate with this font
+ * @param embedURI Path to the embeddable font file (may be null)
* @param subFontName the sub-fontname used for TrueType Collections (null otherwise)
+ * @param encodingMode the encoding mode to use for this font
*/
- public EmbedFontInfo(String metricsFile, boolean kerning, boolean advanced,
- List<FontTriplet> fontTriplets, String embedFile, String subFontName) {
- this.metricsFile = metricsFile;
- this.embedFile = embedFile;
+ public EmbedFontInfo(URI metricsURI, boolean kerning, boolean advanced,
+ List<FontTriplet> fontTriplets, URI embedURI, String subFontName,
+ EncodingMode encodingMode, EmbeddingMode embeddingMode) {
+ this.metricsURI = metricsURI;
+ this.embedURI = embedURI;
this.kerning = kerning;
this.advanced = advanced;
this.fontTriplets = fontTriplets;
this.subFontName = subFontName;
+ this.encodingMode = encodingMode;
+ this.embeddingMode = embeddingMode;
}
/**
- * Returns the path to the metrics file
+ * Returns the URI of the metrics XML resource
+ *
* @return the metrics file path
*/
- public String getMetricsFile() {
- return metricsFile;
+ public URI getMetricsURI() {
+ return metricsURI;
}
/**
- * Returns the path to the embeddable font file
- * @return the font file path
+ * Returns the URI to the embeddable font resource
+ *
+ * @return the font resource URI
*/
- public String getEmbedFile() {
- return embedFile;
+ public URI getEmbedURI() {
+ return embedURI;
}
/**
@@ -145,7 +150,7 @@ public class EmbedFontInfo implements Serializable {
* @return true if the font is embedded, false if it is referenced.
*/
public boolean isEmbedded() {
- if (metricsFile != null && embedFile == null) {
+ if (embedURI == null) {
return false;
} else {
return this.embedded;
@@ -176,28 +181,6 @@ public class EmbedFontInfo implements Serializable {
return this.encodingMode;
}
- /**
- * Sets the requested encoding mode for this font.
- * @param mode the new encoding mode
- */
- public void setEncodingMode(EncodingMode mode) {
- if (mode == null) {
- throw new NullPointerException("mode must not be null");
- }
- this.encodingMode = mode;
- }
-
- /**
- * Sets the embedding mode for this font, currently not supported for Type 1 fonts.
- * @param embeddingMode the new embedding mode.
- */
- public void setEmbeddingMode(EmbeddingMode embeddingMode) {
- if (embeddingMode == null) {
- throw new NullPointerException("embeddingMode must not be null");
- }
- this.embeddingMode = embeddingMode;
- }
-
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
@@ -206,7 +189,7 @@ public class EmbedFontInfo implements Serializable {
/** {@inheritDoc} */
public String toString() {
- return "metrics-url=" + metricsFile + ", embed-url=" + embedFile
+ return "metrics-uri=" + metricsURI + ", embed-uri=" + embedURI
+ ", kerning=" + kerning
+ ", advanced=" + advanced
+ ", enc-mode=" + encodingMode
diff --git a/src/java/org/apache/fop/fonts/FontAdder.java b/src/java/org/apache/fop/fonts/FontAdder.java
index c5e2b8b9f..f585dbfa5 100644
--- a/src/java/org/apache/fop/fonts/FontAdder.java
+++ b/src/java/org/apache/fop/fonts/FontAdder.java
@@ -19,9 +19,11 @@
package org.apache.fop.fonts;
+import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.autodetect.FontInfoFinder;
/**
@@ -29,18 +31,19 @@ import org.apache.fop.fonts.autodetect.FontInfoFinder;
*/
public class FontAdder {
private final FontEventListener listener;
- private final FontResolver resolver;
+ private final InternalResourceResolver resourceResolver;
private final FontManager manager;
/**
* Main constructor
* @param manager a font manager
- * @param resolver a font resolver
+ * @param resourceResolver a font resolver
* @param listener a font event handler
*/
- public FontAdder(FontManager manager, FontResolver resolver, FontEventListener listener) {
+ public FontAdder(FontManager manager, InternalResourceResolver resourceResolver,
+ FontEventListener listener) {
this.manager = manager;
- this.resolver = resolver;
+ this.resourceResolver = resourceResolver;
this.listener = listener;
}
@@ -48,14 +51,16 @@ public class FontAdder {
* Iterates over font url list adding to font info list
* @param fontURLList font file list
* @param fontInfoList a configured font info list
+ * @throws URISyntaxException if a URI syntax error is found
*/
- public void add(List<URL> fontURLList, List<EmbedFontInfo> fontInfoList) {
+ public void add(List<URL> fontURLList, List<EmbedFontInfo> fontInfoList)
+ throws URISyntaxException {
FontCache cache = manager.getFontCache();
FontInfoFinder finder = new FontInfoFinder();
finder.setEventListener(listener);
for (URL fontURL : fontURLList) {
- EmbedFontInfo[] embedFontInfos = finder.find(fontURL, resolver, cache);
+ EmbedFontInfo[] embedFontInfos = finder.find(fontURL.toURI(), resourceResolver, cache);
if (embedFontInfos == null) {
continue;
}
diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java
index 87298a707..35997f3d7 100644
--- a/src/java/org/apache/fop/fonts/FontCache.java
+++ b/src/java/org/apache/fop/fonts/FontCache.java
@@ -29,6 +29,7 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
@@ -40,6 +41,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.util.LogUtil;
/**
@@ -234,9 +236,9 @@ public final class FontCache implements Serializable {
*/
protected static String getCacheKey(EmbedFontInfo fontInfo) {
if (fontInfo != null) {
- String embedFile = fontInfo.getEmbedFile();
- String metricsFile = fontInfo.getMetricsFile();
- return (embedFile != null) ? embedFile : metricsFile;
+ URI embedFile = fontInfo.getEmbedURI();
+ URI metricsFile = fontInfo.getMetricsURI();
+ return (embedFile != null) ? embedFile.toASCIIString() : metricsFile.toASCIIString();
}
return null;
}
@@ -318,7 +320,7 @@ public final class FontCache implements Serializable {
* @param fontInfo
* font info
*/
- public void addFont(EmbedFontInfo fontInfo) {
+ public void addFont(EmbedFontInfo fontInfo, InternalResourceResolver resourceResolver) {
String cacheKey = getCacheKey(fontInfo);
synchronized (changeLock) {
CachedFontFile cachedFontFile;
@@ -329,10 +331,9 @@ public final class FontCache implements Serializable {
}
} else {
// try and determine modified date
- File fontFile = getFileFromUrls(new String[] {
- fontInfo.getEmbedFile(), fontInfo.getMetricsFile() });
- long lastModified = (fontFile != null ? fontFile.lastModified()
- : -1);
+ URI fontUri = resourceResolver.resolveFromBase(fontInfo.getEmbedURI());
+ File fontFile = new File(fontUri);
+ long lastModified = fontFile.lastModified();
cachedFontFile = new CachedFontFile(lastModified);
if (log.isTraceEnabled()) {
log.trace("Font added to cache: " + cacheKey);
@@ -467,8 +468,9 @@ public final class FontCache implements Serializable {
* the URL
* @return the last modified date/time
*/
- public static long getLastModified(URL url) {
+ public static long getLastModified(URI uri) {
try {
+ URL url = uri.toURL();
URLConnection conn = url.openConnection();
try {
return conn.getLastModified();
diff --git a/src/java/org/apache/fop/fonts/FontResolver.java b/src/java/org/apache/fop/fonts/FontCacheManager.java
index bd155482e..fb0a0322b 100644
--- a/src/java/org/apache/fop/fonts/FontResolver.java
+++ b/src/java/org/apache/fop/fonts/FontCacheManager.java
@@ -19,27 +19,35 @@
package org.apache.fop.fonts;
-import javax.xml.transform.Source;
+import java.io.File;
+
+import org.apache.fop.apps.FOPException;
+
/**
- * This interface is used to resolve absolute and relative font URIs.
+ * Fop cache (currently only used for font info caching)
*/
-public interface FontResolver {
+public interface FontCacheManager {
+
+ /**
+ * Loads the font cache into memory from the given file.
+ * @param file the serialized font cache
+ * @return the de-serialized font cache
+ */
+ FontCache load(File file);
/**
- * Called to resolve an URI to a Source instance. The base URI needed by the URIResolver's
- * resolve() method is defined to be implicitly available in this case. If the URI cannot
- * be resolved, null is returned and it is assumed that the FontResolver implementation
- * already warned the user about the problem.
- * @param href An href attribute, which may be relative or absolute.
- * @return A Source object, or null if the href could not resolved.
+ * Serializes the font cache to file.
+ * @param file the file to serialize the font cache to
+ * @throws FOPException if an error occurs serializing the font cache
*/
- Source resolve(String href);
+ void save(File file) throws FOPException;
/**
- * Check whether complex script features are enabled.
- * @return true if FOP is to use complex script features
+ * Deletes the font cache from the file-system.
+ * @param file delete the serialized font cache
+ * @throws FOPException if an error occurs deleting the font cache
*/
- boolean isComplexScriptFeaturesEnabled();
+ void delete(File file) throws FOPException;
}
diff --git a/src/java/org/apache/fop/fonts/FontCacheManagerFactory.java b/src/java/org/apache/fop/fonts/FontCacheManagerFactory.java
new file mode 100644
index 000000000..0236effce
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontCacheManagerFactory.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.fonts;
+
+import java.io.File;
+
+import org.apache.fop.apps.FOPException;
+
+/**
+ * A factory that provides the font caching manager mechanism.
+ *
+ */
+public final class FontCacheManagerFactory {
+
+ private FontCacheManagerFactory() {
+ }
+
+ /**
+ * Create the default font caching mechanism.
+ * @return the font cache manager
+ */
+ public static FontCacheManager createDefault() {
+ return new FontCacheManagerImpl();
+ }
+
+ /**
+ * Create a disabled font caching mechanism which by definition does nothing to cache fonts.
+ * @return a completely restricted font cache manager
+ */
+ public static FontCacheManager createDisabled() {
+ return new DisabledFontCacheManager();
+ }
+
+ private static final class FontCacheManagerImpl implements FontCacheManager {
+
+ private FontCache fontCache;
+
+ public FontCache load(File cacheFile) {
+ if (fontCache == null) {
+ fontCache = FontCache.loadFrom(cacheFile);
+ if (fontCache == null) {
+ fontCache = new FontCache();
+ }
+ }
+ return fontCache;
+ }
+
+ public void save(File cacheFile) throws FOPException {
+ if (fontCache != null && fontCache.hasChanged()) {
+ fontCache.saveTo(cacheFile);
+ }
+ }
+
+ public void delete(File cacheFile) throws FOPException {
+ if (!cacheFile.delete()) {
+ throw new FOPException("Failed to flush the font cache file '" + cacheFile + "'.");
+ }
+ }
+ }
+
+ private static final class DisabledFontCacheManager implements FontCacheManager {
+
+ public FontCache load(File cacheFile) {
+ return null;
+ }
+
+ public void save(File cacheFile) throws FOPException {
+ // nop
+ }
+
+ public void delete(File cacheFile) throws FOPException {
+ throw new FOPException("Font Cache disabled");
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontConfig.java b/src/java/org/apache/fop/fonts/FontConfig.java
new file mode 100644
index 000000000..167baf09e
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontConfig.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.events.EventProducer;
+
+/**
+ * An interface for font configuration information.
+ */
+public interface FontConfig {
+
+ /**
+ * An interface for parsing font configuration information.
+ */
+ public interface FontConfigParser {
+
+ /**
+ * Parse the font configuration and return an object containing all the necessary data.
+ *
+ * @param cfg the configuration object
+ * @param fontManager the font manager
+ * @param strict whether or not to enforce strict validation
+ * @param eventProducer the event producer for handling font events
+ * @return the configuration object
+ * @throws FOPException if an error occurs creating the font configuration object
+ */
+ FontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
+ EventProducer eventProducer) throws FOPException;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/util/ResourceAccessor.java b/src/java/org/apache/fop/fonts/FontConfigurator.java
index 6b9995c44..c1ddb4296 100644
--- a/src/java/org/apache/fop/afp/util/ResourceAccessor.java
+++ b/src/java/org/apache/fop/fonts/FontConfigurator.java
@@ -17,24 +17,23 @@
/* $Id$ */
-package org.apache.fop.afp.util;
+package org.apache.fop.fonts;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
+import java.util.List;
+
+import org.apache.fop.apps.FOPException;
/**
- * Defines an interface through which external resource objects can be accessed.
+ * An abstract FontInfo configurator
*/
-public interface ResourceAccessor {
+// TODO: Make T extends some interface to make the font info type explicit
+public interface FontConfigurator<T> {
/**
- * Creates a new {@link InputStream} for the given URI that allows read access to an external
- * resource.
- * @param uri the URI of an external resource.
- * @return the new input stream
- * @throws IOException if an I/O error occurs while opening the resource
+ * Initializes font info settings from the user configuration
+ * @return a font info list
+ * @throws FOPException if an exception occurs while processing the configuration
*/
- InputStream createInputStream(URI uri) throws IOException;
+ List<T> configure(FontConfig fontInfoConfig) throws FOPException;
}
diff --git a/src/java/org/apache/fop/fonts/FontDetector.java b/src/java/org/apache/fop/fonts/FontDetector.java
index 8cfb0da12..71965f4a4 100644
--- a/src/java/org/apache/fop/fonts/FontDetector.java
+++ b/src/java/org/apache/fop/fonts/FontDetector.java
@@ -17,90 +17,18 @@
/* $Id$ */
+
package org.apache.fop.fonts;
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
import java.util.List;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.xmlgraphics.util.ClasspathResource;
-
import org.apache.fop.apps.FOPException;
-import org.apache.fop.fonts.autodetect.FontFileFinder;
-import org.apache.fop.util.LogUtil;
/**
- * Detector of operating system and classpath fonts
+ * An interface for the font detecting mechanism.
*/
-public class FontDetector {
- private static Log log = LogFactory.getLog(FontDetector.class);
-
- private static final String[] FONT_MIMETYPES = {
- "application/x-font", "application/x-font-truetype"
- };
-
- private final FontManager fontManager;
- private final FontAdder fontAdder;
- private final boolean strict;
- private final FontEventListener eventListener;
-
- /**
- * Main constructor
- * @param manager the font manager
- * @param adder the font adder
- * @param strict true if an Exception should be thrown if an error is found.
- * @param listener for throwing font related events
- */
- public FontDetector(FontManager manager, FontAdder adder, boolean strict,
- FontEventListener listener) {
- this.fontManager = manager;
- this.fontAdder = adder;
- this.strict = strict;
- this.eventListener = listener;
- }
-
- /**
- * Detect installed fonts on the system
- * @param fontInfoList a list of fontinfo to populate
- * @throws FOPException thrown if a problem occurred during detection
- */
- public void detect(List<EmbedFontInfo> fontInfoList) throws FOPException {
- // search in font base if it is defined and
- // is a directory but don't recurse
- FontFileFinder fontFileFinder = new FontFileFinder(eventListener);
- String fontBaseURL = fontManager.getFontBaseURL();
- if (fontBaseURL != null) {
- try {
- File fontBase = FileUtils.toFile(new URL(fontBaseURL));
- if (fontBase != null) {
- List<URL> fontURLList = fontFileFinder.find(fontBase.getAbsolutePath());
- fontAdder.add(fontURLList, fontInfoList);
-
- //Can only use the font base URL if it's a file URL
- }
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- }
- }
-
- // native o/s font directory finding
- List<URL> systemFontList;
- try {
- systemFontList = fontFileFinder.find();
- fontAdder.add(systemFontList, fontInfoList);
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- }
- // classpath font finding
- ClasspathResource resource = ClasspathResource.getInstance();
- for (int i = 0; i < FONT_MIMETYPES.length; i++) {
- fontAdder.add(resource.listResourcesOfMimeType(FONT_MIMETYPES[i]), fontInfoList);
- }
- }
+public interface FontDetector {
+ void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
+ FontEventListener eventListener, List<EmbedFontInfo> fontInfoList) throws FOPException;
}
diff --git a/src/java/org/apache/fop/fonts/FontDetectorFactory.java b/src/java/org/apache/fop/fonts/FontDetectorFactory.java
new file mode 100644
index 000000000..dd96e4a1a
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/FontDetectorFactory.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.util.ClasspathResource;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fonts.autodetect.FontFileFinder;
+import org.apache.fop.util.LogUtil;
+
+/**
+ * A factory that provides the font detecting machanism.
+ */
+public final class FontDetectorFactory {
+ private FontDetectorFactory() {
+ }
+
+ /**
+ * Creates the default font detector
+ * @return the default font detector
+ */
+ public static FontDetector createDefault() {
+ return new DefaultFontDetector();
+ }
+
+ /**
+ * Creates a disabled font detector which, by definition, does nothing to detect fonts.
+ * @return the completely restricted font detector
+ */
+ public static FontDetector createDisabled() {
+ return new DisabledFontDetector();
+ }
+
+
+ private static class DisabledFontDetector implements FontDetector {
+ public void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
+ FontEventListener eventListener, List<EmbedFontInfo> fontInfoList)
+ throws FOPException {
+ // nop
+ }
+ }
+
+ /**
+ * Detector of operating system and classpath fonts
+ */
+ private static class DefaultFontDetector implements FontDetector {
+ private static Log log = LogFactory.getLog(DefaultFontDetector.class);
+
+ private static final String[] FONT_MIMETYPES = {
+ "application/x-font", "application/x-font-truetype"
+ };
+
+ /**
+ * Detect installed fonts on the system
+ * @param fontInfoList a list of fontinfo to populate
+ * @throws FOPException thrown if a problem occurred during detection
+ */
+ public void detect(FontManager fontManager, FontAdder fontAdder, boolean strict,
+ FontEventListener eventListener, List<EmbedFontInfo> fontInfoList)
+ throws FOPException {
+ try {
+ // search in font base if it is defined and
+ // is a directory but don't recurse
+ FontFileFinder fontFileFinder = new FontFileFinder(eventListener);
+ URI fontBaseURI = fontManager.getResourceResolver().getBaseURI();
+ File fontBase = FileUtils.toFile(fontBaseURI.toURL());
+ if (fontBase != null) {
+ List<URL> fontURLList = fontFileFinder.find(fontBase.getAbsolutePath());
+ fontAdder.add(fontURLList, fontInfoList);
+
+ //Can only use the font base URL if it's a file URL
+ }
+
+ // native o/s font directory finding
+ List<URL> systemFontList;
+ systemFontList = fontFileFinder.find();
+ fontAdder.add(systemFontList, fontInfoList);
+
+ // classpath font finding
+ ClasspathResource resource = ClasspathResource.getInstance();
+ for (String mimeTypes : FONT_MIMETYPES) {
+ fontAdder.add(resource.listResourcesOfMimeType(mimeTypes), fontInfoList);
+ }
+ } catch (IOException e) {
+ LogUtil.handleException(log, e, strict);
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(log, use, strict);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
deleted file mode 100644
index 042709884..000000000
--- a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.fonts;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
-import org.apache.avalon.framework.configuration.Configuration;
-import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fonts.autodetect.FontFileFinder;
-import org.apache.fop.fonts.autodetect.FontInfoFinder;
-import org.apache.fop.util.LogUtil;
-
-/**
- * An abstract FontInfo configurator
- */
-public class FontInfoConfigurator {
- /** logger instance */
- protected static final Log log = LogFactory.getLog(FontInfoConfigurator.class);
-
- private final Configuration cfg;
- private final FontManager fontManager;
- private final FontResolver fontResolver;
- private final FontEventListener listener;
- private final boolean strict;
-
- /**
- * Main constructor
- * @param cfg the configuration object
- * @param fontManager the font manager
- * @param fontResolver the font resolver
- * @param listener the font event listener
- * @param strict true if an Exception should be thrown if an error is found.
- */
- public FontInfoConfigurator(Configuration cfg, FontManager fontManager,
- FontResolver fontResolver, FontEventListener listener, boolean strict) {
- this.cfg = cfg;
- this.fontManager = fontManager;
- this.fontResolver = fontResolver;
- this.listener = listener;
- this.strict = strict;
- }
-
- /**
- * Initializes font info settings from the user configuration
- * @param fontInfoList a font info list
- * @throws FOPException if an exception occurs while processing the configuration
- */
- public void configure(List<EmbedFontInfo> fontInfoList)
- throws FOPException {
- Configuration fontsCfg = cfg.getChild("fonts", false);
- if (fontsCfg != null) {
- long start = 0;
- if (log.isDebugEnabled()) {
- log.debug("Starting font configuration...");
- start = System.currentTimeMillis();
- }
-
- FontAdder fontAdder = new FontAdder(fontManager, fontResolver, listener);
-
- // native o/s search (autodetect) configuration
- boolean autodetectFonts = (fontsCfg.getChild("auto-detect", false) != null);
- if (autodetectFonts) {
- FontDetector fontDetector = new FontDetector(fontManager, fontAdder, strict,
- listener);
- fontDetector.detect(fontInfoList);
- }
-
- // Add configured directories to FontInfo list
- addDirectories(fontsCfg, fontAdder, fontInfoList);
-
- // Add fonts from configuration to FontInfo list
- addFonts(fontsCfg, fontManager.getFontCache(), fontInfoList);
-
- // Update referenced fonts (fonts which are not to be embedded)
- fontManager.updateReferencedFonts(fontInfoList);
-
- // Renderer-specific referenced fonts
- Configuration referencedFontsCfg = fontsCfg.getChild("referenced-fonts", false);
- if (referencedFontsCfg != null) {
- FontTriplet.Matcher matcher = FontManagerConfigurator.createFontsMatcher(
- referencedFontsCfg, strict);
- fontManager.updateReferencedFonts(fontInfoList, matcher);
- }
-
- // Update font cache if it has changed
- fontManager.saveCache();
-
- if (log.isDebugEnabled()) {
- log.debug("Finished font configuration in "
- + (System.currentTimeMillis() - start) + "ms");
- }
- }
- }
-
- private void addDirectories(Configuration fontsCfg,
- FontAdder fontAdder, List<EmbedFontInfo> fontInfoList) throws FOPException {
- // directory (multiple font) configuration
- Configuration[] directories = fontsCfg.getChildren("directory");
- for (int i = 0; i < directories.length; i++) {
- boolean recursive = directories[i].getAttributeAsBoolean("recursive", false);
- String directory = null;
- try {
- directory = directories[i].getValue();
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- continue;
- }
- if (directory == null) {
- LogUtil.handleException(log,
- new FOPException("directory defined without value"), strict);
- continue;
- }
-
- // add fonts found in directory
- FontFileFinder fontFileFinder = new FontFileFinder(recursive ? -1 : 1, listener);
- List<URL> fontURLList;
- try {
- fontURLList = fontFileFinder.find(directory);
- fontAdder.add(fontURLList, fontInfoList);
- } catch (IOException e) {
- LogUtil.handleException(log, e, strict);
- }
- }
- }
-
- /**
- * Populates the font info list from the fonts configuration
- * @param fontsCfg a fonts configuration
- * @param fontCache a font cache
- * @param fontInfoList a font info list
- * @throws FOPException if an exception occurs while processing the configuration
- */
- protected void addFonts(Configuration fontsCfg, FontCache fontCache,
- List<EmbedFontInfo> fontInfoList) throws FOPException {
- // font file (singular) configuration
- Configuration[] font = fontsCfg.getChildren("font");
- for (int i = 0; i < font.length; i++) {
- EmbedFontInfo embedFontInfo = getFontInfo(
- font[i], fontCache);
- if (embedFontInfo != null) {
- fontInfoList.add(embedFontInfo);
- }
- }
- }
-
- private static void closeSource(Source src) {
- if (src instanceof StreamSource) {
- StreamSource streamSource = (StreamSource)src;
- IOUtils.closeQuietly(streamSource.getInputStream());
- IOUtils.closeQuietly(streamSource.getReader());
- }
- }
-
- /**
- * Returns a font info from a font node Configuration definition
- *
- * @param fontCfg Configuration object (font node)
- * @param fontCache the font cache (or null if it is disabled)
- * @return the embedded font info
- * @throws FOPException if something's wrong with the config data
- */
- protected EmbedFontInfo getFontInfo(Configuration fontCfg, FontCache fontCache)
- throws FOPException {
- String metricsUrl = fontCfg.getAttribute("metrics-url", null);
- String embedUrl = fontCfg.getAttribute("embed-url", null);
- String subFont = fontCfg.getAttribute("sub-font", null);
-
- if (metricsUrl == null && embedUrl == null) {
- LogUtil.handleError(log,
- "Font configuration without metric-url or embed-url attribute",
- strict);
- return null;
- }
- if (strict) {
- //This section just checks early whether the URIs can be resolved
- //Stream are immediately closed again since they will never be used anyway
- if (embedUrl != null) {
- Source source = fontResolver.resolve(embedUrl);
- closeSource(source);
- if (source == null) {
- LogUtil.handleError(log,
- "Failed to resolve font with embed-url '" + embedUrl + "'", strict);
- return null;
- }
- }
- if (metricsUrl != null) {
- Source source = fontResolver.resolve(metricsUrl);
- closeSource(source);
- if (source == null) {
- LogUtil.handleError(log,
- "Failed to resolve font with metric-url '" + metricsUrl + "'", strict);
- return null;
- }
- }
- }
-
- Configuration[] tripletCfg = fontCfg.getChildren("font-triplet");
-
- // no font triplet info
- if (tripletCfg.length == 0) {
- LogUtil.handleError(log, "font without font-triplet", strict);
-
- File fontFile = FontCache.getFileFromUrls(new String[] {embedUrl, metricsUrl});
- URL fontURL = null;
- try {
- fontURL = fontFile.toURI().toURL();
- } catch (MalformedURLException e) {
- LogUtil.handleException(log, e, strict);
- }
- if (fontFile != null) {
- FontInfoFinder finder = new FontInfoFinder();
- finder.setEventListener(listener);
- EmbedFontInfo[] infos = finder.find(fontURL, fontResolver, fontCache);
- return infos[0]; //When subFont is set, only one font is returned
- } else {
- return null;
- }
- }
-
- List<FontTriplet> tripletList = new java.util.ArrayList<FontTriplet>();
- for (int j = 0; j < tripletCfg.length; j++) {
- FontTriplet fontTriplet = getFontTriplet(tripletCfg[j]);
- tripletList.add(fontTriplet);
- }
-
- boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true);
- boolean useAdvanced = fontCfg.getAttributeAsBoolean("advanced", true);
- EncodingMode encodingMode = EncodingMode.getValue(
- fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName()));
- EmbeddingMode embeddingMode = EmbeddingMode.getValue(
- fontCfg.getAttribute("embedding-mode", EmbeddingMode.AUTO.toString()));
- EmbedFontInfo embedFontInfo
- = new EmbedFontInfo(metricsUrl, useKerning, useAdvanced, tripletList, embedUrl,
- subFont);
- embedFontInfo.setEncodingMode(encodingMode);
- embedFontInfo.setEmbeddingMode(embeddingMode);
-
- boolean skipCachedFont = false;
- if (fontCache != null) {
- if (!fontCache.containsFont(embedFontInfo)) {
- fontCache.addFont(embedFontInfo);
- } else {
- skipCachedFont = true;
- }
- }
-
- if (log.isDebugEnabled()) {
- String embedFile = embedFontInfo.getEmbedFile();
- log.debug( ( skipCachedFont ? "Skipping (cached) font " : "Adding font " )
- + (embedFile != null ? embedFile + ", " : "")
- + "metric file " + embedFontInfo.getMetricsFile());
- for (int j = 0; j < tripletList.size(); ++j) {
- FontTriplet triplet = tripletList.get(j);
- log.debug(" Font triplet "
- + triplet.getName() + ", "
- + triplet.getStyle() + ", "
- + triplet.getWeight());
- }
- }
- return embedFontInfo;
- }
-
- /**
- * Creates a new FontTriplet given a triple Configuration
- *
- * @param tripletCfg a triplet configuration
- * @return a font triplet font key
- * @throws FOPException thrown if a FOP exception occurs
- */
- private FontTriplet getFontTriplet(Configuration tripletCfg) throws FOPException {
- try {
- String name = tripletCfg.getAttribute("name");
- if (name == null) {
- LogUtil.handleError(log, "font-triplet without name", strict);
- return null;
- }
-
- String weightStr = tripletCfg.getAttribute("weight");
- if (weightStr == null) {
- LogUtil.handleError(log, "font-triplet without weight", strict);
- return null;
- }
- int weight = FontUtil.parseCSS2FontWeight(FontUtil.stripWhiteSpace(weightStr));
-
- String style = tripletCfg.getAttribute("style");
- if (style == null) {
- LogUtil.handleError(log, "font-triplet without style", strict);
- return null;
- } else {
- style = FontUtil.stripWhiteSpace(style);
- }
- return FontInfo.createFontKey(name, style, weight);
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, strict);
- }
- return null;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java
index 9bdbcd350..f7ee24cbc 100644
--- a/src/java/org/apache/fop/fonts/FontLoader.java
+++ b/src/java/org/apache/fop/fonts/FontLoader.java
@@ -19,18 +19,13 @@
package org.apache.fop.fonts;
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
+import java.net.URI;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.truetype.TTFFontLoader;
import org.apache.fop.fonts.type1.Type1FontLoader;
@@ -43,9 +38,9 @@ public abstract class FontLoader {
protected static final Log log = LogFactory.getLog(FontLoader.class);
/** URI representing the font file */
- protected String fontFileURI;
- /** the FontResolver to use for font URI resolution */
- protected FontResolver resolver;
+ protected final URI fontFileURI;
+ /** the resource resolver to use for font URI resolution */
+ protected final InternalResourceResolver resourceResolver;
/** the loaded font */
protected CustomFont returnFont;
@@ -65,56 +60,19 @@ public abstract class FontLoader {
* @param useKerning indicates whether kerning information shall be loaded if available
* @param useAdvanced indicates whether advanced typographic information shall be loaded if
* available
- * @param resolver the font resolver used to resolve URIs
+ * @param resourceResolver the font resolver used to resolve URIs
*/
- public FontLoader(String fontFileURI, boolean embedded, boolean useKerning,
- boolean useAdvanced, FontResolver resolver) {
+ public FontLoader(URI fontFileURI, boolean embedded, boolean useKerning,
+ boolean useAdvanced, InternalResourceResolver resourceResolver) {
this.fontFileURI = fontFileURI;
this.embedded = embedded;
this.useKerning = useKerning;
this.useAdvanced = useAdvanced;
- this.resolver = resolver;
+ this.resourceResolver = resourceResolver;
}
- 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 subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
- * @param embedded indicates whether the font is embedded or referenced
- * @param embeddingMode the embedding mode
- * @param encodingMode the requested encoding mode
- * @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, String subFontName,
- boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
- FontResolver resolver) throws IOException {
- return loadFont(fontFile.toURI().toURL(), subFontName,
- embedded, embeddingMode, encodingMode, resolver);
- }
-
- /**
- * Loads a custom font from an URL. In the case of Type 1 fonts, the PFB file must be specified.
- * @param fontUrl the URL representation of the font
- * @param subFontName the sub-fontname of a font (for TrueType Collections, null otherwise)
- * @param embedded indicates whether the font is embedded or referenced
- * @param embeddingMode the embedding mode of the font
- * @param encodingMode the requested encoding mode
- * @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(URL fontUrl, String subFontName,
- boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
- FontResolver resolver) throws IOException {
- return loadFont(fontUrl.toExternalForm(), subFontName,
- embedded, embeddingMode, encodingMode, true, true,
- resolver);
+ private static boolean isType1(URI fontURI) {
+ return fontURI.toASCIIString().toLowerCase().endsWith(".pfb");
}
/**
@@ -127,14 +85,13 @@ public abstract class FontLoader {
* @param useKerning indicates whether kerning information should be loaded if available
* @param useAdvanced indicates whether advanced typographic information shall be loaded if
* available
- * @param resolver the font resolver to use when resolving URIs
+ * @param resourceResolver 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(String fontFileURI, String subFontName,
+ public static CustomFont loadFont(URI fontFileURI, String subFontName,
boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
- boolean useKerning, boolean useAdvanced, FontResolver resolver) throws IOException {
- fontFileURI = fontFileURI.trim();
+ boolean useKerning, boolean useAdvanced, InternalResourceResolver resourceResolver) throws IOException {
boolean type1 = isType1(fontFileURI);
FontLoader loader;
if (type1) {
@@ -146,50 +103,15 @@ public abstract class FontLoader {
throw new IllegalArgumentException(
"Subset embedding for Type 1 fonts is not supported");
}
- loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resolver);
+ loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resourceResolver);
} else {
- loader = new TTFFontLoader(fontFileURI, subFontName,
- embedded, embeddingMode, encodingMode, useKerning, useAdvanced, resolver);
+ loader = new TTFFontLoader(fontFileURI, subFontName, embedded, embeddingMode,
+ encodingMode, useKerning, useAdvanced, resourceResolver);
}
return loader.getFont();
}
/**
- * Opens a font URI 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
- */
- public static InputStream openFontUri(FontResolver resolver, String uri)
- throws IOException, MalformedURLException {
- InputStream in = null;
- if (resolver != null) {
- Source source = resolver.resolve(uri);
- if (source == null) {
- String err = "Cannot load font: failed to create Source for font file "
- + uri;
- throw new IOException(err);
- }
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null && source.getSystemId() != null) {
- in = new java.net.URL(source.getSystemId()).openStream();
- }
- if (in == null) {
- String err = "Cannot load font: failed to create InputStream from"
- + " Source for font file " + uri;
- throw new IOException(err);
- }
- } else {
- in = new URL(uri).openStream();
- }
- return in;
- }
-
- /**
* Reads/parses the font data.
* @throws IOException In case of an I/O error
*/
diff --git a/src/java/org/apache/fop/fonts/FontManager.java b/src/java/org/apache/fop/fonts/FontManager.java
index 9285c94be..e9b021978 100644
--- a/src/java/org/apache/fop/fonts/FontManager.java
+++ b/src/java/org/apache/fop/fonts/FontManager.java
@@ -20,13 +20,10 @@
package org.apache.fop.fonts;
import java.io.File;
-import java.net.MalformedURLException;
import java.util.List;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.FontTriplet.Matcher;
import org.apache.fop.fonts.substitute.FontSubstitutions;
@@ -38,14 +35,13 @@ import org.apache.fop.fonts.substitute.FontSubstitutions;
* font substitution, referenced fonts and similar.
*/
public class FontManager {
- /** Use cache (record previously detected font triplet info) */
- public static final boolean DEFAULT_USE_CACHE = true;
- /** The base URL for all font URL resolutions. */
- private String fontBase = null;
+ /** The resource resolver */
+ private InternalResourceResolver resourceResolver;
+
+ private final FontDetector fontDetector;
- /** Font cache to speed up auto-font configuration (null if disabled) */
- private FontCache fontCache = null;
+ private FontCacheManager fontCacheManager;
/** Font substitutions */
private FontSubstitutions fontSubstitutions = null;
@@ -56,33 +52,33 @@ public class FontManager {
/** FontTriplet matcher for fonts that shall be referenced rather than embedded. */
private FontTriplet.Matcher referencedFontsMatcher;
- /** Enables/disables the use of font caching */
- private boolean useCache = DEFAULT_USE_CACHE;
-
/** Provides a font cache file path **/
private File cacheFile;
/**
* Main constructor
+ *
+ * @param resourceResolver the URI resolver
+ * @param fontDetector the font detector
+ * @param fontCacheManager the font cache manager
*/
- public FontManager() {
+ public FontManager(InternalResourceResolver resourceResolver, FontDetector fontDetector,
+ FontCacheManager fontCacheManager) {
+ this.resourceResolver = resourceResolver;
+ this.fontDetector = fontDetector;
+ this.fontCacheManager = fontCacheManager;
}
/**
- * Sets the font base URL.
- * @param fontBase font base URL
- * @throws MalformedURLException if there's a problem with a URL
+ * Sets the font resource resolver
+ * @param resourceResolver resource resolver
*/
- public void setFontBaseURL(String fontBase) throws MalformedURLException {
- this.fontBase = fontBase;
+ public void setResourceResolver(InternalResourceResolver resourceResolver) {
+ this.resourceResolver = resourceResolver;
}
- /**
- * Returns the font base URL.
- * @return the font base URL (or null if none was set)
- */
- public String getFontBaseURL() {
- return this.fontBase;
+ public InternalResourceResolver getResourceResolver() {
+ return this.resourceResolver;
}
/** @return true if kerning on base 14 fonts is enabled */
@@ -130,29 +126,22 @@ public class FontManager {
* @return the font cache file
*/
public File getCacheFile() {
+ return getCacheFile(false);
+ }
+
+ private File getCacheFile(boolean writable) {
if (cacheFile != null) {
- return this.cacheFile;
+ return cacheFile;
}
- return FontCache.getDefaultCacheFile(false);
+ return FontCache.getDefaultCacheFile(writable);
}
/**
* Whether or not to cache results of font triplet detection/auto-config
* @param useCache use cache or not
*/
- public void setUseCache(boolean useCache) {
- this.useCache = useCache;
- if (!useCache) {
- this.fontCache = null;
- }
- }
-
- /**
- * Cache results of font triplet detection/auto-config?
- * @return true if this font manager uses the cache
- */
- public boolean useCache() {
- return useCache;
+ public void disableFontCache() {
+ fontCacheManager = FontCacheManagerFactory.createDisabled();
}
/**
@@ -160,19 +149,7 @@ public class FontManager {
* @return the font cache
*/
public FontCache getFontCache() {
- if (fontCache == null) {
- if (useCache) {
- if (cacheFile != null) {
- fontCache = FontCache.loadFrom(cacheFile);
- } else {
- fontCache = FontCache.load();
- }
- if (fontCache == null) {
- fontCache = new FontCache();
- }
- }
- }
- return fontCache;
+ return fontCacheManager.load(getCacheFile());
}
/**
@@ -181,31 +158,16 @@ public class FontManager {
* @throws FOPException fop exception
*/
public void saveCache() throws FOPException {
- if (useCache) {
- if (fontCache != null && fontCache.hasChanged()) {
- if (cacheFile != null) {
- fontCache.saveTo(cacheFile);
- } else {
- fontCache.save();
- }
- }
- }
+ fontCacheManager.save(getCacheFile());
}
/**
* Deletes the current FontCache file
* @return Returns true if the font cache file was successfully deleted.
+ * @throws FOPException -
*/
- public boolean deleteCache() {
- boolean deleted = false;
- if (useCache) {
- if (cacheFile != null) {
- deleted = cacheFile.delete();
- } else {
- deleted = FontCache.getDefaultCacheFile(true).delete();
- }
- }
- return deleted;
+ public void deleteCache() throws FOPException {
+ fontCacheManager.delete(getCacheFile(true));
}
/**
@@ -225,34 +187,6 @@ public class FontManager {
}
/**
- * Minimum implemenation of FontResolver.
- */
- public static class MinimalFontResolver implements FontResolver {
- private boolean useComplexScriptFeatures;
- MinimalFontResolver(boolean useComplexScriptFeatures) {
- this.useComplexScriptFeatures = useComplexScriptFeatures;
- }
- /** {@inheritDoc} */
- public Source resolve(String href) {
- //Minimal functionality here
- return new StreamSource(href);
- }
- /** {@inheritDoc} */
- public boolean isComplexScriptFeaturesEnabled() {
- return useComplexScriptFeatures;
- }
- }
-
- /**
- * Create minimal font resolver.
- * @param useComplexScriptFeatures true if complex script features enabled
- * @return a new FontResolver to be used by the font subsystem
- */
- public static FontResolver createMinimalFontResolver(boolean useComplexScriptFeatures) {
- return new MinimalFontResolver ( useComplexScriptFeatures );
- }
-
- /**
* Sets the {@link FontTriplet.Matcher} that can be used to identify the fonts that shall
* be referenced rather than embedded.
* @param matcher the font triplet matcher
@@ -298,4 +232,21 @@ public class FontManager {
}
}
}
+
+ /**
+ * Detect fonts from the operating system via FOPs autodetect mechanism.
+ *
+ * @param autoDetectFonts if autodetect has been enabled
+ * @param fontAdder the font adding mechanism
+ * @param strict whether to enforce strict validation
+ * @param listener the listener for font related events
+ * @param fontInfoList a list of font info objects
+ * @throws FOPException if an exception was thrown auto-detecting fonts
+ */
+ public void autoDetectFonts(boolean autoDetectFonts, FontAdder fontAdder, boolean strict,
+ FontEventListener listener, List<EmbedFontInfo> fontInfoList) throws FOPException {
+ if (autoDetectFonts) {
+ fontDetector.detect(this, fontAdder, strict, listener, fontInfoList);
+ }
+ }
}
diff --git a/src/java/org/apache/fop/fonts/FontManagerConfigurator.java b/src/java/org/apache/fop/fonts/FontManagerConfigurator.java
index 1a900fe2f..c4fe19444 100644
--- a/src/java/org/apache/fop/fonts/FontManagerConfigurator.java
+++ b/src/java/org/apache/fop/fonts/FontManagerConfigurator.java
@@ -20,8 +20,8 @@
package org.apache.fop.fonts;
import java.io.File;
-import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.regex.Pattern;
@@ -31,6 +31,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fonts.substitute.FontSubstitutions;
import org.apache.fop.fonts.substitute.FontSubstitutionsConfigurator;
import org.apache.fop.util.LogUtil;
@@ -45,24 +48,21 @@ public class FontManagerConfigurator {
private final Configuration cfg;
- private URI baseURI = null;
+ private final URI defaultBaseUri;
- /**
- * Main constructor
- * @param cfg the font manager configuration object
- */
- public FontManagerConfigurator(Configuration cfg) {
- this.cfg = cfg;
- }
+ private final ResourceResolver resourceResolver;
/**
* Main constructor
* @param cfg the font manager configuration object
- * @param baseURI the base URI of the configuration
+ * @param defaultBaseUri the default URI base to use for URI resolution
+ * @param resourceResolver the resource resolver
*/
- public FontManagerConfigurator(Configuration cfg, URI baseURI) {
+ public FontManagerConfigurator(Configuration cfg, URI defaultBaseUri,
+ ResourceResolver resourceResolver) {
this.cfg = cfg;
- this.baseURI = baseURI;
+ this.defaultBaseUri = defaultBaseUri;
+ this.resourceResolver = resourceResolver;
}
/**
@@ -75,28 +75,29 @@ public class FontManagerConfigurator {
// caching (fonts)
if (cfg.getChild("use-cache", false) != null) {
try {
- fontManager.setUseCache(cfg.getChild("use-cache").getValueAsBoolean());
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, true);
- }
- }
- if (cfg.getChild("cache-file", false) != null) {
- try {
- fontManager.setCacheFile(new File(cfg.getChild("cache-file").getValue()));
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, true);
+ if (!cfg.getChild("use-cache").getValueAsBoolean()) {
+ fontManager.disableFontCache();
+ } else {
+ if (cfg.getChild("cache-file", false) != null) {
+ fontManager.setCacheFile(new File(cfg.getChild("cache-file").getValue()));
+ }
+ }
+ } catch (ConfigurationException mfue) {
+ LogUtil.handleException(log, mfue, true);
}
}
if (cfg.getChild("font-base", false) != null) {
- String path = cfg.getChild("font-base").getValue(null);
- if (baseURI != null) {
- path = baseURI.resolve(path).normalize().toString();
- }
try {
- fontManager.setFontBaseURL(path);
- } catch (MalformedURLException mfue) {
- LogUtil.handleException(log, mfue, true);
+ URI fontBase = InternalResourceResolver.getBaseURI(cfg.getChild("font-base").getValue(
+ null));
+ fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
+ defaultBaseUri.resolve(fontBase), resourceResolver));
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(log, use, true);
}
+ } else {
+ fontManager.setResourceResolver(ResourceResolverFactory.createInternalResourceResolver(
+ defaultBaseUri, resourceResolver));
}
// [GA] permit configuration control over base14 kerning; without this,
@@ -114,7 +115,6 @@ public class FontManagerConfigurator {
// global font configuration
Configuration fontsCfg = cfg.getChild("fonts", false);
if (fontsCfg != null) {
-
// font substitution
Configuration substitutionsCfg = fontsCfg.getChild("substitutions", false);
if (substitutionsCfg != null) {
@@ -122,7 +122,6 @@ public class FontManagerConfigurator {
new FontSubstitutionsConfigurator(substitutionsCfg).configure(substitutions);
fontManager.setFontSubstitutions(substitutions);
}
-
// referenced fonts (fonts which are not to be embedded)
Configuration referencedFontsCfg = fontsCfg.getChild("referenced-fonts", false);
if (referencedFontsCfg != null) {
@@ -130,7 +129,6 @@ public class FontManagerConfigurator {
referencedFontsCfg, strict);
fontManager.setReferencedFontsMatcher(matcher);
}
-
}
}
@@ -159,6 +157,24 @@ public class FontManagerConfigurator {
return orMatcher;
}
+ /**
+ * Creates a font triplet matcher from a configuration object.
+ * @param fontFamilies the list of font families
+ * @param strict true for strict configuraton error handling
+ * @return the font matcher
+ * @throws FOPException if an error occurs while building the matcher
+ */
+ public static FontTriplet.Matcher createFontsMatcher(
+ List<String> fontFamilies, boolean strict) throws FOPException {
+ List<FontTriplet.Matcher> matcherList = new java.util.ArrayList<FontTriplet.Matcher>();
+ for (String fontFamily : fontFamilies) {
+ matcherList.add(new FontFamilyRegExFontTripletMatcher(fontFamily));
+ }
+ FontTriplet.Matcher orMatcher = new OrFontTripletMatcher(
+ matcherList.toArray(new FontTriplet.Matcher[matcherList.size()]));
+ return orMatcher;
+ }
+
private static class OrFontTripletMatcher implements FontTriplet.Matcher {
private final FontTriplet.Matcher[] matchers;
diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java
index 46ea9123d..68c5c7177 100644
--- a/src/java/org/apache/fop/fonts/FontReader.java
+++ b/src/java/org/apache/fop/fonts/FontReader.java
@@ -21,6 +21,8 @@ package org.apache.fop.fonts;
//Java
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -32,12 +34,12 @@ import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.apps.TTFReader;
/**
@@ -52,19 +54,30 @@ import org.apache.fop.fonts.apps.TTFReader;
*/
public class FontReader extends DefaultHandler {
- // private Locator locator = null; // not used at present
- private boolean isCID = false;
- private CustomFont returnFont = null;
- private MultiByteFont multiFont = null;
- private SingleByteFont singleFont = null;
+ private boolean isCID;
+ private CustomFont returnFont;
+ private MultiByteFont multiFont;
+ private SingleByteFont singleFont;
+ private final InternalResourceResolver resourceResolver;
private StringBuffer text = new StringBuffer();
- private List<Integer> cidWidths = null;
- private int cidWidthIndex = 0;
+ private List<Integer> cidWidths;
+ //private int cidWidthIndex;
- private Map<Integer, Integer> currentKerning = null;
+ private Map<Integer, Integer> currentKerning;
- private List<CMapSegment> bfranges = null;
+ private List<CMapSegment> bfranges;
+
+ /**
+ * Construct a FontReader object from a path to a metric.xml file
+ * and read metric data
+ * @param source Source of the font metric file
+ * @throws FOPException if loading the font fails
+ */
+ public FontReader(InputSource source, InternalResourceResolver resourceResolver) throws FOPException {
+ this.resourceResolver = resourceResolver;
+ createFont(source);
+ }
private void createFont(InputSource source) throws FOPException {
XMLReader parser = null;
@@ -81,11 +94,9 @@ public class FontReader extends DefaultHandler {
}
try {
- parser.setFeature("http://xml.org/sax/features/namespace-prefixes",
- false);
+ parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
} catch (SAXException e) {
- throw new FOPException("You need a SAX parser which supports SAX version 2",
- e);
+ throw new FOPException("You need a SAX parser which supports SAX version 2", e);
}
parser.setContentHandler(this);
@@ -104,8 +115,8 @@ public class FontReader extends DefaultHandler {
* Sets the path to embed a font. A null value disables font embedding.
* @param path URI for the embeddable file
*/
- public void setFontEmbedPath(String path) {
- returnFont.setEmbedFileName(path);
+ public void setFontEmbedURI(URI path) {
+ returnFont.setEmbedURI(path);
}
/**
@@ -125,15 +136,6 @@ public class FontReader extends DefaultHandler {
}
/**
- * Sets the font resolver. Needed for URI resolution.
- * @param resolver the font resolver
- */
- public void setResolver(FontResolver resolver) {
- returnFont.setResolver(resolver);
- }
-
-
- /**
* Get the generated font object
* @return the font
*/
@@ -142,16 +144,6 @@ public class FontReader extends DefaultHandler {
}
/**
- * Construct a FontReader object from a path to a metric.xml file
- * and read metric data
- * @param source Source of the font metric file
- * @throws FOPException if loading the font fails
- */
- public FontReader(InputSource source) throws FOPException {
- createFont(source);
- }
-
- /**
* {@inheritDoc}
*/
@Override
@@ -161,45 +153,41 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
- @Override
- public void setDocumentLocator(Locator locator) {
- // this.locator = locator; // not used at present
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void startElement(String uri, String localName, String qName,
- Attributes attributes) throws SAXException {
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
if (localName.equals("font-metrics")) {
if ("TYPE0".equals(attributes.getValue("type"))) {
- multiFont = new MultiByteFont();
+ multiFont = new MultiByteFont(resourceResolver);
returnFont = multiFont;
isCID = true;
TTFReader.checkMetricsVersion(attributes);
} else if ("TRUETYPE".equals(attributes.getValue("type"))) {
- singleFont = new SingleByteFont();
+ singleFont = new SingleByteFont(resourceResolver);
singleFont.setFontType(FontType.TRUETYPE);
returnFont = singleFont;
isCID = false;
TTFReader.checkMetricsVersion(attributes);
} else {
- singleFont = new SingleByteFont();
+ singleFont = new SingleByteFont(resourceResolver);
singleFont.setFontType(FontType.TYPE1);
returnFont = singleFont;
isCID = false;
}
} else if ("embed".equals(localName)) {
- returnFont.setEmbedFileName(attributes.getValue("file"));
+ try {
+ returnFont.setEmbedURI(InternalResourceResolver.cleanURI(attributes.getValue("file")));
+ } catch (URISyntaxException e) {
+ throw new SAXException("URI syntax error in metrics file: " + e.getMessage(), e);
+ }
returnFont.setEmbedResourceName(attributes.getValue("class"));
} else if ("cid-widths".equals(localName)) {
- cidWidthIndex = getInt(attributes.getValue("start-index"));
+ // This is unused
+ // cidWidthIndex = getInt(attributes.getValue("start-index"));
cidWidths = new ArrayList<Integer>();
} else if ("kerning".equals(localName)) {
currentKerning = new HashMap<Integer, Integer>();
- returnFont.putKerningEntry(new Integer(attributes.getValue("kpx1")),
- currentKerning);
+ returnFont.putKerningEntry(getInt(attributes.getValue("kpx1")),
+ currentKerning);
} else if ("bfranges".equals(localName)) {
bfranges = new ArrayList<CMapSegment>();
} else if ("bf".equals(localName)) {
@@ -208,20 +196,19 @@ public class FontReader extends DefaultHandler {
getInt(attributes.getValue("gi")));
bfranges.add(entry);
} else if ("wx".equals(localName)) {
- cidWidths.add(new Integer(attributes.getValue("w")));
- } else if ("widths".equals(localName)) {
- //singleFont.width = new int[256];
+ cidWidths.add(getInt(attributes.getValue("w")));
+ // } else if ("widths".equals(localName)) {
+ // singleFont.width = new int[256];
} else if ("char".equals(localName)) {
try {
- singleFont.setWidth(Integer.parseInt(attributes.getValue("idx")),
- Integer.parseInt(attributes.getValue("wdt")));
+ singleFont.setWidth(getInt(attributes.getValue("idx")),
+ getInt(attributes.getValue("wdt")));
} catch (NumberFormatException ne) {
- throw new SAXException("Malformed width in metric file: "
- + ne.getMessage(), ne);
+ throw new SAXException("Malformed width in metric file: " + ne.getMessage(), ne);
}
} else if ("pair".equals(localName)) {
- currentKerning.put(new Integer(attributes.getValue("kpx2")),
- new Integer(attributes.getValue("kern")));
+ currentKerning.put(getInt(attributes.getValue("kpx2")),
+ getInt(attributes.getValue("kern")));
}
}
@@ -319,5 +306,4 @@ public class FontReader extends DefaultHandler {
public void characters(char[] ch, int start, int length) {
text.append(ch, start, length);
}
-
}
diff --git a/src/java/org/apache/fop/fonts/FontSetup.java b/src/java/org/apache/fop/fonts/FontSetup.java
index ba31b2d50..f9bae3332 100644
--- a/src/java/org/apache/fop/fonts/FontSetup.java
+++ b/src/java/org/apache/fop/fonts/FontSetup.java
@@ -22,9 +22,7 @@ package org.apache.fop.fonts;
// FOP (base 14 fonts)
import java.util.List;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.base14.Courier;
import org.apache.fop.fonts.base14.CourierBold;
import org.apache.fop.fonts.base14.CourierBoldOblique;
@@ -71,11 +69,11 @@ public final class FontSetup {
*
* @param fontInfo the font info object to set up
* @param embedFontInfoList a list of EmbedFontInfo objects
- * @param resolver the font resolver
+ * @param resourceResolver the font resolver
* @param base14Kerning true if base14 kerning applies
*/
- public static void setup(FontInfo fontInfo, List<EmbedFontInfo> embedFontInfoList,
- FontResolver resolver, boolean base14Kerning) {
+ public static void setup(FontInfo fontInfo, List embedFontInfoList,
+ InternalResourceResolver resourceResolver, boolean base14Kerning) {
fontInfo.addMetrics("F1", new Helvetica(base14Kerning));
fontInfo.addMetrics("F2", new HelveticaOblique(base14Kerning));
fontInfo.addMetrics("F3", new HelveticaBold(base14Kerning));
@@ -181,7 +179,7 @@ public final class FontSetup {
final int startNum = 15;
/* Add configured fonts */
- addConfiguredFonts(fontInfo, embedFontInfoList, startNum, resolver, base14Kerning);
+ addConfiguredFonts(fontInfo, embedFontInfoList, startNum, resourceResolver, base14Kerning);
}
/**
@@ -189,21 +187,16 @@ public final class FontSetup {
* @param fontInfo the font info to set up
* @param embedFontInfoList a list of EmbedFontInfo objects
* @param num starting index for internal font numbering
- * @param resolver the font resolver
+ * @param resourceResolver the font resolver
*/
private static void addConfiguredFonts(FontInfo fontInfo,
- List<EmbedFontInfo> embedFontInfoList, int num, FontResolver resolver,
+ List<EmbedFontInfo> embedFontInfoList, int num,
+ InternalResourceResolver resourceResolver,
boolean base14Kerning) {
if (embedFontInfoList == null) {
return; //No fonts to process
}
-
- if (resolver == null) {
- //Ensure that we have minimal font resolution capabilities
- //None of the built-in base14 fonts have advanced typographic data
- boolean useAdvanced = false;
- resolver = createMinimalFontResolver(useAdvanced);
- }
+ assert resourceResolver != null;
String internalName = null;
@@ -211,7 +204,7 @@ public final class FontSetup {
internalName = "F" + num;
num++;
- LazyFont font = new LazyFont(embedFontInfo, resolver);
+ LazyFont font = new LazyFont(embedFontInfo, resourceResolver, false);
fontInfo.addMetrics(internalName, font);
List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
@@ -221,32 +214,4 @@ public final class FontSetup {
}
}
}
-
- /**
- * Minimum implemenation of FontResolver.
- */
- public static class MinimalFontResolver implements FontResolver {
- private boolean useComplexScriptFeatures;
- MinimalFontResolver(boolean useComplexScriptFeatures) {
- this.useComplexScriptFeatures = useComplexScriptFeatures;
- }
- /** {@inheritDoc} */
- public Source resolve(String href) {
- //Minimal functionality here
- return new StreamSource(href);
- }
- /** {@inheritDoc} */
- public boolean isComplexScriptFeaturesEnabled() {
- return useComplexScriptFeatures;
- }
- }
-
- /**
- * Create minimal font resolver.
- * @param useComplexScriptFeatures true if complex script features enabled
- * @return a new FontResolver to be used by the font subsystem
- */
- public static FontResolver createMinimalFontResolver(boolean useComplexScriptFeatures) {
- return new MinimalFontResolver ( useComplexScriptFeatures );
- }
}
diff --git a/src/java/org/apache/fop/fonts/FontTriplet.java b/src/java/org/apache/fop/fonts/FontTriplet.java
index c14634460..2c1d89088 100644
--- a/src/java/org/apache/fop/fonts/FontTriplet.java
+++ b/src/java/org/apache/fop/fonts/FontTriplet.java
@@ -27,6 +27,8 @@ import java.io.Serializable;
*/
public class FontTriplet implements Comparable<FontTriplet>, Serializable {
+ public static final FontTriplet DEFAULT_FONT_TRIPLET = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+
/** serial version UID */
private static final long serialVersionUID = 1168991106658033508L;
@@ -39,14 +41,6 @@ public class FontTriplet implements Comparable<FontTriplet>, Serializable {
private transient String key;
/**
- * Creates a new font triplet (for base14 use).
- * @param name font name
- */
- public FontTriplet(String name) {
- this.name = name;
- }
-
- /**
* Creates a new font triplet.
* @param name font name
* @param style font style (normal, italic etc.)
@@ -64,7 +58,7 @@ public class FontTriplet implements Comparable<FontTriplet>, Serializable {
* @param priority priority of this triplet/font mapping
*/
public FontTriplet(String name, String style, int weight, int priority) {
- this(name);
+ this.name = name;
this.style = style;
this.weight = weight;
this.priority = priority;
@@ -143,6 +137,5 @@ public class FontTriplet implements Comparable<FontTriplet>, Serializable {
*/
boolean matches(FontTriplet triplet);
}
-
}
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
index dfad4ffce..4c42387f2 100644
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ b/src/java/org/apache/fop/fonts/LazyFont.java
@@ -20,19 +20,17 @@
package org.apache.fop.fonts;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
+import java.net.URI;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.xml.sax.InputSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.complexscripts.fonts.Positionable;
import org.apache.fop.complexscripts.fonts.Substitutable;
@@ -43,49 +41,50 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
private static Log log = LogFactory.getLog(LazyFont.class);
- private String metricsFileName;
- private String fontEmbedPath;
- private boolean useKerning;
- private boolean useAdvanced;
- private EncodingMode encodingMode = EncodingMode.AUTO;
- private EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
- private boolean embedded = true;
- private String subFontName;
+ private final URI metricsURI;
+ private final URI fontEmbedURI;
+ private final boolean useKerning;
+ private final boolean useAdvanced;
+ private final EncodingMode encodingMode;
+ private final EmbeddingMode embeddingMode;
+ private final String subFontName;
+ private final boolean embedded;
+ private final InternalResourceResolver resourceResolver;
private boolean isMetricsLoaded;
private Typeface realFont;
private FontDescriptor realFontDescriptor;
- private FontResolver resolver;
-
/**
* Main constructor
* @param fontInfo the font info to embed
- * @param resolver the font resolver to handle font URIs
+ * @param resourceResolver the font resolver to handle font URIs
*/
- public LazyFont(EmbedFontInfo fontInfo, FontResolver resolver) {
-
- this.metricsFileName = fontInfo.getMetricsFile();
- this.fontEmbedPath = fontInfo.getEmbedFile();
+ public LazyFont(EmbedFontInfo fontInfo, InternalResourceResolver resourceResolver,
+ boolean useComplexScripts) {
+ this.metricsURI = fontInfo.getMetricsURI();
+ this.fontEmbedURI = fontInfo.getEmbedURI();
this.useKerning = fontInfo.getKerning();
- if ( resolver != null ) {
- this.useAdvanced = resolver.isComplexScriptFeaturesEnabled();
+ if (resourceResolver != null) {
+ this.useAdvanced = useComplexScripts;
} else {
this.useAdvanced = fontInfo.getAdvanced();
}
- this.encodingMode = fontInfo.getEncodingMode();
- this.embeddingMode = fontInfo.getEmbeddingMode();
+ this.encodingMode = fontInfo.getEncodingMode() != null ? fontInfo.getEncodingMode()
+ : EncodingMode.AUTO;
+ this.embeddingMode = fontInfo.getEmbeddingMode() != null ? fontInfo.getEmbeddingMode()
+ : EmbeddingMode.AUTO;
this.subFontName = fontInfo.getSubFontName();
this.embedded = fontInfo.isEmbedded();
- this.resolver = resolver;
+ this.resourceResolver = resourceResolver;
}
/** {@inheritDoc} */
public String toString() {
StringBuffer sbuf = new StringBuffer(super.toString());
sbuf.append('{');
- sbuf.append("metrics-url=" + metricsFileName);
- sbuf.append(",embed-url=" + fontEmbedPath);
+ sbuf.append("metrics-url=" + metricsURI);
+ sbuf.append(",embed-url=" + fontEmbedURI);
sbuf.append(",kerning=" + useKerning);
sbuf.append(",advanced=" + useAdvanced);
sbuf.append('}');
@@ -95,75 +94,38 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
private void load(boolean fail) {
if (!isMetricsLoaded) {
try {
- if (metricsFileName != null) {
+ if (metricsURI != null) {
/**@todo Possible thread problem here */
FontReader reader = null;
- if (resolver != null) {
- Source source = resolver.resolve(metricsFileName);
- if (source == null) {
- String err
- = "Cannot load font: failed to create Source from metrics file "
- + metricsFileName;
- if (fail) {
- throw new RuntimeException(err);
- } else {
- log.error(err);
- }
- return;
- }
- InputStream in = null;
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null && source.getSystemId() != null) {
- in = new java.net.URL(source.getSystemId()).openStream();
- }
- if (in == null) {
- String err = "Cannot load font: After URI resolution, the returned"
- + " Source object does not contain an InputStream"
- + " or a valid URL (system identifier) for metrics file: "
- + metricsFileName;
- if (fail) {
- throw new RuntimeException(err);
- } else {
- log.error(err);
- }
- return;
- }
- InputSource src = new InputSource(in);
- src.setSystemId(source.getSystemId());
- reader = new FontReader(src);
- } else {
- reader = new FontReader(new InputSource(
- new URL(metricsFileName).openStream()));
- }
+ InputStream in = resourceResolver.getResource(metricsURI);
+ InputSource src = new InputSource(in);
+ src.setSystemId(metricsURI.toASCIIString());
+ reader = new FontReader(src, resourceResolver);
reader.setKerningEnabled(useKerning);
reader.setAdvancedEnabled(useAdvanced);
if (this.embedded) {
- reader.setFontEmbedPath(fontEmbedPath);
+ reader.setFontEmbedURI(fontEmbedURI);
}
- reader.setResolver(resolver);
realFont = reader.getFont();
} else {
- if (fontEmbedPath == null) {
+ if (fontEmbedURI == null) {
throw new RuntimeException("Cannot load font. No font URIs available.");
}
- realFont = FontLoader.loadFont(fontEmbedPath, subFontName,
- embedded, embeddingMode, encodingMode,
- useKerning, useAdvanced, resolver);
+ realFont = FontLoader.loadFont(fontEmbedURI, subFontName, embedded,
+ embeddingMode, encodingMode, useKerning, useAdvanced, resourceResolver);
}
if (realFont instanceof FontDescriptor) {
realFontDescriptor = (FontDescriptor) realFont;
}
} catch (FOPException fopex) {
- log.error("Failed to read font metrics file " + metricsFileName, fopex);
+ log.error("Failed to read font metrics file " + metricsURI, fopex);
if (fail) {
- throw new RuntimeException(fopex.getMessage());
+ throw new RuntimeException(fopex);
}
} catch (IOException ioex) {
- log.error("Failed to read font metrics file " + metricsFileName, ioex);
+ log.error("Failed to read font metrics file " + metricsURI, ioex);
if (fail) {
- throw new RuntimeException(ioex.getMessage());
+ throw new RuntimeException(ioex);
}
}
realFont.setEventListener(this.eventListener);
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index 54b772b2e..a460140cb 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -26,6 +26,7 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
@@ -68,7 +69,8 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
/**
* Default constructor
*/
- public MultiByteFont() {
+ public MultiByteFont(InternalResourceResolver resourceResolver) {
+ super(resourceResolver);
subset.setupFirstGlyph();
setFontType(FontType.TYPE0);
}
@@ -123,7 +125,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
/** {@inheritDoc} */
public boolean isEmbeddable() {
- return !(getEmbedFileName() == null && getEmbedResourceName() == null);
+ return !(getEmbedFileURI() == null && getEmbedResourceName() == null);
}
public boolean isSubsetEmbedded() {
@@ -553,7 +555,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
}
}
cb.flip();
- return (CharSequence) cb;
+ return cb;
}
}
diff --git a/src/java/org/apache/fop/fonts/MutableFont.java b/src/java/org/apache/fop/fonts/MutableFont.java
index 3ebc3c465..9ea323ebf 100644
--- a/src/java/org/apache/fop/fonts/MutableFont.java
+++ b/src/java/org/apache/fop/fonts/MutableFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts;
+import java.net.URI;
import java.util.Map;
import java.util.Set;
@@ -49,10 +50,10 @@ public interface MutableFont {
void setFamilyNames(Set<String> names);
/**
- * Sets the path to the embeddable font file.
- * @param path URI to the file
+ * Sets the URI to the embeddable font.
+ * @param path URI to the font
*/
- void setEmbedFileName(String path);
+ void setEmbedURI(URI path);
/**
* Sets the resource name of the embeddable font file.
diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java
index 1aed72d69..cd11c7849 100644
--- a/src/java/org/apache/fop/fonts/SingleByteFont.java
+++ b/src/java/org/apache/fop/fonts/SingleByteFont.java
@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.fonts.Glyphs;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
/**
@@ -53,15 +54,16 @@ public class SingleByteFont extends CustomFont {
private PostScriptVersion ttPostScriptVersion;
/**
- * Main constructor.
+ * @param resourceResolver the URI resolver for controlling file access
*/
- public SingleByteFont() {
+ public SingleByteFont(InternalResourceResolver resourceResolver) {
+ super(resourceResolver);
setEncoding(CodePointMapping.WIN_ANSI_ENCODING);
}
/** {@inheritDoc} */
public boolean isEmbeddable() {
- return (!(getEmbedFileName() == null
+ return (!(getEmbedFileURI() == 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 224c8de2f..25b9e3924 100644
--- a/src/java/org/apache/fop/fonts/apps/TTFReader.java
+++ b/src/java/org/apache/fop/fonts/apps/TTFReader.java
@@ -19,7 +19,9 @@
package org.apache.fop.fonts.apps;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.Map;
import java.util.Set;
@@ -219,12 +221,17 @@ public class TTFReader extends AbstractFontReader {
public TTFFile loadTTF(String fileName, String fontName, boolean useKerning, boolean useAdvanced) throws IOException {
TTFFile ttfFile = new TTFFile(useKerning, useAdvanced);
log.info("Reading " + fileName + "...");
-
- FontFileReader reader = new FontFileReader(fileName);
- boolean supported = ttfFile.readFont(reader, fontName);
- if (!supported) {
- return null;
+ InputStream stream = new FileInputStream(fileName);
+ try {
+ FontFileReader reader = new FontFileReader(stream);
+ boolean supported = ttfFile.readFont(reader, fontName);
+ if (!supported) {
+ return null;
+ }
+ } finally {
+ stream.close();
}
+
log.info("Font Family: " + ttfFile.getFamilyNames());
if (ttfFile.isCFF()) {
throw new UnsupportedOperationException(
@@ -465,7 +472,7 @@ public class TTFReader extends AbstractFontReader {
if (isCid || kpx2.intValue() < 256) {
el2 = doc.createElement("pair");
el2.setAttribute("kpx2", kpx2.toString());
- Integer val = (Integer)h2.get(kpx2);
+ Integer val = h2.get(kpx2);
el2.setAttribute("kern", val.toString());
el.appendChild(el2);
}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
index deee4b018..e115264bb 100644
--- a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
+++ b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
@@ -20,7 +20,7 @@
package org.apache.fop.fonts.autodetect;
import java.io.InputStream;
-import java.net.URL;
+import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -30,6 +30,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.EmbeddingMode;
@@ -38,7 +39,6 @@ import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCache;
import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.MultiByteFont;
@@ -134,26 +134,25 @@ public class FontInfoFinder {
/**
* Attempts to determine FontInfo from a given custom font
- * @param fontURL the font URL
+ * @param fontUri the font URI
* @param customFont the custom font
* @param fontCache font cache (may be null)
* @return FontInfo from the given custom font
*/
- private EmbedFontInfo getFontInfoFromCustomFont(
- URL fontURL, CustomFont customFont, FontCache fontCache) {
+ private EmbedFontInfo getFontInfoFromCustomFont(URI fontUri, CustomFont customFont,
+ FontCache fontCache, InternalResourceResolver resourceResolver) {
List<FontTriplet> fontTripletList = new java.util.ArrayList<FontTriplet>();
generateTripletsFromFont(customFont, fontTripletList);
- String embedUrl;
- embedUrl = fontURL.toExternalForm();
String subFontName = null;
if (customFont instanceof MultiByteFont) {
- subFontName = ((MultiByteFont)customFont).getTTCName();
+ subFontName = ((MultiByteFont) customFont).getTTCName();
}
EmbedFontInfo fontInfo = new EmbedFontInfo(null, customFont.isKerningEnabled(),
- customFont.isAdvancedEnabled(), fontTripletList, embedUrl, subFontName);
+ customFont.isAdvancedEnabled(), fontTripletList, fontUri, subFontName,
+ EncodingMode.AUTO, EmbeddingMode.AUTO);
fontInfo.setPostScriptName(customFont.getFontName());
if (fontCache != null) {
- fontCache.addFont(fontInfo);
+ fontCache.addFont(fontInfo, resourceResolver);
}
return fontInfo;
}
@@ -161,32 +160,31 @@ public class FontInfoFinder {
/**
* Attempts to determine EmbedFontInfo from a given font file.
*
- * @param fontURL font URL. Assumed to be local.
- * @param resolver font resolver used to resolve font
+ * @param fontURI the URI of the font resource
+ * @param resourceResolver font resolver used to resolve font
* @param fontCache font cache (may be null)
* @return an array of newly created embed font info. Generally, this array
* will have only one entry, unless the fontUrl is a TrueType Collection
*/
- public EmbedFontInfo[] find(URL fontURL, FontResolver resolver, FontCache fontCache) {
- String embedURL = null;
- embedURL = fontURL.toExternalForm();
+ public EmbedFontInfo[] find(URI fontURI, InternalResourceResolver resourceResolver, FontCache fontCache) {
+ URI embedUri = resourceResolver.resolveFromBase(fontURI);
+ String embedStr = embedUri.toASCIIString();
boolean useKerning = true;
- boolean useAdvanced = ( resolver != null )
- ? resolver.isComplexScriptFeaturesEnabled() : true;
+ boolean useAdvanced = true;
long fileLastModified = -1;
if (fontCache != null) {
- fileLastModified = FontCache.getLastModified(fontURL);
+ fileLastModified = FontCache.getLastModified(fontURI);
// firstly try and fetch it from cache before loading/parsing the font file
- if (fontCache.containsFont(embedURL)) {
- EmbedFontInfo[] fontInfos = fontCache.getFontInfos(embedURL, fileLastModified);
+ if (fontCache.containsFont(embedStr)) {
+ EmbedFontInfo[] fontInfos = fontCache.getFontInfos(embedStr, fileLastModified);
if (fontInfos != null) {
return fontInfos;
}
// is this a previously failed parsed font?
- } else if (fontCache.isFailedFont(embedURL, fileLastModified)) {
+ } else if (fontCache.isFailedFont(embedStr, fileLastModified)) {
if (log.isDebugEnabled()) {
- log.debug("Skipping font file that failed to load previously: " + embedURL);
+ log.debug("Skipping font file that failed to load previously: " + embedUri);
}
return null;
}
@@ -195,19 +193,19 @@ public class FontInfoFinder {
// try to determine triplet information from font file
CustomFont customFont = null;
- if (fontURL.toExternalForm().toLowerCase().endsWith(".ttc")) {
+ if (fontURI.toASCIIString().toLowerCase().endsWith(".ttc")) {
// Get a list of the TTC Font names
List<String> ttcNames = null;
- String fontFileURL = fontURL.toExternalForm().trim();
InputStream in = null;
try {
- in = FontLoader.openFontUri(resolver, fontFileURL);
+ in = resourceResolver.getResource(fontURI);
TTFFile ttf = new TTFFile(false, false);
FontFileReader reader = new FontFileReader(in);
ttcNames = ttf.getTTCnames(reader);
} catch (Exception e) {
if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this, fontFileURL, e);
+ this.eventListener.fontLoadingErrorAtAutoDetection(this,
+ fontURI.toASCIIString(), e);
}
return null;
} finally {
@@ -222,23 +220,25 @@ public class FontInfoFinder {
log.debug("Loading " + fontName);
}
try {
- TTFFontLoader ttfLoader = new TTFFontLoader(
- fontFileURL, fontName, true, EmbeddingMode.AUTO, EncodingMode.AUTO,
- useKerning, useAdvanced, resolver);
+ TTFFontLoader ttfLoader = new TTFFontLoader(fontURI, fontName, true,
+ EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useAdvanced,
+ resourceResolver);
customFont = ttfLoader.getFont();
if (this.eventListener != null) {
customFont.setEventListener(this.eventListener);
}
} catch (Exception e) {
if (fontCache != null) {
- fontCache.registerFailedFont(embedURL, fileLastModified);
+ fontCache.registerFailedFont(embedUri.toASCIIString(), fileLastModified);
}
if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this, embedURL, e);
+ this.eventListener.fontLoadingErrorAtAutoDetection(this,
+ embedUri.toASCIIString(), e);
}
continue;
}
- EmbedFontInfo fi = getFontInfoFromCustomFont(fontURL, customFont, fontCache);
+ EmbedFontInfo fi = getFontInfoFromCustomFont(fontURI, customFont, fontCache,
+ resourceResolver);
if (fi != null) {
embedFontInfoList.add(fi);
}
@@ -248,21 +248,22 @@ public class FontInfoFinder {
} else {
// The normal case
try {
- customFont = FontLoader.loadFont(fontURL, null, true, EmbeddingMode.AUTO,
- EncodingMode.AUTO, resolver);
+ customFont = FontLoader.loadFont(fontURI, null, true, EmbeddingMode.AUTO,
+ EncodingMode.AUTO, useKerning, useAdvanced, resourceResolver);
if (this.eventListener != null) {
customFont.setEventListener(this.eventListener);
}
} catch (Exception e) {
if (fontCache != null) {
- fontCache.registerFailedFont(embedURL, fileLastModified);
+ fontCache.registerFailedFont(embedUri.toASCIIString(), fileLastModified);
}
if (this.eventListener != null) {
- this.eventListener.fontLoadingErrorAtAutoDetection(this, embedURL, e);
+ this.eventListener.fontLoadingErrorAtAutoDetection(this,
+ embedUri.toASCIIString(), e);
}
return null;
}
- EmbedFontInfo fi = getFontInfoFromCustomFont(fontURL, customFont, fontCache);
+ EmbedFontInfo fi = getFontInfoFromCustomFont(fontURI, customFont, fontCache, resourceResolver);
if (fi != null) {
return new EmbedFontInfo[] {fi};
} else {
diff --git a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
index 5da25e4b4..790e885bc 100644
--- a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
+++ b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
@@ -19,7 +19,6 @@
package org.apache.fop.fonts.truetype;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -31,38 +30,9 @@ import org.apache.commons.io.IOUtils;
*/
public class FontFileReader {
- private int fsize; // file size
+ private final int fsize; // file size
private int current; // current position in file
- private byte[] file;
-
- /**
- * Initializes class and reads stream. Init does not close stream.
- *
- * @param in InputStream to read from new array with size + inc
- * @throws IOException In case of an I/O problem
- */
- private void init(InputStream in) throws java.io.IOException {
- this.file = IOUtils.toByteArray(in);
- this.fsize = this.file.length;
- this.current = 0;
- }
-
- /**
- * Constructor
- *
- * @param fileName filename to read
- * @throws IOException In case of an I/O problem
- */
- public FontFileReader(String fileName) throws IOException {
- final File f = new File(fileName);
- InputStream in = new java.io.FileInputStream(f);
- try {
- init(in);
- } finally {
- in.close();
- }
- }
-
+ private final byte[] file;
/**
* Constructor
@@ -71,7 +41,9 @@ public class FontFileReader {
* @throws IOException In case of an I/O problem
*/
public FontFileReader(InputStream in) throws IOException {
- init(in);
+ this.file = IOUtils.toByteArray(in);
+ this.fsize = this.file.length;
+ this.current = 0;
}
@@ -152,9 +124,9 @@ public class FontFileReader {
final byte buf = read();
if (buf < 0) {
- return (int)(256 + buf);
+ return (256 + buf);
} else {
- return (int)buf;
+ return buf;
}
}
@@ -178,7 +150,7 @@ public class FontFileReader {
*/
public final int readTTFUShort() throws IOException {
final int ret = (readTTFUByte() << 8) + readTTFUByte();
- return (int)ret;
+ return ret;
}
/**
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
index bc979f277..878af1124 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
@@ -19,7 +19,9 @@
package org.apache.fop.fonts.truetype;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Comparator;
@@ -33,6 +35,7 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -1672,7 +1675,7 @@ public class TTFFile {
for (Integer unicodeKey2 : ckpx.keySet()) {
Integer cidKey2 = unicodeToGlyph(unicodeKey2.intValue());
- Integer kern = (Integer)ckpx.get(unicodeKey2);
+ Integer kern = ckpx.get(unicodeKey2);
Iterator uniMap = mtxTab[cidKey2.intValue()].getUnicodeIndex().listIterator();
while (uniMap.hasNext()) {
@@ -1838,6 +1841,8 @@ public class TTFFile {
* @throws IOException In case of an I/O problem
*/
public final List<String> getTTCnames(FontFileReader in) throws IOException {
+ this.fontFile = in;
+
List<String> fontNames = new ArrayList<String>();
String tag = in.readTTFString(4);
@@ -2011,12 +2016,14 @@ public class TTFFile {
* @param args The command line arguments
*/
public static void main(String[] args) {
+ InputStream stream = null;
try {
boolean useKerning = true;
boolean useAdvanced = true;
TTFFile ttfFile = new TTFFile(useKerning, useAdvanced);
- FontFileReader reader = new FontFileReader(args[0]);
+ stream = new FileInputStream(args[0]);
+ FontFileReader reader = new FontFileReader(stream);
String name = null;
if (args.length >= 2) {
@@ -2029,6 +2036,8 @@ public class TTFFile {
} catch (IOException ioe) {
System.err.println("Problem reading font: " + ioe.toString());
ioe.printStackTrace(System.err);
+ } finally {
+ IOUtils.closeQuietly(stream);
}
}
}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
index 1410239ee..c97b17211 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
@@ -21,17 +21,18 @@ package org.apache.fop.fonts.truetype;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.CIDFontType;
import org.apache.fop.fonts.CMapSegment;
import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.NamedCharacter;
@@ -53,10 +54,10 @@ public class TTFFontLoader extends FontLoader {
/**
* Default constructor
* @param fontFileURI the URI representing the font file
- * @param resolver the FontResolver for font URI resolution
+ * @param resourceResolver the resource resolver for font URI resolution
*/
- public TTFFontLoader(String fontFileURI, FontResolver resolver) {
- this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resolver);
+ public TTFFontLoader(URI fontFileURI, InternalResourceResolver resourceResolver) {
+ this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resourceResolver);
}
/**
@@ -71,9 +72,9 @@ public class TTFFontLoader extends FontLoader {
* @param useAdvanced true to enable loading advanced info if available, false to disable
* @param resolver the FontResolver for font URI resolution
*/
- public TTFFontLoader(String fontFileURI, String subFontName,
- boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
- boolean useKerning, boolean useAdvanced, FontResolver resolver) {
+ public TTFFontLoader(URI fontFileURI, String subFontName, boolean embedded,
+ EmbeddingMode embeddingMode, EncodingMode encodingMode, boolean useKerning,
+ boolean useAdvanced, InternalResourceResolver resolver) {
super(fontFileURI, embedded, useKerning, useAdvanced, resolver);
this.subFontName = subFontName;
this.encodingMode = encodingMode;
@@ -98,7 +99,7 @@ public class TTFFontLoader extends FontLoader {
* @throws IOException if an I/O error occurs
*/
private void read(String ttcFontName) throws IOException {
- InputStream in = openFontUri(resolver, this.fontFileURI);
+ InputStream in = resourceResolver.getResource(this.fontFileURI);
try {
TTFFile ttf = new TTFFile(useKerning, useAdvanced);
FontFileReader reader = new FontFileReader(in);
@@ -126,14 +127,13 @@ public class TTFFontLoader extends FontLoader {
}
if (isCid) {
- multiFont = new MultiByteFont();
+ multiFont = new MultiByteFont(resourceResolver);
returnFont = multiFont;
multiFont.setTTCName(ttcFontName);
} else {
- singleFont = new SingleByteFont();
+ singleFont = new SingleByteFont(resourceResolver);
returnFont = singleFont;
}
- returnFont.setResolver(resolver);
returnFont.setFontName(ttf.getPostScriptName());
returnFont.setFullName(ttf.getFullName());
@@ -172,7 +172,7 @@ public class TTFFontLoader extends FontLoader {
}
if (this.embedded) {
if (ttf.isEmbeddable()) {
- returnFont.setEmbedFileName(this.fontFileURI);
+ returnFont.setEmbedURI(this.fontFileURI);
} else {
String msg = "The font " + this.fontFileURI + " is not embeddable due to a"
+ " licensing restriction.";
diff --git a/src/java/org/apache/fop/fonts/type1/PFBParser.java b/src/java/org/apache/fop/fonts/type1/PFBParser.java
index b92332b6d..339a9e141 100644
--- a/src/java/org/apache/fop/fonts/type1/PFBParser.java
+++ b/src/java/org/apache/fop/fonts/type1/PFBParser.java
@@ -48,38 +48,6 @@ public class PFBParser {
/**
* Parses a PFB file into a PFBData object.
- * @param url URL to load the PFB file from
- * @return PFBData memory representation of the font
- * @throws IOException In case of an I/O problem
- */
- public PFBData parsePFB(java.net.URL url) throws IOException {
- InputStream in = url.openStream();
- try {
- return parsePFB(in);
- } finally {
- in.close();
- }
- }
-
-
- /**
- * Parses a PFB file into a PFBData object.
- * @param pfbFile File to load the PFB file from
- * @return PFBData memory representation of the font
- * @throws IOException In case of an I/O problem
- */
- public PFBData parsePFB(java.io.File pfbFile) throws IOException {
- InputStream in = new java.io.FileInputStream(pfbFile);
- try {
- return parsePFB(in);
- } finally {
- in.close();
- }
- }
-
-
- /**
- * Parses a PFB file into a PFBData object.
* @param in InputStream to load the PFB file from
* @return PFBData memory representation of the font
* @throws IOException In case of an I/O problem
@@ -113,7 +81,6 @@ public class PFBParser {
private void parsePCFormat(PFBData pfb, DataInputStream din) throws IOException {
int segmentHead;
int segmentType;
- int bytesRead;
//Read first segment
segmentHead = din.readUnsignedByte();
diff --git a/src/java/org/apache/fop/fonts/type1/PFMFile.java b/src/java/org/apache/fop/fonts/type1/PFMFile.java
index d1a3d79ff..3b171e85a 100644
--- a/src/java/org/apache/fop/fonts/type1/PFMFile.java
+++ b/src/java/org/apache/fop/fonts/type1/PFMFile.java
@@ -23,6 +23,7 @@ package org.apache.fop.fonts.type1;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
@@ -40,7 +41,7 @@ public class PFMFile {
private String windowsName;
private String postscriptName;
private short dfItalic;
- private int dfWeight;
+ //private int dfWeight;
private short dfCharSet;
private short dfPitchAndFamily;
private int dfAvgWidth;
@@ -61,7 +62,7 @@ public class PFMFile {
// Extent table
private int[] extentTable;
- private Map kerningTab = new java.util.HashMap();
+ private Map<Integer, Map<Integer, Integer>> kerningTab = new HashMap<Integer, Map<Integer, Integer>>();
/**
* logging instance
@@ -119,7 +120,7 @@ public class PFMFile {
inStream.skip(80);
dfItalic = inStream.readByte();
inStream.skip(2);
- dfWeight = inStream.readShort();
+ inStream.readShort(); // dfWeight =
dfCharSet = inStream.readByte();
inStream.skip(4);
dfPitchAndFamily = inStream.readByte();
@@ -192,10 +193,10 @@ public class PFMFile {
log.trace(i + " kerning pairs");
}
while (i > 0) {
- int g1 = (int)inStream.readByte();
+ int g1 = (int) inStream.readByte();
i--;
- int g2 = (int)inStream.readByte();
+ int g2 = (int) inStream.readByte();
int adj = inStream.readShort();
if (adj > 0x8000) {
@@ -209,12 +210,12 @@ public class PFMFile {
log.trace("glyphs: " + glyph1 + ", " + glyph2);
}
- Map adjTab = (Map)kerningTab.get(new Integer(g1));
+ Map<Integer, Integer> adjTab = kerningTab.get(Integer.valueOf(g1));
if (adjTab == null) {
- adjTab = new java.util.HashMap();
+ adjTab = new HashMap<Integer, Integer>();
}
- adjTab.put(new Integer(g2), new Integer(adj));
- kerningTab.put(new Integer(g1), adjTab);
+ adjTab.put(Integer.valueOf(g2), Integer.valueOf(adj));
+ kerningTab.put(Integer.valueOf(g1), adjTab);
}
}
@@ -270,7 +271,7 @@ public class PFMFile {
*
* @return A Map containing the kerning table
*/
- public Map getKerning() {
+ public Map<Integer, Map<Integer, Integer>> getKerning() {
return kerningTab;
}
@@ -453,9 +454,9 @@ public class PFMFile {
public int getStemV() {
// Just guessing....
if (dfItalic != 0) {
- return (int)Math.round(dfMinWidth * 0.25);
+ return (int) Math.round(dfMinWidth * 0.25);
} else {
- return (int)Math.round(dfMinWidth * 0.6);
+ return (int) Math.round(dfMinWidth * 0.6);
}
}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
index 924f7b0b8..853e23eb5 100644
--- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
+++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
@@ -22,15 +22,19 @@ package org.apache.fop.fonts.type1;
import java.awt.geom.RectangularShape;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.CodePointMapping;
import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
@@ -40,6 +44,8 @@ import org.apache.fop.fonts.SingleByteFont;
*/
public class Type1FontLoader extends FontLoader {
+ private static final Log log = LogFactory.getLog(Type1FontLoader.class);
+
private SingleByteFont singleFont;
/**
@@ -47,12 +53,12 @@ public class Type1FontLoader extends FontLoader {
* @param fontFileURI the URI to the PFB file of a Type 1 font
* @param embedded indicates whether the font is embedded or referenced
* @param useKerning indicates whether to load kerning information if available
- * @param resolver the font resolver used to resolve URIs
+ * @param resourceResolver the font resolver used to resolve URIs
* @throws IOException In case of an I/O error
*/
- public Type1FontLoader(String fontFileURI, boolean embedded, boolean useKerning,
- FontResolver resolver) throws IOException {
- super(fontFileURI, embedded, useKerning, true, resolver);
+ public Type1FontLoader(URI fontFileURI, boolean embedded, boolean useKerning,
+ InternalResourceResolver resourceResolver) throws IOException {
+ super(fontFileURI, embedded, useKerning, true, resourceResolver);
}
private String getPFMURI(String pfbURI) {
@@ -71,17 +77,20 @@ public class Type1FontLoader extends FontLoader {
PFMFile pfm = null;
InputStream afmIn = null;
+ String fontFileStr = fontFileURI.toASCIIString();
+ String partialAfmUri = fontFileStr.substring(0, fontFileStr.length() - 4);
String afmUri = null;
- for (int i = 0; i < AFM_EXTENSIONS.length; i++) {
+ for (String afmExtension : AFM_EXTENSIONS) {
try {
- afmUri = this.fontFileURI.substring(0, this.fontFileURI.length() - 4)
- + AFM_EXTENSIONS[i];
- afmIn = openFontUri(resolver, afmUri);
+ afmUri = partialAfmUri + afmExtension;
+ afmIn = resourceResolver.getResource(afmUri);
if (afmIn != null) {
break;
}
} catch (IOException ioe) {
// Ignore, AFM probably not available under the URI
+ } catch (URISyntaxException e) {
+ // Ignore, AFM probably not available under the URI
}
}
if (afmIn != null) {
@@ -93,12 +102,14 @@ public class Type1FontLoader extends FontLoader {
}
}
- String pfmUri = getPFMURI(this.fontFileURI);
+ String pfmUri = getPFMURI(fontFileStr);
InputStream pfmIn = null;
try {
- pfmIn = openFontUri(resolver, pfmUri);
+ pfmIn = resourceResolver.getResource(pfmUri);
} catch (IOException ioe) {
// Ignore, PFM probably not available under the URI
+ } catch (URISyntaxException e) {
+ // Ignore, PFM probably not available under the URI
}
if (pfmIn != null) {
try {
@@ -126,11 +137,10 @@ public class Type1FontLoader extends FontLoader {
if (afm == null && pfm == null) {
throw new IllegalArgumentException("Need at least an AFM or a PFM!");
}
- singleFont = new SingleByteFont();
+ singleFont = new SingleByteFont(resourceResolver);
singleFont.setFontType(FontType.TYPE1);
- singleFont.setResolver(this.resolver);
if (this.embedded) {
- singleFont.setEmbedFileName(this.fontFileURI);
+ singleFont.setEmbedURI(this.fontFileURI);
}
returnFont = singleFont;
diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java
index 062b0e922..31cf8e1c8 100644
--- a/src/java/org/apache/fop/hyphenation/Hyphenator.java
+++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java
@@ -20,21 +20,20 @@
package org.apache.fop.hyphenation;
import java.io.BufferedInputStream;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
+import java.net.URISyntaxException;
import java.util.Map;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.xml.sax.InputSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
+
/**
* <p>This class is the main entry point to the hyphenation package.
* You can use only the static methods or create an instance.</p>
@@ -75,7 +74,7 @@ public final class Hyphenator {
* @return the hyphenation tree
*/
public static HyphenationTree getHyphenationTree(String lang,
- String country, HyphenationTreeResolver resolver, Map hyphPatNames) {
+ String country, InternalResourceResolver resolver, Map hyphPatNames) {
String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
HyphenationTreeCache cache = getHyphenationTreeCache();
@@ -126,12 +125,12 @@ public final class Hyphenator {
* The hyphenation trees are cached.
* @param lang the language
* @param country the country (may be null or "none")
- * @param resolver resolver to find the hyphenation files
+ * @param resourceResolver resolver to find the hyphenation files
* @param hyphPatNames the map with user-configured hyphenation pattern file names
* @return the hyphenation tree
*/
- private static HyphenationTree getHyphenationTree2(String lang,
- String country, HyphenationTreeResolver resolver, Map hyphPatNames) {
+ public static HyphenationTree getHyphenationTree2(String lang,
+ String country, InternalResourceResolver resourceResolver, Map hyphPatNames) {
String llccKey = HyphenationTreeCache.constructLlccKey(lang, country);
HyphenationTreeCache cache = getHyphenationTreeCache();
@@ -147,8 +146,8 @@ public final class Hyphenator {
key = llccKey;
}
- if (resolver != null) {
- hTree = getUserHyphenationTree(key, resolver);
+ if (resourceResolver != null) {
+ hTree = getUserHyphenationTree(key, resourceResolver);
}
if (hTree == null) {
hTree = getFopHyphenationTree(key);
@@ -230,30 +229,11 @@ public final class Hyphenator {
* Load tree from serialized file or xml file
* using configuration settings
* @param key language key for the requested hyphenation file
- * @param hyphenDir base directory to find hyphenation files in
- * @return the requested HypenationTree or null if it is not available
- */
- public static HyphenationTree getUserHyphenationTree(String key,
- String hyphenDir) {
- final File baseDir = new File(hyphenDir);
- HyphenationTreeResolver resolver = new HyphenationTreeResolver() {
- public Source resolve(String href) {
- File f = new File(baseDir, href);
- return new StreamSource(f);
- }
- };
- return getUserHyphenationTree(key, resolver);
- }
-
- /**
- * Load tree from serialized file or xml file
- * using configuration settings
- * @param key language key for the requested hyphenation file
- * @param resolver resolver to find the hyphenation files
+ * @param resourceResolver resource resolver to find the hyphenation files
* @return the requested HypenationTree or null if it is not available
*/
public static HyphenationTree getUserHyphenationTree(String key,
- HyphenationTreeResolver resolver) {
+ InternalResourceResolver resourceResolver) {
HyphenationTree hTree = null;
// I use here the following convention. The file name specified in
// the configuration is taken as the base name. First we try
@@ -262,93 +242,63 @@ public final class Hyphenator {
// first try serialized object
String name = key + ".hyp";
- Source source = resolver.resolve(name);
- if (source != null) {
+ try {
+ InputStream in = getHyphenationTreeStream(name, resourceResolver);
try {
- InputStream in = null;
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null) {
- if (source.getSystemId() != null) {
- in = new java.net.URL(source.getSystemId()).openStream();
- } else {
- throw new UnsupportedOperationException
- ("Cannot load hyphenation pattern file"
- + " with the supplied Source object: " + source);
- }
- }
- in = new BufferedInputStream(in);
- try {
- hTree = readHyphenationTree(in);
- } finally {
- IOUtils.closeQuietly(in);
- }
- return hTree;
- } catch (IOException ioe) {
- if (log.isDebugEnabled()) {
- log.debug("I/O problem while trying to load " + name, ioe);
- }
+ hTree = readHyphenationTree(in);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ return hTree;
+ } catch (IOException ioe) {
+ if (log.isDebugEnabled()) {
+ log.debug("I/O problem while trying to load " + name, ioe);
}
}
// try the raw XML file
name = key + ".xml";
- source = resolver.resolve(name);
- if (source != null) {
- hTree = new HyphenationTree();
+ hTree = new HyphenationTree();
+ try {
+ InputStream in = getHyphenationTreeStream(name, resourceResolver);
try {
- InputStream in = null;
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null) {
- if (source.getSystemId() != null) {
- in = new java.net.URL(source.getSystemId()).openStream();
- } else {
- throw new UnsupportedOperationException(
- "Cannot load hyphenation pattern file"
- + " with the supplied Source object: " + source);
- }
- }
- if (!(in instanceof BufferedInputStream)) {
- in = new BufferedInputStream(in);
- }
- try {
- InputSource src = new InputSource(in);
- src.setSystemId(source.getSystemId());
- hTree.loadPatterns(src);
- } finally {
- IOUtils.closeQuietly(in);
- }
- if (statisticsDump) {
- System.out.println("Stats: ");
- hTree.printStats();
- }
- return hTree;
- } catch (HyphenationException ex) {
- log.error("Can't load user patterns from XML file " + source.getSystemId()
- + ": " + ex.getMessage());
- return null;
- } catch (IOException ioe) {
- if (log.isDebugEnabled()) {
- log.debug("I/O problem while trying to load " + name, ioe);
- }
- return null;
+ InputSource src = new InputSource(in);
+ src.setSystemId(name);
+ hTree.loadPatterns(src);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ if (statisticsDump) {
+ System.out.println("Stats: ");
+ hTree.printStats();
}
- } else {
+ return hTree;
+ } catch (HyphenationException ex) {
+ log.error("Can't load user patterns from XML file " + name + ": " + ex.getMessage());
+ return null;
+ } catch (IOException ioe) {
if (log.isDebugEnabled()) {
- log.debug("Could not load user hyphenation file for '" + key + "'.");
+ log.debug("I/O problem while trying to load " + name, ioe);
}
return null;
}
}
+ private static InputStream getHyphenationTreeStream(String name,
+ InternalResourceResolver resourceResolver) throws IOException {
+ try {
+ return new BufferedInputStream(resourceResolver.getResource(name));
+ } catch (URISyntaxException use) {
+ log.debug("An exception was thrown while attempting to load " + name, use);
+ }
+ return null;
+ }
+
/**
* Hyphenates a word.
* @param lang the language
* @param country the optional country code (may be null or "none")
- * @param resolver resolver to find the hyphenation files
+ * @param resourceResolver resolver to find the hyphenation files
* @param hyphPatNames the map with user-configured hyphenation pattern file names
* @param word the word to hyphenate
* @param leftMin the minimum number of characters before the hyphenation point
@@ -356,15 +306,12 @@ public final class Hyphenator {
* @return the hyphenation result
*/
public static Hyphenation hyphenate(String lang, String country,
- HyphenationTreeResolver resolver,
- Map hyphPatNames,
- String word,
- int leftMin, int rightMin) {
- HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames);
+ InternalResourceResolver resourceResolver, Map hyphPatNames, String word, int leftMin,
+ int rightMin) {
+ HyphenationTree hTree = getHyphenationTree(lang, country, resourceResolver, hyphPatNames);
if (hTree == null) {
return null;
}
return hTree.hyphenate(word, leftMin, rightMin);
}
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
index a46b74e1a..7cbe33f26 100644
--- a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
@@ -91,7 +91,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan
initialize();
FOUserAgent userAgent = pageSeq.getUserAgent();
- ImageManager imageManager = userAgent.getFactory().getImageManager();
+ ImageManager imageManager = userAgent.getImageManager();
String uri = URISpecification.getURL(getExternalDocument().getSrc());
Integer firstPageIndex = ImageUtil.getPageIndexFromURI(uri);
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 27958f7e0..56c534f90 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -1396,11 +1396,10 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// TextLM which generate the hyphenation buffer,
// since these properties inherit and could be specified
// on an inline or wrapper below the block level.
- Hyphenation hyph
- = Hyphenator.hyphenate(hyphenationProperties.language.getString(),
+ Hyphenation hyph = Hyphenator.hyphenate(hyphenationProperties.language.getString(),
hyphenationProperties.country.getString(),
- getFObj().getUserAgent().getFactory().getHyphenationTreeResolver(),
- getFObj().getUserAgent().getFactory().getHyphPatNames(),
+ getFObj().getUserAgent().getResourceResolver(),
+ getFObj().getUserAgent().getHyphPatNames(),
sbChars.toString(),
hyphenationProperties.hyphenationRemainCharacterCount.getValue(),
hyphenationProperties.hyphenationPushCharacterCount.getValue());
diff --git a/src/java/org/apache/fop/pdf/PDFAMode.java b/src/java/org/apache/fop/pdf/PDFAMode.java
index b5b764dd4..899f9aa7d 100644
--- a/src/java/org/apache/fop/pdf/PDFAMode.java
+++ b/src/java/org/apache/fop/pdf/PDFAMode.java
@@ -20,14 +20,14 @@
package org.apache.fop.pdf;
/** Enum class for PDF/A modes. */
-public final class PDFAMode {
+public enum PDFAMode {
/** PDF/A disabled */
- public static final PDFAMode DISABLED = new PDFAMode("PDF/A disabled");
+ DISABLED("PDF/A disabled"),
/** PDF/A-1a enabled */
- public static final PDFAMode PDFA_1A = new PDFAMode("PDF/A-1a");
+ PDFA_1A("PDF/A-1a"),
/** PDF/A-1b enabled */
- public static final PDFAMode PDFA_1B = new PDFAMode("PDF/A-1b");
+ PDFA_1B("PDF/A-1b");
private String name;
@@ -66,7 +66,7 @@ public final class PDFAMode {
* @param s the string
* @return the PDFAMode enum object (DISABLED will be returned if no match is found)
*/
- public static PDFAMode valueOf(String s) {
+ public static PDFAMode getValueOf(String s) {
if (PDFA_1A.getName().equalsIgnoreCase(s)) {
return PDFA_1A;
} else if (PDFA_1B.getName().equalsIgnoreCase(s)) {
diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java
index 9850c605e..dad404d11 100644
--- a/src/java/org/apache/fop/pdf/PDFDocument.java
+++ b/src/java/org/apache/fop/pdf/PDFDocument.java
@@ -21,7 +21,6 @@ package org.apache.fop.pdf;
// Java
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
@@ -719,24 +718,6 @@ public class PDFDocument {
}
/**
- * Resolve a URI.
- *
- * @param uri the uri to resolve
- * @throws java.io.FileNotFoundException if the URI could not be resolved
- * @return the InputStream from the URI.
- */
- protected InputStream resolveURI(String uri)
- throws java.io.FileNotFoundException {
- try {
- /* TODO: Temporary hack to compile, improve later */
- return new java.net.URL(uri).openStream();
- } catch (Exception e) {
- throw new java.io.FileNotFoundException(
- "URI could not be resolved (" + e.getMessage() + "): " + uri);
- }
- }
-
- /**
* Get an image from the image map.
*
* @param key the image key to look for
diff --git a/src/java/org/apache/fop/pdf/PDFEncryptionParams.java b/src/java/org/apache/fop/pdf/PDFEncryptionParams.java
index 71dccd867..563c05233 100644
--- a/src/java/org/apache/fop/pdf/PDFEncryptionParams.java
+++ b/src/java/org/apache/fop/pdf/PDFEncryptionParams.java
@@ -273,4 +273,17 @@ public class PDFEncryptionParams {
this.encryptionLengthInBits = encryptionLength;
}
+ public String toString() {
+ return "userPassword = " + userPassword + "\n"
+ + "ownerPassword = " + ownerPassword + "\n"
+ + "allowPrint = " + allowPrint + "\n"
+ + "allowCopyContent = " + allowCopyContent + "\n"
+ + "allowEditContent = " + allowEditContent + "\n"
+ + "allowEditAnnotations = " + allowEditAnnotations + "\n"
+ + "allowFillInForms = " + allowFillInForms + "\n"
+ + "allowAccessContent = " + allowAccessContent + "\n"
+ + "allowAssembleDocument = " + allowAssembleDocument + "\n"
+ + "allowPrintHq = " + allowPrintHq;
+ }
+
}
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index beb384dcf..633ce9dd1 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -23,10 +23,8 @@ package org.apache.fop.pdf;
import java.awt.Color;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.net.MalformedURLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -35,9 +33,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
@@ -1637,79 +1632,48 @@ public class PDFFactory {
InputStream in = null;
try {
- Source source = font.getEmbedFileSource();
- if (source == null && font.getEmbedResourceName() != null) {
- source = new StreamSource(this.getClass()
- .getResourceAsStream(font.getEmbedResourceName()));
- }
- if (source == null) {
- return null;
- }
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null && source.getSystemId() != null) {
- try {
- in = new java.net.URL(source.getSystemId()).openStream();
- } catch (MalformedURLException e) {
- //TODO: Why construct a new exception here, when it is not thrown?
- new FileNotFoundException(
- "File not found. URL could not be resolved: "
- + e.getMessage());
- }
- }
- if (in == null) {
- return null;
- }
- //Make sure the InputStream is decorated with a BufferedInputStream
- if (!(in instanceof java.io.BufferedInputStream)) {
- in = new java.io.BufferedInputStream(in);
- }
+ in = font.getInputStream();
if (in == null) {
return null;
} else {
- try {
- AbstractPDFStream embeddedFont;
- if (desc.getFontType() == FontType.TYPE0) {
- MultiByteFont mbfont = (MultiByteFont)font;
- FontFileReader reader = new FontFileReader(in);
-
- TTFSubSetFile subset = new TTFSubSetFile();
- subset.readFont(reader, mbfont.getTTCName(), mbfont.getUsedGlyphs());
- byte[] subsetFont = subset.getFontSubset();
- // Only TrueType CID fonts are supported now
-
- embeddedFont = new PDFTTFStream(subsetFont.length);
- ((PDFTTFStream)embeddedFont).setData(subsetFont, subsetFont.length);
- } else if (desc.getFontType() == FontType.TYPE1) {
- PFBParser parser = new PFBParser();
- PFBData pfb = parser.parsePFB(in);
- embeddedFont = new PDFT1Stream();
- ((PDFT1Stream)embeddedFont).setData(pfb);
- } else {
- byte[] file = IOUtils.toByteArray(in);
- embeddedFont = new PDFTTFStream(file.length);
- ((PDFTTFStream)embeddedFont).setData(file, file.length);
- }
+ AbstractPDFStream embeddedFont;
+ if (desc.getFontType() == FontType.TYPE0) {
+ MultiByteFont mbfont = (MultiByteFont) font;
+ FontFileReader reader = new FontFileReader(in);
+
+ TTFSubSetFile subset = new TTFSubSetFile();
+ subset.readFont(reader, mbfont.getTTCName(), mbfont.getUsedGlyphs());
+ byte[] subsetFont = subset.getFontSubset();
+ // Only TrueType CID fonts are supported now
+
+ embeddedFont = new PDFTTFStream(subsetFont.length);
+ ((PDFTTFStream) embeddedFont).setData(subsetFont, subsetFont.length);
+ } else if (desc.getFontType() == FontType.TYPE1) {
+ PFBParser parser = new PFBParser();
+ PFBData pfb = parser.parsePFB(in);
+ embeddedFont = new PDFT1Stream();
+ ((PDFT1Stream) embeddedFont).setData(pfb);
+ } else {
+ byte[] file = IOUtils.toByteArray(in);
+ embeddedFont = new PDFTTFStream(file.length);
+ ((PDFTTFStream) embeddedFont).setData(file, file.length);
+ }
- /*
- embeddedFont.getFilterList().addFilter("flate");
- if (getDocument().isEncryptionActive()) {
- getDocument().applyEncryption(embeddedFont);
- } else {
- embeddedFont.getFilterList().addFilter("ascii-85");
- }*/
+ /*
+ embeddedFont.getFilterList().addFilter("flate");
+ if (getDocument().isEncryptionActive()) {
+ getDocument().applyEncryption(embeddedFont);
+ } else {
+ embeddedFont.getFilterList().addFilter("ascii-85");
+ }*/
- return embeddedFont;
- } finally {
- in.close();
- }
+ return embeddedFont;
}
} catch (IOException ioe) {
- log.error(
- "Failed to embed font [" + desc + "] "
- + desc.getEmbedFontName(), ioe);
+ log.error("Failed to embed font [" + desc + "] " + desc.getEmbedFontName(), ioe);
return null;
+ } finally {
+ IOUtils.closeQuietly(in);
}
}
diff --git a/src/java/org/apache/fop/pdf/PDFXMode.java b/src/java/org/apache/fop/pdf/PDFXMode.java
index 03813273b..be0312891 100644
--- a/src/java/org/apache/fop/pdf/PDFXMode.java
+++ b/src/java/org/apache/fop/pdf/PDFXMode.java
@@ -20,12 +20,12 @@
package org.apache.fop.pdf;
/** Enum class for PDF/X modes. */
-public final class PDFXMode {
+public enum PDFXMode {
/** PDF/X disabled */
- public static final PDFXMode DISABLED = new PDFXMode("PDF/X disabled");
+ DISABLED("PDF/X disabled"),
/** PDF/X-3:2003 enabled */
- public static final PDFXMode PDFX_3_2003 = new PDFXMode("PDF/X-3:2003");
+ PDFX_3_2003("PDF/X-3:2003");
private String name;
@@ -47,7 +47,7 @@ public final class PDFXMode {
* @param s the string
* @return the PDFAMode enum object (DISABLED will be returned if no match is found)
*/
- public static PDFXMode valueOf(String s) {
+ public static PDFXMode getValueOf(String s) {
if (PDFX_3_2003.getName().equalsIgnoreCase(s)) {
return PDFX_3_2003;
} else {
diff --git a/src/java/org/apache/fop/pdf/StreamCacheFactory.java b/src/java/org/apache/fop/pdf/StreamCacheFactory.java
index 4e2d12eb2..aa4d665da 100644
--- a/src/java/org/apache/fop/pdf/StreamCacheFactory.java
+++ b/src/java/org/apache/fop/pdf/StreamCacheFactory.java
@@ -24,56 +24,24 @@ import java.io.IOException;
/**
* This class is serves as a factory from
*/
-public class StreamCacheFactory {
+public final class StreamCacheFactory {
- private static boolean defaultCacheToFile = false;
- private static StreamCacheFactory fileInstance = null;
- private static StreamCacheFactory memoryInstance = null;
-
- private boolean cacheToFile = false;
+ private static StreamCacheFactory memoryInstance = new StreamCacheFactory();
/**
* Returns an instance of a StreamCacheFactory with the requested features.
* @param cacheToFile True if file shall be cached using a temporary file
* @return StreamCacheFactory the requested factory
*/
- public static StreamCacheFactory getInstance(boolean cacheToFile) {
- if (cacheToFile) {
- if (fileInstance == null) {
- fileInstance = new StreamCacheFactory(true);
- }
- return fileInstance;
- } else {
- if (memoryInstance == null) {
- memoryInstance = new StreamCacheFactory(false);
- }
- return memoryInstance;
- }
- }
-
- /**
- * Returns an instance of a StreamCacheFactory depending on the default
- * setting for cacheToFile.
- * @return StreamCacheFactory the requested factory
- */
public static StreamCacheFactory getInstance() {
- return getInstance(defaultCacheToFile);
- }
-
- /**
- * Sets the global default for cacheToFile
- * @param cacheToFile True if stream caches should be held in files.
- */
- public static void setDefaultCacheToFile(boolean cacheToFile) {
- defaultCacheToFile = cacheToFile;
+ return memoryInstance;
}
/**
* Creates a new StreamCacheFactory.
* @param cacheToFile True if file shall be cached using a temporary file
*/
- public StreamCacheFactory(boolean cacheToFile) {
- this.cacheToFile = cacheToFile;
+ private StreamCacheFactory() {
}
/**
@@ -83,11 +51,7 @@ public class StreamCacheFactory {
* @return a new StreamCache for caching streams
*/
public StreamCache createStreamCache() throws IOException {
- if (this.cacheToFile) {
- return new TempFileStreamCache();
- } else {
- return new InMemoryStreamCache();
- }
+ return new InMemoryStreamCache();
}
/**
@@ -98,20 +62,6 @@ public class StreamCacheFactory {
* @return a new StreamCache for caching streams
*/
public StreamCache createStreamCache(int hintSize) throws IOException {
- if (this.cacheToFile) {
- return new TempFileStreamCache();
- } else {
- return new InMemoryStreamCache(hintSize);
- }
- }
-
- /**
- * Get the value of the global cacheToFile flag.
- * @return the current cache to file flag
- */
- public boolean getCacheToFile() {
- return this.cacheToFile;
+ return new InMemoryStreamCache(hintSize);
}
-
-
}
diff --git a/src/java/org/apache/fop/render/AbstractConfigurator.java b/src/java/org/apache/fop/render/AbstractConfigurator.java
index c3c6733b0..c890d0830 100644
--- a/src/java/org/apache/fop/render/AbstractConfigurator.java
+++ b/src/java/org/apache/fop/render/AbstractConfigurator.java
@@ -19,9 +19,6 @@
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;
@@ -49,41 +46,6 @@ public abstract class AbstractConfigurator {
}
/**
- * Returns the configuration subtree for a specific renderer.
- * @param mimeType the MIME type of the renderer
- * @return the requested configuration subtree, null if there's no configuration
- */
- protected Configuration getConfig(String mimeType) {
- Configuration cfg = userAgent.getFactory().getUserConfig();
- if (cfg == null) {
- if (log.isDebugEnabled()) {
- log.debug("userconfig is null");
- }
- return null;
- }
-
- Configuration userConfig = null;
-
- String type = getType();
- Configuration[] cfgs
- = cfg.getChild(type + "s").getChildren(type);
- for (int i = 0; i < cfgs.length; ++i) {
- Configuration child = cfgs[i];
- try {
- if (child.getAttribute(MIME).equals(mimeType)) {
- userConfig = child;
- break;
- }
- } catch (ConfigurationException e) {
- // silently pass over configurations without mime type
- }
- }
- log.debug((userConfig == null ? "No u" : "U")
- + "ser configuration found for MIME type " + mimeType);
- return userConfig;
- }
-
- /**
* Returns the configurator type
* @return the configurator type
*/
diff --git a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
index e1bc10440..799469353 100644
--- a/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/AbstractRendererConfigurator.java
@@ -19,49 +19,30 @@
package org.apache.fop.render;
-import org.apache.avalon.framework.configuration.Configuration;
-
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 extends AbstractConfigurator {
+public abstract class AbstractRendererConfigurator {
- private static final String TYPE = "renderer";
+ /** fop factory configuration */
+ protected final FOUserAgent userAgent;
/**
* Default constructor
* @param userAgent user agent
*/
public AbstractRendererConfigurator(FOUserAgent userAgent) {
- super(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) {
- return super.getConfig(renderer.getMimeType());
+ this.userAgent = userAgent;
}
/**
- * Returns the configuration subtree for a specific renderer.
- * @param mimeType the MIME type of the renderer
- * @return the requested configuration subtree, null if there's no configuration
+ * Returns the configurator type
+ * @return the configurator type
*/
- protected Configuration getRendererConfig(String mimeType) {
- return super.getConfig(mimeType);
+ public static String getType() {
+ return "renderer";
}
-
- /**
- * {@inheritDoc}
- */
- public String getType() {
- return TYPE;
- }
-
}
diff --git a/src/java/org/apache/fop/render/AbstractRendererMaker.java b/src/java/org/apache/fop/render/AbstractRendererMaker.java
index fadfda94d..b4a281efa 100644
--- a/src/java/org/apache/fop/render/AbstractRendererMaker.java
+++ b/src/java/org/apache/fop/render/AbstractRendererMaker.java
@@ -19,6 +19,7 @@
package org.apache.fop.render;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
/**
@@ -50,9 +51,8 @@ public abstract class AbstractRendererMaker {
* @param userAgent user agent
* @return a config object that can be used to configure the renderer
*/
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return null;
- }
+ public abstract void configureRenderer(FOUserAgent userAgent, Renderer renderer)
+ throws FOPException;
/**
* Indicates whether a specific MIME type is supported by this renderer.
diff --git a/src/java/org/apache/fop/render/DefaultRendererConfigurator.java b/src/java/org/apache/fop/render/DefaultRendererConfigurator.java
new file mode 100644
index 000000000..061c25709
--- /dev/null
+++ b/src/java/org/apache/fop/render/DefaultRendererConfigurator.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util.ArrayList;
+import java.util.List;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
+
+/**
+ * This object represents the default renderer configurator and contains the methods for most the
+ * RendererConfigurators.
+ */
+public class DefaultRendererConfigurator extends PrintRendererConfigurator {
+
+ public DefaultRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
+ }
+
+ protected List<FontCollection> getDefaultFontCollection() {
+ FontManager fontManager = userAgent.getFontManager();
+ List<FontCollection> fontCollection = new ArrayList<FontCollection>();
+ fontCollection.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));
+ return fontCollection;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/PrintRenderer.java b/src/java/org/apache/fop/render/PrintRenderer.java
index 96a62cb11..b1ff59c84 100644
--- a/src/java/org/apache/fop/render/PrintRenderer.java
+++ b/src/java/org/apache/fop/render/PrintRenderer.java
@@ -36,7 +36,6 @@ import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.base14.Base14FontCollection;
@@ -53,9 +52,6 @@ public abstract class PrintRenderer extends AbstractRenderer {
/** Font configuration */
protected FontInfo fontInfo;
- /** Font resolver */
- protected FontResolver fontResolver = null;
-
/** list of fonts */
protected List<EmbedFontInfo> embedFontInfoList = null;
@@ -88,11 +84,11 @@ public abstract class PrintRenderer extends AbstractRenderer {
/** {@inheritDoc} */
public void setupFontInfo(FontInfo inFontInfo) throws FOPException {
this.fontInfo = inFontInfo;
- FontManager fontManager = userAgent.getFactory().getFontManager();
+ FontManager fontManager = userAgent.getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
new Base14FontCollection(fontManager.isBase14KerningEnabled()),
- new CustomFontCollection(getFontResolver(), getFontList(),
- userAgent.isComplexScriptFeaturesEnabled())
+ new CustomFontCollection(fontManager.getResourceResolver(), getFontList(),
+ userAgent.isComplexScriptFeaturesEnabled())
};
fontManager.setup(getFontInfo(), fontCollections);
}
@@ -107,7 +103,7 @@ public abstract class PrintRenderer extends AbstractRenderer {
String key = fontInfo.getInternalFontKey(triplet);
if (key == null) {
//Find a default fallback font as last resort
- triplet = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+ triplet = FontTriplet.DEFAULT_FONT_TRIPLET;
key = fontInfo.getInternalFontKey(triplet);
}
return key;
@@ -180,18 +176,6 @@ public abstract class PrintRenderer extends AbstractRenderer {
}
/**
- * Get FontResolver
- *
- * @return FontResolver
- */
- public FontResolver getFontResolver() {
- if (this.fontResolver == null) {
- this.fontResolver = new DefaultFontResolver(super.userAgent);
- }
- return this.fontResolver;
- }
-
- /**
* @return the font info
*/
public FontInfo getFontInfo() {
diff --git a/src/java/org/apache/fop/render/PrintRendererConfigurator.java b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
index 93678b4f8..8de2d1a92 100644
--- a/src/java/org/apache/fop/render/PrintRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/PrintRendererConfigurator.java
@@ -19,124 +19,158 @@
package org.apache.fop.render;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import org.apache.avalon.framework.configuration.Configuration;
-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.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.CustomFontCollection;
+import org.apache.fop.fonts.DefaultFontConfigurator;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.fonts.FontConfigurator;
import org.apache.fop.fonts.FontEventAdapter;
-import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontInfoConfigurator;
import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontResolver;
-import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
/**
* Base Print renderer configurator (mostly handles font configuration)
*/
-public class PrintRendererConfigurator extends AbstractRendererConfigurator
- implements RendererConfigurator, IFDocumentHandlerConfigurator {
+public abstract class PrintRendererConfigurator extends AbstractRendererConfigurator
+ implements IFDocumentHandlerConfigurator {
+
+ private final RendererConfigParser rendererConfigParser;
- /** logger instance */
- protected static final Log log = LogFactory.getLog(PrintRendererConfigurator.class);
+ private final FontConfigurator<EmbedFontInfo> fontInfoConfigurator;
/**
* Default constructor
* @param userAgent user agent
*/
- public PrintRendererConfigurator(FOUserAgent userAgent) {
+ public PrintRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ this(userAgent, rendererConfigParser,
+ new DefaultFontConfigurator(userAgent.getFontManager(), new FontEventAdapter(
+ userAgent.getEventBroadcaster()), userAgent.validateUserConfigStrictly()));
+ }
+
+ /**
+ * Default constructor
+ * @param userAgent user agent
+ */
+ public PrintRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser,
+ FontConfigurator<EmbedFontInfo> fontInfoConfigurator) {
super(userAgent);
+ this.rendererConfigParser = rendererConfigParser;
+ this.fontInfoConfigurator = fontInfoConfigurator;
}
/**
- * Builds a list of EmbedFontInfo objects for use with the setup() method.
+ * Returns the renderer configuration data for a specific renderer.
*
- * @param renderer print renderer
- * @throws FOPException if something's wrong with the config data
+ * @param documentHandler the document handler
+ * @return the renderer configuration data
+ * @throws FOPException if an error occurs
*/
- public void configure(Renderer renderer) throws FOPException {
- Configuration cfg = getRendererConfig(renderer);
- if (cfg == null) {
- log.trace("no configuration found for " + renderer);
- return;
- }
-
- PrintRenderer printRenderer = (PrintRenderer)renderer;
- FontResolver fontResolver = printRenderer.getFontResolver();
+ protected RendererConfig getRendererConfig(IFDocumentHandler documentHandler) throws FOPException {
+ return getRendererConfig(documentHandler.getMimeType());
+ }
- FontEventListener listener = new FontEventAdapter(
- renderer.getUserAgent().getEventBroadcaster());
- List<EmbedFontInfo> embedFontInfoList = buildFontList(cfg, fontResolver, listener);
- printRenderer.addFontList(embedFontInfoList);
+ /**
+ * gets the renderer configuration data for a specific renderer.
+ *
+ * @param mimeType the MIME type
+ * @return the renderer configuration data
+ * @throws FOPException if an error occurs
+ */
+ protected RendererConfig getRendererConfig(String mimeType) throws FOPException {
+ return userAgent.getRendererConfig(mimeType, rendererConfigParser);
}
/**
- * Builds the font list from configuration.
- * @param cfg the configuration object
- * @param fontResolver a font resolver
- * @param listener the font event listener
- * @return the list of {@link EmbedFontInfo} objects
- * @throws FOPException if an error occurs while processing the configuration
+ * gets the renderer configuration data for a specific renderer.
+ *
+ * @param renderer the renderer
+ * @return the renderer configuration data
+ * @throws FOPException if an error occurs
*/
- protected List<EmbedFontInfo> buildFontList(Configuration cfg, FontResolver fontResolver,
- FontEventListener listener) throws FOPException {
- FopFactory factory = userAgent.getFactory();
- FontManager fontManager = factory.getFontManager();
- if (fontResolver == null) {
- //Ensure that we have minimal font resolution capabilities
- fontResolver
- = FontManager.createMinimalFontResolver
- ( userAgent.isComplexScriptFeaturesEnabled() );
- }
+ protected RendererConfig getRendererConfig(Renderer renderer) throws FOPException {
+ return getRendererConfig(renderer.getMimeType());
+ }
- boolean strict = factory.validateUserConfigStrictly();
- //Read font configuration
- FontInfoConfigurator fontInfoConfigurator
- = new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict);
- List<EmbedFontInfo> fontInfoList = new ArrayList<EmbedFontInfo>();
- fontInfoConfigurator.configure(fontInfoList);
- return fontInfoList;
+ /**
+ * 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 {
+ PrintRenderer printRenderer = (PrintRenderer) renderer;
+ List<EmbedFontInfo> embedFontInfoList = buildFontList(renderer.getMimeType());
+ printRenderer.addFontList(embedFontInfoList);
}
- // ---=== IFDocumentHandler configuration ===---
-
/** {@inheritDoc} */
public void configure(IFDocumentHandler documentHandler) throws FOPException {
//nop
}
/** {@inheritDoc} */
- public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
- throws FOPException {
- FontManager fontManager = userAgent.getFactory().getFontManager();
- List<FontCollection> fontCollections = new ArrayList<FontCollection>();
- fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));
-
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- FontResolver fontResolver = new DefaultFontResolver(userAgent);
- FontEventListener listener = new FontEventAdapter(
- userAgent.getEventBroadcaster());
- List<EmbedFontInfo> fontList = buildFontList(cfg, fontResolver, listener);
- fontCollections.add(new CustomFontCollection(fontResolver, fontList,
- userAgent.isComplexScriptFeaturesEnabled()));
+ public void setupFontInfo(String mimeType, FontInfo fontInfo) throws FOPException {
+ FontManager fontManager = userAgent.getFontManager();
+ List<FontCollection> fontCollections = getDefaultFontCollection();
+ fontCollections.add(getCustomFontCollection(fontManager.getResourceResolver(), mimeType));
+ fontManager.setup(fontInfo, fontCollections.toArray(new FontCollection[fontCollections.size()]));
+ }
+
+ protected abstract List<FontCollection> getDefaultFontCollection();
+
+ /**
+ * Returns the font collection for custom configured fonts.
+ *
+ * @param resolver the resource resolver
+ * @param mimeType the renderer MIME type
+ * @return the font collection
+ * @throws FOPException if an error occurs
+ */
+ protected FontCollection getCustomFontCollection(InternalResourceResolver resolver, String mimeType)
+ throws FOPException {
+ List<EmbedFontInfo> fontList;
+ if (rendererConfigParser == null) {
+ fontList = Collections.<EmbedFontInfo>emptyList();
+ } else {
+ fontList = fontInfoConfigurator.configure(getRendererConfig(mimeType).getFontInfoConfig());
}
+ return createCollectionFromFontList(resolver, fontList);
+ }
+
+ /***
+ * Creates the font collection given a list of embedded font infomation.
+ *
+ * @param resolver the resource resolver
+ * @param fontList the embedded font infomation
+ * @return the font collection
+ */
+ protected FontCollection createCollectionFromFontList(InternalResourceResolver resolver,
+ List<EmbedFontInfo> fontList) {
+ return new CustomFontCollection(resolver, fontList,
+ userAgent.isComplexScriptFeaturesEnabled());
+ }
+
+ private List<EmbedFontInfo> buildFontList(String mimeType) throws FOPException {
+ return fontInfoConfigurator.configure(getRendererConfig(mimeType).getFontInfoConfig());
+ }
- fontManager.setup(fontInfo,
- (FontCollection[])fontCollections.toArray(
- new FontCollection[fontCollections.size()]));
- documentHandler.setFontInfo(fontInfo);
+ public static PrintRendererConfigurator createDefaultInstance(FOUserAgent userAgent) {
+ return new PrintRendererConfigurator(userAgent, null) {
+ @Override
+ protected List<FontCollection> getDefaultFontCollection() {
+ throw new UnsupportedOperationException();
+ }
+ };
}
}
diff --git a/src/java/org/apache/fop/render/RendererConfig.java b/src/java/org/apache/fop/render/RendererConfig.java
new file mode 100644
index 000000000..4b3b63a51
--- /dev/null
+++ b/src/java/org/apache/fop/render/RendererConfig.java
@@ -0,0 +1,64 @@
+/*
+ * 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.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.FontConfig;
+
+/**
+ * Implementations of this interface have all the renderer-specific configuration data found in the
+ * FOP-conf. This object is just a data object that is created by the {@link RendererConfigParser}
+ * when the FOP conf is parsed.
+ */
+public interface RendererConfig {
+
+ /**
+ * Returns the render-specific font configuration information.
+ * @return the font config
+ */
+ FontConfig getFontInfoConfig();
+
+ /**
+ * Implementations of this interface parse the relevant renderer-specific configuration data
+ * within the FOP-conf and create a {@link RendererConfig}.
+ */
+ public interface RendererConfigParser {
+
+ /**
+ * Builds the object that contains the renderer configuration data.
+ *
+ * @param userAgent the user agent
+ * @param rendererConfiguration the Avalon config object for parsing the data
+ * @return the configuration data object
+ * @throws FOPException if an error occurs while parsing the fop conf
+ */
+ RendererConfig build(FOUserAgent userAgent, Configuration rendererConfiguration) throws FOPException;
+
+ /**
+ * The MIME type of the renderer.
+ *
+ * @return the mime type
+ */
+ String getMimeType();
+ }
+}
diff --git a/src/java/org/apache/fop/render/RendererConfigurator.java b/src/java/org/apache/fop/render/RendererConfigOption.java
index 6dceeb74d..5b670d07a 100644
--- a/src/java/org/apache/fop/render/RendererConfigurator.java
+++ b/src/java/org/apache/fop/render/RendererConfigOption.java
@@ -19,16 +19,11 @@
package org.apache.fop.render;
-import org.apache.fop.apps.FOPException;
-
/**
- * Renderer configurator interface
+ * Implementations of this interface enumerate the various renderer configuration options available
+ * to users in the FOP conf.
*/
-public interface RendererConfigurator {
- /**
- * Configures a renderer
- * @param renderer renderer
- * @throws FOPException fop exception
- */
- void configure(Renderer renderer) throws FOPException;
+public interface RendererConfigOption {
+ /** The name of the option. */
+ String getName();
}
diff --git a/src/java/org/apache/fop/render/RendererFactory.java b/src/java/org/apache/fop/render/RendererFactory.java
index 3ceb27a8e..df5213dad 100644
--- a/src/java/org/apache/fop/render/RendererFactory.java
+++ b/src/java/org/apache/fop/render/RendererFactory.java
@@ -36,6 +36,7 @@ import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.EventProducingFilter;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.intermediate.IFRenderer;
@@ -52,25 +53,19 @@ public class RendererFactory {
private Map eventHandlerMakerMapping = new java.util.HashMap();
private Map documentHandlerMakerMapping = new java.util.HashMap();
- private boolean rendererPreferred = false;
+ private final boolean rendererPreferred;
/**
* Main constructor.
+ * @param rendererPreferred Controls whether a {@link Renderer} is preferred over a
+ * {@link IFDocumentHandler} if both are available for the same MIME type. True to prefer the
+ * {@link Renderer}, false to prefer the {@link IFDocumentHandler}.
*/
- public RendererFactory() {
+ public RendererFactory(boolean rendererPreferred) {
discoverRenderers();
discoverFOEventHandlers();
discoverDocumentHandlers();
- }
-
- /**
- * Controls whether a {@link Renderer} is preferred over a {@link IFDocumentHandler} if
- * both are available for the same MIME type.
- * @param value true to prefer the {@link Renderer},
- * false to prefer the {@link IFDocumentHandler}.
- */
- public void setRendererPreferred(boolean value) {
- this.rendererPreferred = value;
+ this.rendererPreferred = rendererPreferred;
}
/**
@@ -239,7 +234,7 @@ public class RendererFactory {
* @param mime the requested output format
* @return the requested RendererMaker or null if none is available
*/
- public AbstractIFDocumentHandlerMaker getDocumentHandlerMaker(String mime) {
+ private AbstractIFDocumentHandlerMaker getDocumentHandlerMaker(String mime) {
AbstractIFDocumentHandlerMaker maker
= (AbstractIFDocumentHandlerMaker)documentHandlerMakerMapping.get(mime);
return maker;
@@ -299,10 +294,7 @@ public class RendererFactory {
AbstractRendererMaker maker = getRendererMaker(outputFormat);
if (maker != null) {
Renderer rend = maker.makeRenderer(userAgent);
- RendererConfigurator configurator = maker.getConfigurator(userAgent);
- if (configurator != null) {
- configurator.configure(rend);
- }
+ maker.configureRenderer(userAgent, rend);
return rend;
} else {
return null;
@@ -383,7 +375,10 @@ public class RendererFactory {
throw new UnsupportedOperationException(
"No IF document handler for the requested format available: " + outputFormat);
}
- IFDocumentHandler documentHandler = maker.makeIFDocumentHandler(userAgent);
+ IFDocumentHandler documentHandler = maker.makeIFDocumentHandler(new IFContext(userAgent));
+ // TODO: do all the configuration in the makeIfDocumentHandler method, that would beam when
+ // you ask for a document handler, a configured one is returned to you. Getting it and
+ // configuring it in two steps doesn't make sense.
IFDocumentHandlerConfigurator configurator = documentHandler.getConfigurator();
if (configurator != null) {
configurator.configure(documentHandler);
@@ -398,15 +393,15 @@ public class RendererFactory {
List lst = new java.util.ArrayList();
Iterator iter = this.rendererMakerMapping.keySet().iterator();
while (iter.hasNext()) {
- lst.add(((String)iter.next()));
+ lst.add(iter.next());
}
iter = this.eventHandlerMakerMapping.keySet().iterator();
while (iter.hasNext()) {
- lst.add(((String)iter.next()));
+ lst.add(iter.next());
}
iter = this.documentHandlerMakerMapping.keySet().iterator();
while (iter.hasNext()) {
- lst.add(((String)iter.next()));
+ lst.add(iter.next());
}
Collections.sort(lst);
return (String[])lst.toArray(new String[lst.size()]);
diff --git a/src/java/org/apache/fop/render/XMLHandlerConfigurator.java b/src/java/org/apache/fop/render/XMLHandlerConfigurator.java
index 604fdb672..fbce59a07 100644
--- a/src/java/org/apache/fop/render/XMLHandlerConfigurator.java
+++ b/src/java/org/apache/fop/render/XMLHandlerConfigurator.java
@@ -83,7 +83,7 @@ public class XMLHandlerConfigurator extends AbstractRendererConfigurator {
*/
public void configure(RendererContext context, String ns) throws FOPException {
//Optional XML handler configuration
- Configuration cfg = getRendererConfig(context.getRenderer());
+ Configuration cfg = userAgent.getRendererConfiguration(context.getRenderer().getMimeType());
if (cfg != null) {
cfg = getHandlerConfig(cfg, ns);
if (cfg != null) {
diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
index e0924c0d0..1bdb18cf2 100644
--- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java
+++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
@@ -19,6 +19,8 @@
package org.apache.fop.render.afp;
+import java.net.URI;
+
import org.apache.fop.afp.AFPResourceLevelDefaults;
/**
@@ -152,10 +154,10 @@ public interface AFPCustomizable {
boolean isStrokeGOCAText();
/**
- * Sets the default resource group file path
- * @param filePath the default resource group file path
+ * Sets the default resource group URI
+ * @param uri the default resource group URI
*/
- void setDefaultResourceGroupFilePath(String filePath);
+ void setDefaultResourceGroupUri(URI uri);
/**
* Sets the resource level defaults. The object passed in provides information which resource
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index d427f9d7f..9c786acf5 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -24,6 +24,7 @@ import java.awt.Dimension;
import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.util.HashMap;
+import java.net.URI;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -39,13 +40,13 @@ import org.apache.fop.afp.DataStream;
import org.apache.fop.afp.fonts.AFPFontCollection;
import org.apache.fop.afp.fonts.AFPPageFonts;
import org.apache.fop.afp.modca.ResourceObject;
-import org.apache.fop.afp.util.DefaultFOPResourceAccessor;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontEventAdapter;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontManager;
+import org.apache.fop.render.afp.AFPRendererConfig.AFPRendererConfigParser;
import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPIncludeFormMap;
import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap;
@@ -54,13 +55,14 @@ import org.apache.fop.render.afp.extensions.AFPPageSegmentElement;
import org.apache.fop.render.afp.extensions.AFPPageSetup;
import org.apache.fop.render.afp.extensions.ExtensionPlacement;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
/**
- * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation that
- * produces AFP (MO:DCA).
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation that produces AFP
+ * (MO:DCA).
*/
public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
implements AFPCustomizable {
@@ -109,8 +111,9 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
/**
* Default constructor.
*/
- public AFPDocumentHandler() {
- this.resourceManager = new AFPResourceManager();
+ public AFPDocumentHandler(IFContext context) {
+ super(context);
+ this.resourceManager = new AFPResourceManager(context.getUserAgent().getResourceResolver());
this.paintingState = new AFPPaintingState();
this.unitConv = paintingState.getUnitConverter();
}
@@ -127,13 +130,13 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
/** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new AFPRendererConfigurator(getUserAgent());
+ return new AFPRendererConfigurator(getUserAgent(), new AFPRendererConfigParser());
}
/** {@inheritDoc} */
@Override
public void setDefaultFontInfo(FontInfo fontInfo) {
- FontManager fontManager = getUserAgent().getFactory().getFontManager();
+ FontManager fontManager = getUserAgent().getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
new AFPFontCollection(getUserAgent().getEventBroadcaster(), null)
};
@@ -391,8 +394,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
} else if (extension instanceof AFPIncludeFormMap) {
AFPIncludeFormMap formMap = (AFPIncludeFormMap)extension;
- ResourceAccessor accessor = new DefaultFOPResourceAccessor(
- getUserAgent(), null, null);
+ AFPResourceAccessor accessor = new AFPResourceAccessor(
+ getUserAgent().getResourceResolver());
try {
getResourceManager().createIncludedResource(formMap.getName(),
formMap.getSrc(), accessor,
@@ -546,9 +549,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
return paintingState.getFS45();
}
- /** {@inheritDoc} */
- public void setDefaultResourceGroupFilePath(String filePath) {
- resourceManager.setDefaultResourceGroupFilePath(filePath);
+ public void setDefaultResourceGroupUri(URI uri) {
+ resourceManager.setDefaultResourceGroupUri(uri);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandlerMaker.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandlerMaker.java
index cbe6d0ca3..f83ede9f7 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.afp;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
@@ -36,10 +35,8 @@ public class AFPDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- AFPDocumentHandler handler = new AFPDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new AFPDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/afp/AFPFontConfig.java b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
new file mode 100644
index 000000000..eca76078f
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPFontConfig.java
@@ -0,0 +1,442 @@
+/*
+ * 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.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.afp.AFPEventProducer;
+import org.apache.fop.afp.fonts.AFPFont;
+import org.apache.fop.afp.fonts.AFPFontInfo;
+import org.apache.fop.afp.fonts.CharacterSet;
+import org.apache.fop.afp.fonts.CharacterSetBuilder;
+import org.apache.fop.afp.fonts.CharacterSetType;
+import org.apache.fop.afp.fonts.DoubleByteFont;
+import org.apache.fop.afp.fonts.OutlineFont;
+import org.apache.fop.afp.fonts.RasterFont;
+import org.apache.fop.afp.util.AFPResourceAccessor;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.events.EventProducer;
+import org.apache.fop.fonts.FontConfig;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.fonts.FontManagerConfigurator;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.FontTriplet.Matcher;
+import org.apache.fop.fonts.FontUtil;
+import org.apache.fop.fonts.Typeface;
+
+/**
+ * The config object for AFP fonts, these differ from the the more generic fonts (TTF and Type1).
+ */
+public final class AFPFontConfig implements FontConfig {
+
+ private static final Log LOG = LogFactory.getLog(AFPFontConfig.class);
+
+ private final List<AFPFontConfigData> fontsConfig;
+
+ private AFPFontConfig() {
+ fontsConfig = new ArrayList<AFPFontConfigData>();
+ }
+
+ /**
+ * Returns a list of AFP font configuration data.
+ * @return the AFP font config data
+ */
+ public List<AFPFontConfigData> getFontConfig() {
+ return fontsConfig;
+ }
+
+ /**
+ * The parser for AFP font data.
+ */
+ static final class AFPFontInfoConfigParser implements FontConfigParser {
+
+ /** {@inheritDoc}} */
+ public AFPFontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
+ EventProducer eventProducer) throws FOPException {
+ try {
+ return new ParserHelper(cfg, fontManager, strict,
+ (AFPEventProducer) eventProducer).fontConfig;
+ } catch (ConfigurationException ce) {
+ throw new FOPException(ce);
+ }
+ }
+
+ AFPFontConfig getEmptyConfig() {
+ return new AFPFontConfig();
+ }
+ }
+
+ private static final class AggregateMatcher implements Matcher {
+
+ private final List<Matcher> matchers;
+
+ private AggregateMatcher(Matcher... matchers) {
+ this.matchers = new ArrayList<Matcher>();
+ for (Matcher matcher : matchers) {
+ if (matcher != null) {
+ this.matchers.add(matcher);
+ }
+ }
+ }
+
+ public boolean matches(FontTriplet triplet) {
+ for (Matcher matcher : matchers) {
+ if (matcher.matches(triplet)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ }
+
+ private static final class ParserHelper {
+
+ private static final Log LOG = LogFactory.getLog(ParserHelper.class);
+
+ private final AFPFontConfig fontConfig;
+
+ private final Matcher matcher;
+
+ private ParserHelper(Configuration cfg, FontManager fontManager, boolean strict,
+ AFPEventProducer eventProducer) throws FOPException, ConfigurationException {
+ Configuration fonts = cfg.getChild("fonts");
+ Matcher localMatcher = null;
+ Configuration referencedFontsCfg = fonts.getChild("referenced-fonts", false);
+ if (referencedFontsCfg != null) {
+ localMatcher = FontManagerConfigurator.createFontsMatcher(referencedFontsCfg, strict);
+ }
+ matcher = new AggregateMatcher(fontManager.getReferencedFontsMatcher(), localMatcher);
+ fontConfig = new AFPFontConfig();
+ for (Configuration font : fonts.getChildren("font")) {
+ buildFont(font, eventProducer);
+ }
+ }
+
+ private void buildFont(Configuration fontCfg, AFPEventProducer eventProducer)
+ throws ConfigurationException {
+ //FontManager fontManager = this.userAgent.getFontManager();
+ Configuration[] triplets = fontCfg.getChildren("font-triplet");
+ List<FontTriplet> tripletList = new ArrayList<FontTriplet>();
+ if (triplets.length == 0) {
+ eventProducer.fontConfigMissing(this, "<font-triplet...", fontCfg.getLocation());
+ return;
+ }
+ for (Configuration triplet : triplets) {
+ int weight = FontUtil.parseCSS2FontWeight(triplet.getAttribute("weight"));
+ FontTriplet fontTriplet = new FontTriplet(triplet.getAttribute("name"),
+ triplet.getAttribute("style"), weight);
+ tripletList.add(fontTriplet);
+ }
+ //build the fonts
+ Configuration[] config = fontCfg.getChildren("afp-font");
+ if (config.length == 0) {
+ eventProducer.fontConfigMissing(this, "<afp-font...", fontCfg.getLocation());
+ return;
+ }
+ Configuration afpFontCfg = config[0];
+ String uri = afpFontCfg.getAttribute("base-uri", null);
+ try {
+ String type = afpFontCfg.getAttribute("type");
+ if (type == null) {
+ eventProducer.fontConfigMissing(this, "type attribute", fontCfg.getLocation());
+ return;
+ }
+ String codepage = afpFontCfg.getAttribute("codepage");
+ if (codepage == null) {
+ eventProducer.fontConfigMissing(this, "codepage attribute",
+ fontCfg.getLocation());
+ return;
+ }
+ String encoding = afpFontCfg.getAttribute("encoding");
+ if (encoding == null) {
+ eventProducer.fontConfigMissing(this, "encoding attribute",
+ fontCfg.getLocation());
+ return;
+ }
+
+ fontFromType(tripletList, type, codepage, encoding, afpFontCfg, eventProducer, uri);
+ } catch (ConfigurationException ce) {
+ eventProducer.invalidConfiguration(this, ce);
+ }
+ }
+
+ private void fontFromType(List<FontTriplet> fontTriplets, String type, String codepage,
+ String encoding, Configuration cfg, AFPEventProducer eventProducer, String embedURI)
+ throws ConfigurationException {
+ AFPFontConfigData config = null;
+ if ("raster".equalsIgnoreCase(type)) {
+ config = getRasterFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
+ embedURI);
+ } else if ("outline".equalsIgnoreCase(type)) {
+ config = getOutlineFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
+ embedURI);
+ } else if ("CIDKeyed".equalsIgnoreCase(type)) {
+ config = getCIDKeyedFont(fontTriplets, type, codepage, encoding, cfg,
+ eventProducer,
+ embedURI);
+ } else {
+ LOG.error("No or incorrect type attribute: " + type);
+ }
+ if (config != null) {
+ fontConfig.fontsConfig.add(config);
+ }
+ }
+
+ private CIDKeyedFontConfig getCIDKeyedFont(List<FontTriplet> fontTriplets, String type,
+ String codepage, String encoding, Configuration cfg, AFPEventProducer eventProducer,
+ String uri) throws ConfigurationException {
+ String characterset = cfg.getAttribute("characterset");
+ if (characterset == null) {
+ eventProducer.fontConfigMissing(this, "characterset attribute",
+ cfg.getLocation());
+ return null;
+ }
+ String name = cfg.getAttribute("name", characterset);
+ CharacterSetType charsetType = cfg.getAttributeAsBoolean("ebcdic-dbcs", false)
+ ? CharacterSetType.DOUBLE_BYTE_LINE_DATA : CharacterSetType.DOUBLE_BYTE;
+ return new CIDKeyedFontConfig(fontTriplets, type, codepage, encoding, characterset,
+ name, charsetType, isEmbbedable(fontTriplets), uri);
+ }
+
+ private OutlineFontConfig getOutlineFont(List<FontTriplet> fontTriplets, String type,
+ String codepage, String encoding, Configuration cfg,
+ AFPEventProducer eventProducer, String uri) throws ConfigurationException {
+ String characterset = cfg.getAttribute("characterset");
+ if (characterset == null) {
+ eventProducer.fontConfigMissing(this, "characterset attribute",
+ cfg.getLocation());
+ return null;
+ }
+ String name = cfg.getAttribute("name", characterset);
+ String base14 = cfg.getAttribute("base14-font", null);
+ return new OutlineFontConfig(fontTriplets, type, codepage, encoding, characterset,
+ name, base14, isEmbbedable(fontTriplets), uri);
+ }
+
+ private RasterFontConfig getRasterFont(List<FontTriplet> triplets, String type,
+ String codepage, String encoding, Configuration cfg,
+ AFPEventProducer eventProducer, String uri)
+ throws ConfigurationException {
+ String name = cfg.getAttribute("name", "Unknown");
+ // Create a new font object
+ Configuration[] rasters = cfg.getChildren("afp-raster-font");
+ if (rasters.length == 0) {
+ eventProducer.fontConfigMissing(this, "<afp-raster-font...",
+ cfg.getLocation());
+ return null;
+ }
+ List<RasterCharactersetData> charsetData = new ArrayList<RasterCharactersetData>();
+ for (Configuration rasterCfg : rasters) {
+ String characterset = rasterCfg.getAttribute("characterset");
+ if (characterset == null) {
+ eventProducer.fontConfigMissing(this, "characterset attribute",
+ cfg.getLocation());
+ return null;
+ }
+ float size = rasterCfg.getAttributeAsFloat("size");
+ int sizeMpt = (int) (size * 1000);
+ String base14 = rasterCfg.getAttribute("base14-font", null);
+ charsetData.add(new RasterCharactersetData(characterset, sizeMpt, base14));
+ }
+ return new RasterFontConfig(triplets, type, codepage, encoding, null, name, uri, charsetData,
+ isEmbbedable(triplets));
+ }
+
+ private boolean isEmbbedable(List<FontTriplet> triplets) {
+ for (FontTriplet triplet : triplets) {
+ if (matcher.matches(triplet)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ }
+
+ abstract static class AFPFontConfigData {
+ private final List<FontTriplet> triplets;
+ private final String codePage;
+ private final String encoding;
+ private final String name;
+ private final boolean embeddable;
+ private final String uri;
+
+ AFPFontConfigData(List<FontTriplet> triplets, String type, String codePage,
+ String encoding, String name, boolean embeddable, String uri) {
+ this.triplets = Collections.unmodifiableList(triplets);
+ this.codePage = codePage;
+ this.encoding = encoding;
+ this.name = name;
+ this.embeddable = embeddable;
+ this.uri = uri;
+ }
+
+ static AFPFontInfo getFontInfo(AFPFont font, AFPFontConfigData config) {
+ return font != null ? new AFPFontInfo(font, config.triplets) : null;
+ }
+
+ abstract AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver,
+ AFPEventProducer eventProducer) throws IOException;
+
+ AFPResourceAccessor getAccessor(InternalResourceResolver resourceResolver) {
+ return new AFPResourceAccessor(resourceResolver, uri);
+ }
+ }
+
+ static final class CIDKeyedFontConfig extends AFPFontConfigData {
+
+ private final CharacterSetType charsetType;
+
+ private final String characterset;
+
+ private CIDKeyedFontConfig(List<FontTriplet> triplets, String type, String codePage,
+ String encoding, String characterset, String name, CharacterSetType charsetType, boolean embeddable, String uri) {
+ super(triplets, type, codePage, encoding, name, embeddable, uri);
+ this.characterset = characterset;
+ this.charsetType = charsetType;
+ }
+
+ @Override
+ AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
+ throws IOException {
+ AFPResourceAccessor accessor = getAccessor(resourceResolver);
+ CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(
+ characterset, super.codePage, super.encoding, charsetType, accessor, eventProducer);
+ return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet),
+ this);
+ }
+ }
+
+ static final class OutlineFontConfig extends AFPFontConfigData {
+ private final String base14;
+ private final String characterset;
+
+ private OutlineFontConfig(List<FontTriplet> triplets, String type, String codePage,
+ String encoding, String characterset, String name, String base14, boolean embeddable, String uri) {
+ super(triplets, type, codePage, encoding, name, embeddable, uri);
+ this.characterset = characterset;
+ this.base14 = base14;
+ }
+
+ @Override
+ AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
+ throws IOException {
+ CharacterSet characterSet = null;
+ if (base14 != null) {
+ try {
+ Typeface tf = getTypeFace(base14);
+ characterSet = CharacterSetBuilder.getSingleByteInstance()
+ .build(characterset, super.codePage,
+ super.encoding, tf, eventProducer);
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "The base 14 font class for " + characterset
+ + " could not be found";
+ LOG.error(msg);
+ }
+ } else {
+ AFPResourceAccessor accessor = getAccessor(resourceResolver);
+ characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
+ characterset, super.codePage, super.encoding, accessor, eventProducer);
+ }
+ return getFontInfo(new OutlineFont(super.name, super.embeddable, characterSet), this);
+ }
+ }
+
+ private static Typeface getTypeFace(String base14Name) throws ClassNotFoundException {
+ try {
+ Class<? extends Typeface> clazz = Class.forName("org.apache.fop.fonts.base14."
+ + base14Name).asSubclass(Typeface.class);
+ return clazz.newInstance();
+ } catch (IllegalAccessException iae) {
+ LOG.error(iae.getMessage());
+ } catch (ClassNotFoundException cnfe) {
+ LOG.error(cnfe.getMessage());
+ } catch (InstantiationException ie) {
+ LOG.error(ie.getMessage());
+ }
+ throw new ClassNotFoundException("Couldn't load file for AFP font with base14 name: "
+ + base14Name);
+ }
+
+ static final class RasterFontConfig extends AFPFontConfigData {
+ private final List<RasterCharactersetData> charsets;
+
+ private RasterFontConfig(List<FontTriplet> triplets, String type, String codePage,
+ String encoding, String characterset, String name, String uri,
+ List<RasterCharactersetData> csetData, boolean embeddable) {
+ super(triplets, type, codePage, encoding, name, embeddable, uri);
+ this.charsets = Collections.unmodifiableList(csetData);
+ }
+
+ @Override
+ AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
+ throws IOException {
+ RasterFont rasterFont = new RasterFont(super.name, super.embeddable);
+ for (RasterCharactersetData charset : charsets) {
+ if (charset.base14 != null) {
+ try {
+ Typeface tf = getTypeFace(charset.base14);
+ rasterFont.addCharacterSet(charset.size,
+ CharacterSetBuilder.getSingleByteInstance().build(
+ charset.characterset, super.codePage, super.encoding,
+ tf, eventProducer));
+
+ } catch (ClassNotFoundException cnfe) {
+ String msg = "The base 14 font class for " + charset.characterset
+ + " could not be found";
+ LOG.error(msg);
+ } catch (IOException ie) {
+ String msg = "The base 14 font class " + charset.characterset
+ + " could not be instantiated";
+ LOG.error(msg);
+ }
+ } else {
+ AFPResourceAccessor accessor = getAccessor(resourceResolver);
+ rasterFont.addCharacterSet(charset.size,
+ CharacterSetBuilder.getSingleByteInstance().buildSBCS(charset.characterset,
+ super.codePage, super.encoding, accessor, eventProducer));
+ }
+ }
+ return getFontInfo(rasterFont, this);
+ }
+ }
+
+ static final class RasterCharactersetData {
+ private final String characterset;
+ private final int size;
+ private final String base14;
+
+ private RasterCharactersetData(String characterset, int size, String base14) {
+ this.characterset = characterset;
+ this.size = size;
+ this.base14 = base14;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java
index a03aaf816..5f155e277 100644
--- a/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java
+++ b/src/java/org/apache/fop/render/afp/AFPForeignAttributeReader.java
@@ -19,7 +19,7 @@
package org.apache.fop.render.afp;
-import java.io.File;
+import java.net.URI;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -46,7 +46,7 @@ public class AFPForeignAttributeReader {
AFPElementMapping.NAMESPACE, "afp:resource-level");
/** the resource-group-file attribute */
- public static final QName RESOURCE_GROUP_FILE = new QName(
+ public static final QName RESOURCE_GROUP_URI = new QName(
AFPElementMapping.NAMESPACE, "afp:resource-group-file");
/**
@@ -64,7 +64,7 @@ public class AFPForeignAttributeReader {
public AFPResourceInfo getResourceInfo(Map/*<QName, String>*/ foreignAttributes) {
AFPResourceInfo resourceInfo = new AFPResourceInfo();
if (foreignAttributes != null && !foreignAttributes.isEmpty()) {
- String resourceName = (String)foreignAttributes.get(RESOURCE_NAME);
+ String resourceName = (String) foreignAttributes.get(RESOURCE_NAME);
if (resourceName != null) {
resourceInfo.setName(resourceName);
}
@@ -82,45 +82,20 @@ public class AFPForeignAttributeReader {
* @param foreignAttributes the foreign attributes
* @return the resource level
*/
- public AFPResourceLevel getResourceLevel(Map/*<QName, String>*/ foreignAttributes) {
+ public AFPResourceLevel getResourceLevel(Map<QName, String> foreignAttributes) {
AFPResourceLevel resourceLevel = null;
if (foreignAttributes != null && !foreignAttributes.isEmpty()) {
if (foreignAttributes.containsKey(RESOURCE_LEVEL)) {
- String levelString = (String)foreignAttributes.get(RESOURCE_LEVEL);
+ String levelString = foreignAttributes.get(RESOURCE_LEVEL);
resourceLevel = AFPResourceLevel.valueOf(levelString);
// if external get resource group file attributes
if (resourceLevel != null && resourceLevel.isExternal()) {
- String resourceGroupFile
- = (String)foreignAttributes.get(RESOURCE_GROUP_FILE);
- if (resourceGroupFile == null) {
- String msg = RESOURCE_GROUP_FILE + " not specified";
- LOG.error(msg);
+ String resourceGroupUri = foreignAttributes.get(RESOURCE_GROUP_URI);
+ if (resourceGroupUri == null) {
+ String msg = RESOURCE_GROUP_URI + " not specified";
throw new UnsupportedOperationException(msg);
}
- File resourceExternalGroupFile = new File(resourceGroupFile);
- SecurityManager security = System.getSecurityManager();
- try {
- if (security != null) {
- security.checkWrite(resourceExternalGroupFile.getPath());
- }
- } catch (SecurityException ex) {
- String msg = "unable to gain write access to external resource file: "
- + resourceGroupFile;
- LOG.error(msg);
- }
-
- try {
- boolean exists = resourceExternalGroupFile.exists();
- if (exists) {
- LOG.warn("overwriting external resource file: "
- + resourceGroupFile);
- }
- resourceLevel.setExternalFilePath(resourceGroupFile);
- } catch (SecurityException ex) {
- String msg = "unable to gain read access to external resource file: "
- + resourceGroupFile;
- LOG.error(msg);
- }
+ resourceLevel.setExternalUri(URI.create(resourceGroupUri));
}
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java
index 834304f6b..68d806a1c 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerSVG.java
@@ -42,6 +42,7 @@ import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceLevel;
+import org.apache.fop.afp.AFPResourceLevel.ResourceType;
import org.apache.fop.afp.AFPResourceManager;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.image.loader.batik.BatikImageFlavors;
@@ -142,7 +143,7 @@ public class AFPImageHandlerSVG implements ImageHandler {
//level not explicitly set/changed so default to inline for GOCA graphic objects
// (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07), hard copy works just fine)
if (!resourceInfo.levelChanged()) {
- resourceInfo.setLevel(new AFPResourceLevel(AFPResourceLevel.INLINE));
+ resourceInfo.setLevel(new AFPResourceLevel(ResourceType.INLINE));
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPPainter.java b/src/java/org/apache/fop/render/afp/AFPPainter.java
index 5d8c1a93f..47ff5dba1 100644
--- a/src/java/org/apache/fop/render/afp/AFPPainter.java
+++ b/src/java/org/apache/fop/render/afp/AFPPainter.java
@@ -51,6 +51,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
import org.apache.fop.afp.AFPBorderPainter;
+import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.AFPObjectAreaInfo;
import org.apache.fop.afp.AFPPaintingState;
import org.apache.fop.afp.AFPResourceInfo;
@@ -67,17 +68,14 @@ import org.apache.fop.afp.modca.AbstractPageObject;
import org.apache.fop.afp.modca.PresentationTextObject;
import org.apache.fop.afp.ptoca.PtocaBuilder;
import org.apache.fop.afp.ptoca.PtocaProducer;
-import org.apache.fop.afp.util.DefaultFOPResourceAccessor;
-import org.apache.fop.afp.util.ResourceAccessor;
+import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.ImageHandlerUtil;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.BorderPainter;
-import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -88,7 +86,7 @@ import org.apache.fop.util.CharUtilities;
/**
* IFPainter implementation that produces AFP (MO:DCA).
*/
-public class AFPPainter extends AbstractIFPainter {
+public class AFPPainter extends AbstractIFPainter<AFPDocumentHandler> {
@@ -99,8 +97,6 @@ public class AFPPainter extends AbstractIFPainter {
private static final int X = 0;
private static final int Y = 1;
- private final AFPDocumentHandler documentHandler;
-
/** the border painter */
private final AFPBorderPainterAdapter borderPainter;
/** the rectangle painter */
@@ -109,37 +105,39 @@ public class AFPPainter extends AbstractIFPainter {
/** unit converter */
private final AFPUnitConverter unitConv;
+ private final AFPEventProducer eventProducer;
+
/**
* Default constructor.
* @param documentHandler the parent document handler
*/
public AFPPainter(AFPDocumentHandler documentHandler) {
- super();
- this.documentHandler = documentHandler;
+ super(documentHandler);
this.state = IFState.create();
this.borderPainter = new AFPBorderPainterAdapter(
new AFPBorderPainter(getPaintingState(), getDataStream()), this, documentHandler);
this.rectanglePainter = documentHandler.createRectanglePainter();
this.unitConv = getPaintingState().getUnitConverter();
+ this.eventProducer = AFPEventProducer.Provider.get(getUserAgent().getEventBroadcaster());
}
- /** {@inheritDoc} */
- @Override
- protected IFContext getContext() {
- return this.documentHandler.getContext();
- }
-
- FontInfo getFontInfo() {
- return this.documentHandler.getFontInfo();
+ private AFPPaintingState getPaintingState() {
+ return getDocumentHandler().getPaintingState();
}
- AFPPaintingState getPaintingState() {
- return this.documentHandler.getPaintingState();
+ private DataStream getDataStream() {
+ return getDocumentHandler().getDataStream();
}
- DataStream getDataStream() {
- return this.documentHandler.getDataStream();
+ @Override
+ public String getFontKey(FontTriplet triplet) throws IFException {
+ try {
+ return super.getFontKey(triplet);
+ } catch (IFException e) {
+ eventProducer.invalidConfiguration(null, e);
+ return super.getFontKey(FontTriplet.DEFAULT_FONT_TRIPLET);
+ }
}
/** {@inheritDoc} */
@@ -205,7 +203,7 @@ public class AFPPainter extends AbstractIFPainter {
protected RenderingContext createRenderingContext() {
AFPRenderingContext renderingContext = new AFPRenderingContext(
getUserAgent(),
- documentHandler.getResourceManager(),
+ getDocumentHandler().getResourceManager(),
getPaintingState(),
getFontInfo(),
getContext().getForeignAttributes());
@@ -214,7 +212,7 @@ public class AFPPainter extends AbstractIFPainter {
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle rect) throws IFException {
- PageSegmentDescriptor pageSegment = documentHandler.getPageSegmentNameFor(uri);
+ PageSegmentDescriptor pageSegment = getDocumentHandler().getPageSegmentNameFor(uri);
if (pageSegment != null) {
float[] srcPts = {rect.x, rect.y};
@@ -227,11 +225,11 @@ public class AFPPainter extends AbstractIFPainter {
//Do we need to embed an external page segment?
if (pageSegment.getURI() != null) {
- ResourceAccessor accessor = new DefaultFOPResourceAccessor (
- documentHandler.getUserAgent(), null, null);
+ AFPResourceAccessor accessor = new AFPResourceAccessor(
+ getDocumentHandler().getUserAgent().getResourceResolver());
try {
URI resourceUri = new URI(pageSegment.getURI());
- documentHandler.getResourceManager().createIncludedResourceFromExternal(
+ getDocumentHandler().getResourceManager().createIncludedResourceFromExternal(
pageSegment.getName(), resourceUri, accessor);
} catch (URISyntaxException urie) {
@@ -1186,14 +1184,10 @@ public class AFPPainter extends AbstractIFPainter {
FontTriplet triplet = new FontTriplet(
state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
//TODO Ignored: state.getFontVariant()
- String fontKey = getFontInfo().getInternalFontKey(triplet);
- if (fontKey == null) {
- triplet = new FontTriplet("any", Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
- fontKey = getFontInfo().getInternalFontKey(triplet);
- }
+ String fontKey = getFontKey(triplet);
// register font as necessary
- Map<String, Typeface> fontMetricMap = documentHandler.getFontInfo().getFonts();
+ Map<String, Typeface> fontMetricMap = getFontInfo().getFonts();
final AFPFont afpFont = (AFPFont)fontMetricMap.get(fontKey);
final Font font = getFontInfo().getFontInstance(triplet, fontSize);
AFPPageFonts pageFonts = getPaintingState().getPageFonts();
@@ -1207,7 +1201,7 @@ public class AFPPainter extends AbstractIFPainter {
if (afpFont.isEmbeddable()) {
try {
- documentHandler.getResourceManager().embedFont(afpFont, charSet);
+ getDocumentHandler().getResourceManager().embedFont(afpFont, charSet);
} catch (IOException ioe) {
throw new IFException("Error while embedding font resources", ioe);
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfig.java b/src/java/org/apache/fop/render/afp/AFPRendererConfig.java
new file mode 100644
index 000000000..90cc6e767
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfig.java
@@ -0,0 +1,375 @@
+/*
+ * 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.net.URI;
+import java.net.URISyntaxException;
+import java.util.EnumMap;
+
+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.afp.AFPConstants;
+import org.apache.fop.afp.AFPDataObjectInfo;
+import org.apache.fop.afp.AFPEventProducer;
+import org.apache.fop.afp.AFPResourceLevel;
+import org.apache.fop.afp.AFPResourceLevelDefaults;
+import org.apache.fop.afp.modca.triplets.MappingOptionTriplet;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.fonts.FontManager;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.afp.AFPFontConfig.AFPFontInfoConfigParser;
+import org.apache.fop.util.LogUtil;
+
+import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_COLOR;
+import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_GRAYSCALE;
+import static org.apache.fop.render.afp.AFPRendererOption.DEFAULT_RESOURCE_LEVELS;
+import static org.apache.fop.render.afp.AFPRendererOption.GOCA;
+import static org.apache.fop.render.afp.AFPRendererOption.GOCA_TEXT;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_DITHERING_QUALITY;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_FS45;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_JPEG;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MAPPING_OPTION;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_MODE;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_NATIVE;
+import static org.apache.fop.render.afp.AFPRendererOption.IMAGES_WRAP_PSEG;
+import static org.apache.fop.render.afp.AFPRendererOption.JPEG_ALLOW_JPEG_EMBEDDING;
+import static org.apache.fop.render.afp.AFPRendererOption.JPEG_BITMAP_ENCODING_QUALITY;
+import static org.apache.fop.render.afp.AFPRendererOption.LINE_WIDTH_CORRECTION;
+import static org.apache.fop.render.afp.AFPRendererOption.RENDERER_RESOLUTION;
+import static org.apache.fop.render.afp.AFPRendererOption.RESOURCE_GROUP_URI;
+import static org.apache.fop.render.afp.AFPRendererOption.SHADING;
+
+/**
+ * The AFP renderer config object.
+ */
+public final class AFPRendererConfig implements RendererConfig {
+
+ /**
+ * An enumeration for the various images modes available to the AFP renderer.
+ */
+ public enum ImagesModeOptions {
+
+ MODE_GRAYSCALE("b+w", "bits-per-pixel"),
+ MODE_COLOR("color", "cmyk");
+
+ private final String name;
+
+ private final String modeAttribute;
+
+ private ImagesModeOptions(String name, String modeAttribute) {
+ this.name = name;
+ this.modeAttribute = modeAttribute;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getModeAttribute() {
+ return modeAttribute;
+ }
+
+ public static ImagesModeOptions forName(String name) {
+ for (ImagesModeOptions option : values()) {
+ if (option.name.equals(name)) {
+ return option;
+ }
+ }
+ throw new IllegalArgumentException(name);
+ }
+ }
+
+ private final EnumMap<AFPRendererOption, Object> params = new EnumMap<AFPRendererOption, Object>(AFPRendererOption.class);
+
+ private final EnumMap<ImagesModeOptions, Object> imageModeParams
+ = new EnumMap<ImagesModeOptions, Object>(ImagesModeOptions.class);
+
+ private final AFPFontConfig fontConfig;
+
+ private AFPRendererConfig(AFPFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public AFPFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public Boolean isColorImages() {
+ return getParam(IMAGES_MODE, Boolean.class);
+ }
+
+ public Boolean isCmykImagesSupported() {
+ if (!isColorImages()) {
+ throw new IllegalStateException();
+ }
+ return Boolean.class.cast(imageModeParams.get(MODE_COLOR));
+ }
+
+ public Integer getBitsPerPixel() {
+ if (isColorImages()) {
+ throw new IllegalStateException();
+ }
+ return Integer.class.cast(imageModeParams.get(MODE_GRAYSCALE));
+ }
+
+ public Float getDitheringQuality() {
+ return getParam(IMAGES_DITHERING_QUALITY, Float.class);
+ }
+
+ public Boolean isNativeImagesSupported() {
+ return getParam(IMAGES_NATIVE, Boolean.class);
+ }
+
+ public AFPShadingMode getShadingMode() {
+ return getParam(SHADING, AFPShadingMode.class);
+ }
+
+ public Integer getResolution() {
+ return getParam(RENDERER_RESOLUTION, Integer.class);
+ }
+
+
+ public URI getDefaultResourceGroupUri() {
+ return getParam(RESOURCE_GROUP_URI, URI.class);
+ }
+
+ public AFPResourceLevelDefaults getResourceLevelDefaults() {
+ return getParam(DEFAULT_RESOURCE_LEVELS, AFPResourceLevelDefaults.class);
+ }
+
+ public Boolean isWrapPseg() {
+ return getParam(IMAGES_WRAP_PSEG, Boolean.class);
+ }
+
+ public Boolean isFs45() {
+ return getParam(IMAGES_FS45, Boolean.class);
+ }
+
+ public Boolean allowJpegEmbedding() {
+ return getParam(JPEG_ALLOW_JPEG_EMBEDDING, Boolean.class);
+ }
+
+ public Float getBitmapEncodingQuality() {
+ return getParam(JPEG_BITMAP_ENCODING_QUALITY, Float.class);
+ }
+
+ public Float getLineWidthCorrection() {
+ return getParam(LINE_WIDTH_CORRECTION, Float.class);
+ }
+
+ public Boolean isGocaEnabled() {
+ return getParam(GOCA, Boolean.class);
+ }
+
+ public Boolean isStrokeGocaText() {
+ return getParam(GOCA_TEXT, Boolean.class);
+ }
+
+ private <T> T getParam(AFPRendererOption options, Class<T> type) {
+ assert options.getType().equals(type);
+ return type.cast(params.get(options));
+ }
+
+ private <T> void setParam(AFPRendererOption option, T value) {
+ assert option.getType().isInstance(value);
+ params.put(option, value);
+ }
+
+ /**
+ * The parser for AFP renderer specific data in the FOP conf.
+ */
+ public static final class AFPRendererConfigParser implements RendererConfigParser {
+
+ private static final Log LOG = LogFactory.getLog(AFPRendererConfigParser.class);
+
+ /** {@inheritDoc} */
+ public AFPRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ boolean strict = userAgent.validateUserConfigStrictly();
+ AFPRendererConfig config = null;
+ AFPEventProducer eventProducer = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster());
+ try {
+ config = new ParserHelper(cfg, userAgent.getFontManager(), strict, eventProducer).config;
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, strict);
+ }
+ return config;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_AFP;
+ }
+ }
+
+ private static final class ParserHelper {
+
+ private static final Log LOG = LogFactory.getLog(ParserHelper.class);
+
+ private final AFPRendererConfig config;
+
+ private final boolean strict;
+
+ private final Configuration cfg;
+
+ private ParserHelper(Configuration cfg, FontManager fontManager, boolean strict,
+ AFPEventProducer eventProducer)
+ throws ConfigurationException, FOPException {
+ this.cfg = cfg;
+ this.strict = strict;
+ if (cfg != null) {
+ config = new AFPRendererConfig(new AFPFontInfoConfigParser().parse(cfg,
+ fontManager, strict, eventProducer));
+ configure();
+ } else {
+ config = new AFPRendererConfig(new AFPFontInfoConfigParser().getEmptyConfig());
+ }
+ }
+
+ private void configure() throws ConfigurationException, FOPException {
+ configureImages();
+ setParam(SHADING, AFPShadingMode.getValueOf(
+ cfg.getChild(SHADING.getName()).getValue(AFPShadingMode.COLOR.getName())));
+ Configuration rendererResolutionCfg = cfg.getChild(RENDERER_RESOLUTION.getName(), false);
+ setParam(RENDERER_RESOLUTION, rendererResolutionCfg == null ? 240
+ : rendererResolutionCfg.getValueAsInteger(240));
+ Configuration lineWidthCorrectionCfg = cfg.getChild(LINE_WIDTH_CORRECTION.getName(),
+ false);
+ setParam(LINE_WIDTH_CORRECTION, lineWidthCorrectionCfg != null
+ ? lineWidthCorrectionCfg.getValueAsFloat()
+ : AFPConstants.LINE_WIDTH_CORRECTION);
+ Configuration gocaCfg = cfg.getChild(GOCA.getName());
+ boolean gocaEnabled = gocaCfg.getAttributeAsBoolean("enabled", true);
+ setParam(GOCA, gocaEnabled);
+ String strokeGocaText = gocaCfg.getAttribute(GOCA_TEXT.getName(), "default");
+ setParam(GOCA_TEXT, "stroke".equalsIgnoreCase(strokeGocaText)
+ || "shapes".equalsIgnoreCase(strokeGocaText));
+ //TODO remove
+ createResourceGroupFile();
+ createResourceLevel();
+ }
+
+ private void setParam(AFPRendererOption option, Object value) {
+ config.setParam(option, value);
+ }
+
+ private void configureImages() throws ConfigurationException, FOPException {
+ Configuration imagesCfg = cfg.getChild(IMAGES.getName());
+ ImagesModeOptions imagesMode = ImagesModeOptions.forName(imagesCfg.getAttribute(
+ IMAGES_MODE.getName(), MODE_GRAYSCALE.getName()));
+ boolean colorImages = MODE_COLOR == imagesMode;
+ setParam(IMAGES_MODE, colorImages);
+ if (colorImages) {
+ config.imageModeParams.put(MODE_COLOR, imagesCfg
+ .getAttributeAsBoolean(imagesMode.getModeAttribute(), false));
+ } else {
+ config.imageModeParams.put(MODE_GRAYSCALE,
+ imagesCfg.getAttributeAsInteger(imagesMode.getModeAttribute(), 8));
+ }
+ String dithering = imagesCfg.getAttribute(AFPRendererOption.IMAGES_DITHERING_QUALITY.getName(), "medium");
+ float dq;
+ if (dithering.startsWith("min")) {
+ dq = 0.0f;
+ } else if (dithering.startsWith("max")) {
+ dq = 1.0f;
+ } else {
+ try {
+ dq = Float.parseFloat(dithering);
+ } catch (NumberFormatException nfe) {
+ //Default value
+ dq = 0.5f;
+ }
+ }
+ setParam(IMAGES_DITHERING_QUALITY, dq);
+ setParam(IMAGES_NATIVE, imagesCfg.getAttributeAsBoolean(IMAGES_NATIVE.getName(), false));
+ setParam(IMAGES_WRAP_PSEG,
+ imagesCfg.getAttributeAsBoolean(IMAGES_WRAP_PSEG.getName(), false));
+ setParam(IMAGES_FS45, imagesCfg.getAttributeAsBoolean(IMAGES_FS45.getName(), false));
+ if ("scale-to-fit".equals(imagesCfg.getAttribute(IMAGES_MAPPING_OPTION.getName(), null))) {
+ setParam(IMAGES_MAPPING_OPTION, MappingOptionTriplet.SCALE_TO_FILL);
+ } else {
+ setParam(IMAGES_MAPPING_OPTION, AFPDataObjectInfo.DEFAULT_MAPPING_OPTION);
+ }
+ configureJpegImages(imagesCfg);
+ }
+
+ private void configureJpegImages(Configuration imagesCfg) {
+ Configuration jpegConfig = imagesCfg.getChild(IMAGES_JPEG.getName());
+ float bitmapEncodingQuality = 1.0f;
+ boolean allowJpegEmbedding = false;
+ if (jpegConfig != null) {
+ allowJpegEmbedding = jpegConfig.getAttributeAsBoolean(
+ JPEG_ALLOW_JPEG_EMBEDDING.getName(),
+ false);
+ String bitmapEncodingQualityStr = jpegConfig.getAttribute(
+ JPEG_BITMAP_ENCODING_QUALITY.getName(), null);
+ if (bitmapEncodingQualityStr != null) {
+ try {
+ bitmapEncodingQuality = Float.parseFloat(bitmapEncodingQualityStr);
+ } catch (NumberFormatException nfe) {
+ //ignore and leave the default above
+ }
+ }
+ }
+ setParam(JPEG_BITMAP_ENCODING_QUALITY, bitmapEncodingQuality);
+ setParam(JPEG_ALLOW_JPEG_EMBEDDING, allowJpegEmbedding);
+ }
+
+ private void createResourceGroupFile() throws FOPException {
+ try {
+ Configuration resourceGroupUriCfg = cfg.getChild(RESOURCE_GROUP_URI.getName(), false);
+ if (resourceGroupUriCfg != null) {
+ URI resourceGroupUri = InternalResourceResolver.cleanURI(resourceGroupUriCfg.getValue());
+ setParam(RESOURCE_GROUP_URI, resourceGroupUri);
+ }
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, strict);
+ } catch (URISyntaxException use) {
+ LogUtil.handleException(LOG, use, strict);
+ }
+ }
+
+ private void createResourceLevel() throws FOPException {
+ Configuration defaultResourceLevelCfg = cfg.getChild(DEFAULT_RESOURCE_LEVELS.getName(), false);
+ if (defaultResourceLevelCfg != null) {
+ AFPResourceLevelDefaults defaults = new AFPResourceLevelDefaults();
+ String[] types = defaultResourceLevelCfg.getAttributeNames();
+ for (int i = 0, c = types.length; i < c; i++) {
+ String type = types[i];
+ try {
+ String level = defaultResourceLevelCfg.getAttribute(type);
+ defaults.setDefaultResourceLevel(type, AFPResourceLevel.valueOf(level));
+ } catch (IllegalArgumentException iae) {
+ LogUtil.handleException(LOG, iae, strict);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, strict);
+ }
+ }
+ setParam(DEFAULT_RESOURCE_LEVELS, defaults);
+ }
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index e93d8b6aa..3412c3d67 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -19,42 +19,24 @@
package org.apache.fop.render.afp;
-import java.io.File;
import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
-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.afp.AFPConstants;
import org.apache.fop.afp.AFPEventProducer;
-import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceLevelDefaults;
-import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontCollection;
import org.apache.fop.afp.fonts.AFPFontInfo;
-import org.apache.fop.afp.fonts.CharacterSet;
-import org.apache.fop.afp.fonts.CharacterSetBuilder;
-import org.apache.fop.afp.fonts.CharacterSetType;
-import org.apache.fop.afp.fonts.DoubleByteFont;
-import org.apache.fop.afp.fonts.OutlineFont;
-import org.apache.fop.afp.fonts.RasterFont;
-import org.apache.fop.afp.util.DefaultFOPResourceAccessor;
-import org.apache.fop.afp.util.ResourceAccessor;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.FontCollection;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontManagerConfigurator;
-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.RendererConfig.RendererConfigParser;
+import org.apache.fop.render.afp.AFPFontConfig.AFPFontConfigData;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.util.LogUtil;
@@ -62,8 +44,9 @@ import org.apache.fop.util.LogUtil;
/**
* AFP Renderer configurator
*/
-public class AFPRendererConfigurator extends PrintRendererConfigurator
- implements IFDocumentHandlerConfigurator {
+public class AFPRendererConfigurator extends PrintRendererConfigurator implements
+ IFDocumentHandlerConfigurator {
+ private static Log log = LogFactory.getLog(AFPRendererConfigurator.class);
private final AFPEventProducer eventProducer;
@@ -72,470 +55,104 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
*
* @param userAgent user agent
*/
- public AFPRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public AFPRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
eventProducer = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster());
}
- private AFPFontInfo buildFont(Configuration fontCfg, String fontPath)
- throws ConfigurationException {
- FontManager fontManager = this.userAgent.getFactory().getFontManager();
- Configuration[] triple = fontCfg.getChildren("font-triplet");
- List<FontTriplet> tripletList = new ArrayList<FontTriplet>();
- if (triple.length == 0) {
- eventProducer.fontConfigMissing(this, "<font-triplet...", fontCfg.getLocation());
- return null;
- }
- for (Configuration config : triple) {
- int weight = FontUtil.parseCSS2FontWeight(config.getAttribute("weight"));
- FontTriplet triplet = new FontTriplet(config.getAttribute("name"),
- config.getAttribute("style"),
- weight);
- tripletList.add(triplet);
- }
-
- //build the fonts
- Configuration[] config = fontCfg.getChildren("afp-font");
- if (config.length == 0) {
- eventProducer.fontConfigMissing(this, "<afp-font...", fontCfg.getLocation());
- return null;
- }
- Configuration afpFontCfg = config[0];
-
- URI baseURI = null;
- String uri = afpFontCfg.getAttribute("base-uri", fontPath);
- if (uri == null) {
- //Fallback for old attribute which only supports local filenames
- String path = afpFontCfg.getAttribute("path", fontPath);
- if (path != null) {
- File f = new File(path);
- baseURI = f.toURI();
- }
- } else {
- try {
- baseURI = new URI(uri);
- } catch (URISyntaxException e) {
- eventProducer.invalidConfiguration(this, e);
- return null;
- }
- }
- ResourceAccessor accessor = new DefaultFOPResourceAccessor(
- this.userAgent,
- fontManager.getFontBaseURL(),
- baseURI);
-
- AFPFont font = null;
- try {
- String type = afpFontCfg.getAttribute("type");
- if (type == null) {
- eventProducer.fontConfigMissing(this, "type attribute", fontCfg.getLocation());
- return null;
- }
- String codepage = afpFontCfg.getAttribute("codepage");
- if (codepage == null) {
- eventProducer.fontConfigMissing(this, "codepage attribute",
- fontCfg.getLocation());
- return null;
- }
- String encoding = afpFontCfg.getAttribute("encoding");
- if (encoding == null) {
- eventProducer.fontConfigMissing(this, "encoding attribute",
- fontCfg.getLocation());
- return null;
- }
-
- font = fontFromType(type, codepage, encoding, accessor, afpFontCfg);
- } catch (ConfigurationException ce) {
- eventProducer.invalidConfiguration(this, ce);
- } catch (IOException ioe) {
- eventProducer.invalidConfiguration(this, ioe);
- } catch (IllegalArgumentException iae) {
- eventProducer.invalidConfiguration(this, iae);
+ @Override
+ public void configure(IFDocumentHandler documentHandler) throws FOPException {
+ AFPRendererConfig config = (AFPRendererConfig) getRendererConfig(documentHandler);
+ if (config != null) {
+ AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler) documentHandler;
+ configure(afpDocumentHandler, config);
}
-
- return font != null ? new AFPFontInfo(font, tripletList) : null;
}
-
- /**
- * Create the AFPFont based on type and type-dependent configuration.
- *
- * @param type font type e.g. 'raster', 'outline'
- * @param codepage codepage file
- * @param encoding character encoding e.g. 'Cp500', 'UnicodeBigUnmarked'
- * @param accessor
- * @param afpFontCfg
- * @return the created AFPFont
- * @throws ConfigurationException
- */
- private AFPFont fontFromType(String type, String codepage, String encoding,
- ResourceAccessor accessor, Configuration afpFontCfg) throws ConfigurationException,
- IOException {
-
- 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) {
- eventProducer.fontConfigMissing(this, "<afp-raster-font...",
- afpFontCfg.getLocation());
- return null;
- }
- for (int j = 0; j < rasters.length; j++) {
- Configuration rasterCfg = rasters[j];
-
- String characterset = rasterCfg.getAttribute("characterset");
-
- if (characterset == null) {
- eventProducer.fontConfigMissing(this, "characterset attribute",
- afpFontCfg.getLocation());
- return null;
- }
- float size = rasterCfg.getAttributeAsFloat("size");
- int sizeMpt = (int) (size * 1000);
- String base14 = rasterCfg.getAttribute("base14-font", null);
-
- if (base14 != null) {
- try {
- Class<? extends Typeface> clazz = Class.forName(
- "org.apache.fop.fonts.base14." + base14).asSubclass(Typeface.class);
- try {
- Typeface tf = clazz.newInstance();
- font.addCharacterSet(sizeMpt,
- CharacterSetBuilder.getSingleByteInstance()
- .build(characterset, codepage, encoding, tf,
- eventProducer));
- } 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(sizeMpt, CharacterSetBuilder.getSingleByteInstance()
- .buildSBCS(characterset, codepage, encoding, accessor, eventProducer));
- }
- }
- return font;
-
- } else if ("outline".equalsIgnoreCase(type)) {
- String characterset = afpFontCfg.getAttribute("characterset");
- if (characterset == null) {
- eventProducer.fontConfigMissing(this, "characterset attribute",
- afpFontCfg.getLocation());
- return null;
- }
- String name = afpFontCfg.getAttribute("name", characterset);
- CharacterSet characterSet = null;
- String base14 = afpFontCfg.getAttribute("base14-font", null);
- if (base14 != null) {
- try {
- Class<? extends Typeface> clazz = Class.forName("org.apache.fop.fonts.base14."
- + base14).asSubclass(Typeface.class);
- try {
- Typeface tf = clazz.newInstance();
- characterSet = CharacterSetBuilder.getSingleByteInstance()
- .build(characterset, codepage, encoding, tf, eventProducer);
- } 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);
- }
+ private void configure(AFPDocumentHandler documentHandler, AFPRendererConfig config) {
+ Boolean colorImages = config.isColorImages();
+ if (colorImages != null) {
+ documentHandler.setColorImages(colorImages);
+ if (colorImages) {
+ documentHandler.setCMYKImagesSupported(config.isCmykImagesSupported());
} else {
- characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
- characterset, codepage, encoding, accessor, eventProducer);
+ documentHandler.setBitsPerPixel(config.getBitsPerPixel());
}
- // Return new font object
- return new OutlineFont(name, characterSet);
-
- } else if ("CIDKeyed".equalsIgnoreCase(type)) {
- String characterset = afpFontCfg.getAttribute("characterset");
- if (characterset == null) {
- eventProducer.fontConfigMissing(this, "characterset attribute",
- afpFontCfg.getLocation());
- return null;
- }
- String name = afpFontCfg.getAttribute("name", characterset);
- CharacterSet characterSet = null;
- CharacterSetType charsetType = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false)
- ? CharacterSetType.DOUBLE_BYTE_LINE_DATA : CharacterSetType.DOUBLE_BYTE;
- characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset,
- codepage, encoding, charsetType, accessor, eventProducer);
-
- // Create a new font object
- DoubleByteFont font = new DoubleByteFont(name, characterSet);
- return font;
-
- } else {
- log.error("No or incorrect type attribute: " + type);
}
-
- return null;
- }
-
- /**
- * Builds a list of AFPFontInfo objects for use with the setup() method.
- *
- * @param cfg Configuration object
- * @param eventProducer for AFP font related events
- * @return List the newly created list of fonts
- * @throws ConfigurationException if something's wrong with the config data
- */
- private List<AFPFontInfo> buildFontListFromConfiguration(Configuration cfg,
- AFPEventProducer eventProducer) throws FOPException, ConfigurationException {
-
- Configuration fonts = cfg.getChild("fonts");
- FontManager fontManager = this.userAgent.getFactory().getFontManager();
-
- // General matcher
- FontTriplet.Matcher referencedFontsMatcher = fontManager.getReferencedFontsMatcher();
- // Renderer-specific matcher
- FontTriplet.Matcher localMatcher = null;
-
- // Renderer-specific referenced fonts
- Configuration referencedFontsCfg = fonts.getChild("referenced-fonts", false);
- if (referencedFontsCfg != null) {
- localMatcher = FontManagerConfigurator.createFontsMatcher(
- referencedFontsCfg, this.userAgent.getFactory().validateUserConfigStrictly());
+ if (config.getDitheringQuality() != null) {
+ documentHandler.setDitheringQuality(config.getDitheringQuality());
}
-
- List<AFPFontInfo> fontList = new java.util.ArrayList<AFPFontInfo>();
- Configuration[] font = fonts.getChildren("font");
- final String fontPath = null;
- for (int i = 0; i < font.length; i++) {
- AFPFontInfo afi = buildFont(font[i], fontPath);
- if (afi != null) {
- if (log.isDebugEnabled()) {
- log.debug("Adding font " + afi.getAFPFont().getFontName());
- }
- List<FontTriplet> fontTriplets = afi.getFontTriplets();
- for (int j = 0; j < fontTriplets.size(); ++j) {
- FontTriplet triplet = fontTriplets.get(j);
- if (log.isDebugEnabled()) {
- log.debug(" Font triplet "
- + triplet.getName() + ", "
- + triplet.getStyle() + ", "
- + triplet.getWeight());
- }
-
- if ((referencedFontsMatcher != null && referencedFontsMatcher.matches(triplet))
- || (localMatcher != null && localMatcher.matches(triplet))) {
- afi.getAFPFont().setEmbeddable(false);
- break;
- }
- }
-
- fontList.add(afi);
- }
+ if (config.isNativeImagesSupported() != null) {
+ documentHandler.setNativeImagesSupported(config.isNativeImagesSupported());
}
- return fontList;
- }
-
- /** images are converted to grayscale bitmapped IOCA */
- private static final String IMAGES_MODE_GRAYSCALE = "b+w";
-
- /** images are converted to color bitmapped IOCA */
- private static final String IMAGES_MODE_COLOR = "color";
-
- /**
- * Throws an UnsupportedOperationException.
- *
- * @param renderer not used
- */
- @Override
- public void configure(Renderer renderer) {
- throw new UnsupportedOperationException();
- }
-
- private void configure(AFPCustomizable customizable, Configuration cfg) throws FOPException {
-
- // image information
- Configuration imagesCfg = cfg.getChild("images");
-
- // default to grayscale images
- String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE);
- if (IMAGES_MODE_COLOR.equals(imagesMode)) {
- customizable.setColorImages(true);
-
- boolean cmyk = imagesCfg.getAttributeAsBoolean("cmyk", false);
- customizable.setCMYKImagesSupported(cmyk);
- } else {
- customizable.setColorImages(false);
- // default to 8 bits per pixel
- int bitsPerPixel = imagesCfg.getAttributeAsInteger("bits-per-pixel", 8);
- customizable.setBitsPerPixel(bitsPerPixel);
+ if (config.getShadingMode() != null) {
+ documentHandler.setShadingMode(config.getShadingMode());
}
-
- String dithering = imagesCfg.getAttribute("dithering-quality", "medium");
- float dq = 0.5f;
- if (dithering.startsWith("min")) {
- dq = 0.0f;
- } else if (dithering.startsWith("max")) {
- dq = 1.0f;
- } else {
- try {
- dq = Float.parseFloat(dithering);
- } catch (NumberFormatException nfe) {
- //ignore and leave the default above
- }
+ if (config.getResolution() != null) {
+ documentHandler.setResolution(config.getResolution());
}
- customizable.setDitheringQuality(dq);
-
- // native image support
- boolean nativeImageSupport = imagesCfg.getAttributeAsBoolean("native", false);
- customizable.setNativeImagesSupported(nativeImageSupport);
-
- Configuration jpegConfig = imagesCfg.getChild("jpeg");
- boolean allowEmbedding = false;
- float ieq = 1.0f;
- if (jpegConfig != null) {
- allowEmbedding = jpegConfig.getAttributeAsBoolean("allow-embedding", false);
- String bitmapEncodingQuality = jpegConfig.getAttribute("bitmap-encoding-quality", null);
-
- if (bitmapEncodingQuality != null) {
- try {
- ieq = Float.parseFloat(bitmapEncodingQuality);
- } catch (NumberFormatException nfe) {
- //ignore and leave the default above
- }
- }
+ if (config.isWrapPseg() != null) {
+ documentHandler.setWrapPSeg(config.isWrapPseg());
}
- customizable.canEmbedJpeg(allowEmbedding);
- customizable.setBitmapEncodingQuality(ieq);
-
- //FS11 and FS45 page segment wrapping
- boolean pSeg = imagesCfg.getAttributeAsBoolean("pseg", false);
- customizable.setWrapPSeg(pSeg);
-
- //FS45 image forcing
- boolean fs45 = imagesCfg.getAttributeAsBoolean("fs45", false);
- customizable.setFS45(fs45);
-
- // shading (filled rectangles)
- Configuration shadingCfg = cfg.getChild("shading");
- AFPShadingMode shadingMode = AFPShadingMode.valueOf(
- shadingCfg.getValue(AFPShadingMode.COLOR.getName()));
- customizable.setShadingMode(shadingMode);
-
- // GOCA Support
- Configuration gocaCfg = cfg.getChild("goca");
- boolean gocaEnabled = gocaCfg.getAttributeAsBoolean(
- "enabled", customizable.isGOCAEnabled());
- customizable.setGOCAEnabled(gocaEnabled);
- String gocaText = gocaCfg.getAttribute(
- "text", customizable.isStrokeGOCAText() ? "stroke" : "default");
- customizable.setStrokeGOCAText("stroke".equalsIgnoreCase(gocaText)
- || "shapes".equalsIgnoreCase(gocaText));
-
- // renderer resolution
- Configuration rendererResolutionCfg = cfg.getChild("renderer-resolution", false);
- if (rendererResolutionCfg != null) {
- customizable.setResolution(rendererResolutionCfg.getValueAsInteger(240));
+ if (config.isFs45() != null) {
+ documentHandler.setFS45(config.isFs45());
}
-
- // renderer resolution
- Configuration lineWidthCorrectionCfg = cfg.getChild("line-width-correction", false);
- if (lineWidthCorrectionCfg != null) {
- customizable.setLineWidthCorrection(lineWidthCorrectionCfg
- .getValueAsFloat(AFPConstants.LINE_WIDTH_CORRECTION));
+ if (config.allowJpegEmbedding() != null) {
+ documentHandler.canEmbedJpeg(config.allowJpegEmbedding());
}
-
- // a default external resource group file setting
- Configuration resourceGroupFileCfg
- = cfg.getChild("resource-group-file", false);
- if (resourceGroupFileCfg != null) {
- String resourceGroupDest = null;
- try {
- resourceGroupDest = resourceGroupFileCfg.getValue();
- if (resourceGroupDest != null) {
- File resourceGroupFile = new File(resourceGroupDest);
- boolean created = resourceGroupFile.createNewFile();
- if (created && resourceGroupFile.canWrite()) {
- customizable.setDefaultResourceGroupFilePath(resourceGroupDest);
- } else {
- log.warn("Unable to write to default external resource group file '"
- + resourceGroupDest + "'");
- }
- }
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e,
- userAgent.getFactory().validateUserConfigStrictly());
- } catch (IOException ioe) {
- throw new FOPException("Could not create default external resource group file"
- , ioe);
- }
+ if (config.getBitmapEncodingQuality() != null) {
+ documentHandler.setBitmapEncodingQuality(config.getBitmapEncodingQuality());
}
-
- Configuration defaultResourceLevelCfg = cfg.getChild("default-resource-levels", false);
- if (defaultResourceLevelCfg != null) {
- AFPResourceLevelDefaults defaults = new AFPResourceLevelDefaults();
- String[] types = defaultResourceLevelCfg.getAttributeNames();
- for (int i = 0, c = types.length; i < c; i++) {
- String type = types[i];
- try {
- String level = defaultResourceLevelCfg.getAttribute(type);
- defaults.setDefaultResourceLevel(type, AFPResourceLevel.valueOf(level));
- } catch (IllegalArgumentException iae) {
- LogUtil.handleException(log, iae,
- userAgent.getFactory().validateUserConfigStrictly());
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e,
- userAgent.getFactory().validateUserConfigStrictly());
- }
- }
- customizable.setResourceLevelDefaults(defaults);
+ if (config.getLineWidthCorrection() != null) {
+ documentHandler.setLineWidthCorrection(config.getLineWidthCorrection());
+ }
+ if (config.isGocaEnabled() != null) {
+ documentHandler.setGOCAEnabled(config.isGocaEnabled());
+ }
+ if (config.isStrokeGocaText() != null) {
+ documentHandler.setStrokeGOCAText(config.isStrokeGocaText());
+ }
+ if (config.getDefaultResourceGroupUri() != null) {
+ documentHandler.setDefaultResourceGroupUri(config.getDefaultResourceGroupUri());
+ }
+ AFPResourceLevelDefaults resourceLevelDefaults = config.getResourceLevelDefaults();
+ if (resourceLevelDefaults != null) {
+ documentHandler.setResourceLevelDefaults(resourceLevelDefaults);
}
}
- /** {@inheritDoc} */
@Override
- public void configure(IFDocumentHandler documentHandler) throws FOPException {
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler) documentHandler;
- configure(afpDocumentHandler, cfg);
- }
+ protected List<FontCollection> getDefaultFontCollection() {
+ return new ArrayList<FontCollection>();
}
- /** {@inheritDoc} */
@Override
- public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
- throws FOPException {
- FontManager fontManager = userAgent.getFactory().getFontManager();
- List<AFPFontCollection> fontCollections = new ArrayList<AFPFontCollection>();
-
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
+ protected FontCollection getCustomFontCollection(InternalResourceResolver uriResolverWrapper,
+ String mimeType) throws FOPException {
+ AFPRendererConfig config = (AFPRendererConfig) getRendererConfig(mimeType);
+ if (config != null) {
try {
- List<AFPFontInfo> fontList = buildFontListFromConfiguration(cfg, eventProducer);
- fontCollections.add(new AFPFontCollection(
- userAgent.getEventBroadcaster(), fontList));
- } catch (ConfigurationException e) {
+ return new AFPFontCollection(userAgent.getEventBroadcaster(), createFontsList(
+ config.getFontInfoConfig(), mimeType));
+ } catch (IOException e) {
eventProducer.invalidConfiguration(this, e);
- LogUtil.handleException(log, e,
- userAgent.getFactory().validateUserConfigStrictly());
+ LogUtil.handleException(log, e, userAgent.validateUserConfigStrictly());
+ } catch (IllegalArgumentException iae) {
+ eventProducer.invalidConfiguration(this, iae);
+ LogUtil.handleException(log, iae, userAgent.validateUserConfigStrictly());
}
- } else {
- fontCollections.add(new AFPFontCollection(userAgent.getEventBroadcaster(), null));
}
+ return new AFPFontCollection(userAgent.getEventBroadcaster(), null);
+ }
- fontManager.setup(fontInfo,
- fontCollections.toArray(
- new FontCollection[fontCollections.size()]));
- documentHandler.setFontInfo(fontInfo);
+ private List<AFPFontInfo> createFontsList(AFPFontConfig fontConfig, String mimeType)
+ throws FOPException, IOException {
+ List<AFPFontInfo> afpFonts = new ArrayList<AFPFontInfo>();
+ for (AFPFontConfigData config : fontConfig.getFontConfig()) {
+ afpFonts.add(config.getFontInfo(userAgent.getFontManager().getResourceResolver(),
+ eventProducer));
+ }
+ return afpFonts;
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererOption.java b/src/java/org/apache/fop/render/afp/AFPRendererOption.java
new file mode 100644
index 000000000..d573570d0
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/AFPRendererOption.java
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.afp;
+
+import java.net.URI;
+
+import org.apache.fop.afp.AFPResourceLevelDefaults;
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * An enumeration of the configuration options available for the AFP renderer.
+ */
+public enum AFPRendererOption implements RendererConfigOption {
+ DEFAULT_RESOURCE_LEVELS("default-resource-levels", AFPResourceLevelDefaults.class),
+ IMAGES("images", null),
+ IMAGES_JPEG("jpeg", null),
+ IMAGES_DITHERING_QUALITY("dithering-quality", Float.class),
+ IMAGES_FS45("fs45", Boolean.class),
+ IMAGES_MAPPING_OPTION("mapping_option", Byte.class),
+ IMAGES_MODE("mode", Boolean.class),
+ IMAGES_NATIVE("native", Boolean.class),
+ IMAGES_WRAP_PSEG("pseg", Boolean.class),
+ JPEG_ALLOW_JPEG_EMBEDDING("allow-embedding", Boolean.class),
+ JPEG_BITMAP_ENCODING_QUALITY("bitmap-encoding-quality", Float.class),
+ RENDERER_RESOLUTION("renderer-resolution", Integer.class),
+ RESOURCE_GROUP_URI("resource-group-file", URI.class),
+ SHADING("shading", AFPShadingMode.class),
+ LINE_WIDTH_CORRECTION("line-width-correction", Float.class),
+ GOCA("goca", Boolean.class),
+ GOCA_TEXT("text", Boolean.class);
+
+ private final String name;
+
+ private final Class<?> type;
+
+ private AFPRendererOption(String name, Class<?> type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ /** {@inheritDoc}}*/
+ public String getName() {
+ return name;
+ }
+
+ public Class<?> getType() {
+ return type;
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
index 48b82bbf3..b73e22d89 100644
--- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
@@ -195,7 +195,7 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
* @return a bridge context
*/
public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) {
- ImageManager imageManager = userAgent.getFactory().getImageManager();
+ ImageManager imageManager = userAgent.getImageManager();
SVGUserAgent svgUserAgent
= new SVGUserAgent(userAgent, new AffineTransform());
diff --git a/src/java/org/apache/fop/render/afp/AFPShadingMode.java b/src/java/org/apache/fop/render/afp/AFPShadingMode.java
index b45c33a8e..7e963148a 100644
--- a/src/java/org/apache/fop/render/afp/AFPShadingMode.java
+++ b/src/java/org/apache/fop/render/afp/AFPShadingMode.java
@@ -20,17 +20,13 @@
package org.apache.fop.render.afp;
import java.io.ObjectStreamException;
-import java.io.Serializable;
-
-/** Enumeration class for the AFP shading mode. */
-public final class AFPShadingMode implements Serializable {
-
- private static final long serialVersionUID = 8579867898716480779L;
+/** Enumeration of the AFP shading modes. */
+public enum AFPShadingMode {
/** the color mode (the default) */
- public static final AFPShadingMode COLOR = new AFPShadingMode("COLOR");
+ COLOR("COLOR"),
/** the dithered mode */
- public static final AFPShadingMode DITHERED = new AFPShadingMode("DITHERED");
+ DITHERED("DITHERED");
private String name;
@@ -52,7 +48,7 @@ public final class AFPShadingMode implements Serializable {
* @param name the name of the enumeration value
* @return the enumeration object
*/
- public static AFPShadingMode valueOf(String name) {
+ public static AFPShadingMode getValueOf(String name) {
if (COLOR.getName().equalsIgnoreCase(name)) {
return COLOR;
} else if (DITHERED.getName().equalsIgnoreCase(name)) {
@@ -70,5 +66,4 @@ public final class AFPShadingMode implements Serializable {
public String toString() {
return getClass().getName() + ":" + name;
}
-
}
diff --git a/src/java/org/apache/fop/render/awt/AWTRenderer.java b/src/java/org/apache/fop/render/awt/AWTRenderer.java
index 826dde233..0651975fd 100644
--- a/src/java/org/apache/fop/render/awt/AWTRenderer.java
+++ b/src/java/org/apache/fop/render/awt/AWTRenderer.java
@@ -41,7 +41,7 @@ import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.FopFactoryConfigurator;
+import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.area.Area;
import org.apache.fop.area.PageViewport;
@@ -131,13 +131,13 @@ public class AWTRenderer extends Java2DRenderer implements Pageable {
pageWidth = (int) Math.round(bounds.getWidth() / 1000f);
pageHeight = (int) Math.round(bounds.getHeight() / 1000f);
double scaleX = scaleFactor
- * (UnitConv.IN2MM / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+ * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION)
/ userAgent.getTargetPixelUnitToMillimeter();
double scaleY = scaleFactor
- * (UnitConv.IN2MM / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+ * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION)
/ userAgent.getTargetPixelUnitToMillimeter();
if (getPageViewport(pageNum).getForeignAttributes() != null) {
- String scale = (String) getPageViewport(pageNum).getForeignAttributes().get(
+ String scale = getPageViewport(pageNum).getForeignAttributes().get(
PageScale.EXT_PAGE_SCALE);
Point2D scales = PageScale.getScale(scale);
if (scales != null) {
diff --git a/src/java/org/apache/fop/render/awt/AWTRendererMaker.java b/src/java/org/apache/fop/render/awt/AWTRendererMaker.java
index d65a550d4..5efa49a99 100644
--- a/src/java/org/apache/fop/render/awt/AWTRendererMaker.java
+++ b/src/java/org/apache/fop/render/awt/AWTRendererMaker.java
@@ -31,20 +31,23 @@ public class AWTRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_AWT_PREVIEW};
-
- /** {@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent ua) {
return new AWTRenderer(ua);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return false;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) {
+ // No-Op
+ }
}
diff --git a/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
index 0c6ebde56..262caa53b 100644
--- a/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
@@ -36,7 +36,7 @@ import org.apache.xmlgraphics.image.writer.ImageWriter;
import org.apache.xmlgraphics.image.writer.ImageWriterRegistry;
import org.apache.xmlgraphics.image.writer.MultiImageWriter;
-import org.apache.fop.apps.FopFactoryConfigurator;
+import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFContext;
@@ -80,7 +80,14 @@ public abstract class AbstractBitmapDocumentHandler extends AbstractBinaryWritin
/**
* Default constructor.
*/
- public AbstractBitmapDocumentHandler() {
+ public AbstractBitmapDocumentHandler(IFContext context) {
+ super(context);
+ //Set target resolution
+ int dpi = Math.round(context.getUserAgent().getTargetResolution());
+ getSettings().getWriterParams().setResolution(dpi);
+
+ Map renderingOptions = getUserAgent().getRendererOptions();
+ setTargetBitmapSize((Dimension)renderingOptions.get(TARGET_BITMAP_SIZE));
}
/** {@inheritDoc} */
@@ -98,18 +105,6 @@ public abstract class AbstractBitmapDocumentHandler extends AbstractBinaryWritin
public abstract String getDefaultExtension();
/** {@inheritDoc} */
- public void setContext(IFContext context) {
- super.setContext(context);
-
- //Set target resolution
- int dpi = Math.round(context.getUserAgent().getTargetResolution());
- getSettings().getWriterParams().setResolution(dpi);
-
- Map renderingOptions = getUserAgent().getRendererOptions();
- setTargetBitmapSize((Dimension)renderingOptions.get(TARGET_BITMAP_SIZE));
- }
-
- /** {@inheritDoc} */
public abstract IFDocumentHandlerConfigurator getConfigurator();
/**
@@ -228,7 +223,7 @@ public abstract class AbstractBitmapDocumentHandler extends AbstractBinaryWritin
//Normal case: just scale according to the target resolution
scale = scaleFactor
* getUserAgent().getTargetResolution()
- / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+ / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
bitmapWidth = (int) ((this.currentPageDimensions.width * scale / 1000f) + 0.5f);
bitmapHeight = (int) ((this.currentPageDimensions.height * scale / 1000f) + 0.5f);
}
diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java
new file mode 100644
index 000000000..828f41d34
--- /dev/null
+++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfig.java
@@ -0,0 +1,178 @@
+/*
+ * 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.Color;
+import java.awt.image.BufferedImage;
+import java.util.EnumMap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.java2d.Java2DRendererConfig;
+import org.apache.fop.render.java2d.Java2DRendererConfig.Java2DRendererConfigParser;
+import org.apache.fop.util.ColorUtil;
+
+import static org.apache.fop.render.bitmap.BitmapRendererOption.ANTI_ALIASING;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.BACKGROUND_COLOR;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY_ELEMENT;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_SPEED;
+
+/**
+ * The Bitmap renderer config data object.
+ */
+public class BitmapRendererConfig implements RendererConfig {
+
+ private final EnumMap<BitmapRendererOption, Object> params
+ = new EnumMap<BitmapRendererOption, Object>(BitmapRendererOption.class);
+
+ private final DefaultFontConfig fontConfig;
+
+ BitmapRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public Color getBackgroundColor() {
+ return (Color) get(BACKGROUND_COLOR);
+ }
+
+ public Boolean hasAntiAliasing() {
+ return (Boolean) get(ANTI_ALIASING);
+ }
+
+ public Boolean isRenderHighQuality() {
+ return (Boolean) get(RENDERING_QUALITY);
+ }
+
+ public Integer getColorMode() {
+ return (Integer) get(COLOR_MODE);
+ }
+
+ public boolean hasTransparentBackround() {
+ Object result = get(JAVA2D_TRANSPARENT_PAGE_BACKGROUND);
+ return (Boolean) (result != null ? result
+ : JAVA2D_TRANSPARENT_PAGE_BACKGROUND.getDefaultValue());
+ }
+
+ private Object get(BitmapRendererOption option) {
+ return params.get(option);
+ }
+
+ /**
+ * The parser for the Bitmap renderer configuration data.
+ */
+ public static class BitmapRendererConfigParser implements RendererConfigParser {
+
+ private final String mimeType;
+
+ public BitmapRendererConfigParser(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ private void setParam(BitmapRendererConfig config, BitmapRendererOption option,
+ Object value) {
+ config.params.put(option, value != null ? value : option.getDefaultValue());
+ }
+
+ void build(BitmapRendererConfig config, FOUserAgent userAgent,
+ Configuration cfg) throws FOPException {
+ if (cfg != null) {
+ Java2DRendererConfig j2dConfig = new Java2DRendererConfigParser(null).build(
+ userAgent, cfg);
+ Boolean isTransparent = j2dConfig.isPageBackgroundTransparent();
+ isTransparent = isTransparent == null
+ ? (Boolean) JAVA2D_TRANSPARENT_PAGE_BACKGROUND.getDefaultValue()
+ : isTransparent;
+ setParam(config, JAVA2D_TRANSPARENT_PAGE_BACKGROUND, isTransparent);
+
+ String background = getValue(cfg, BACKGROUND_COLOR);
+ if (isTransparent) {
+ // We don't use setParam here because we want to force a null value
+ config.params.put(BACKGROUND_COLOR, null);
+ } else {
+ setParam(config, BACKGROUND_COLOR,
+ ColorUtil.parseColorString(userAgent, background));
+ }
+
+ setParam(config, BitmapRendererOption.ANTI_ALIASING,
+ getChild(cfg, ANTI_ALIASING).getValueAsBoolean(
+ (Boolean) ANTI_ALIASING.getDefaultValue()));
+
+ String optimization = getValue(cfg, RENDERING_QUALITY_ELEMENT);
+ setParam(config, RENDERING_QUALITY,
+ !(BitmapRendererOption.getValue(optimization) == RENDERING_SPEED));
+
+ String color = getValue(cfg, COLOR_MODE);
+ setParam(config, COLOR_MODE,
+ getBufferedImageIntegerFromColor(BitmapRendererOption.getValue(color)));
+ }
+ }
+
+ public BitmapRendererConfig build(FOUserAgent userAgent, Configuration cfg)
+ throws FOPException {
+ BitmapRendererConfig config = new BitmapRendererConfig(new DefaultFontConfigParser()
+ .parse(cfg, userAgent.validateStrictly()));
+ build(config, userAgent, cfg);
+ return config;
+ }
+
+ private Integer getBufferedImageIntegerFromColor(BitmapRendererOption option) {
+ if (option == null) {
+ return null;
+ }
+ switch (option) {
+ case COLOR_MODE_RGBA:
+ return BufferedImage.TYPE_INT_ARGB;
+ case COLOR_MODE_RGB:
+ return BufferedImage.TYPE_INT_RGB;
+ case COLOR_MODE_GRAY:
+ return BufferedImage.TYPE_BYTE_GRAY;
+ case COLOR_MODE_BINARY:
+ case COLOR_MODE_BILEVEL:
+ return BufferedImage.TYPE_BYTE_BINARY;
+ default:
+ return null;
+ }
+ }
+
+ private Configuration getChild(Configuration cfg, BitmapRendererOption option) {
+ return cfg.getChild(option.getName());
+ }
+
+ private String getValue(Configuration cfg, BitmapRendererOption option) {
+ return cfg.getChild(option.getName()).getValue(null);
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java
index 2ca0a172b..f0e32a9d7 100644
--- a/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererConfigurator.java
@@ -19,123 +19,84 @@
package org.apache.fop.render.bitmap;
-import java.awt.image.BufferedImage;
+import java.util.ArrayList;
import java.util.List;
-import org.apache.avalon.framework.configuration.Configuration;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontCollection;
-import org.apache.fop.fonts.FontEventAdapter;
-import org.apache.fop.fonts.FontEventListener;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontResolver;
-import org.apache.fop.render.DefaultFontResolver;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
+import org.apache.fop.render.bitmap.BitmapRendererConfig.BitmapRendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
-import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.java2d.Base14FontCollection;
import org.apache.fop.render.java2d.ConfiguredFontCollection;
import org.apache.fop.render.java2d.InstalledFontCollection;
import org.apache.fop.render.java2d.Java2DFontMetrics;
-import org.apache.fop.render.java2d.Java2DRenderer;
import org.apache.fop.render.java2d.Java2DRendererConfigurator;
-import org.apache.fop.util.ColorUtil;
/**
* Configurator for bitmap output.
*/
-public class BitmapRendererConfigurator extends Java2DRendererConfigurator
- implements IFDocumentHandlerConfigurator {
+public class BitmapRendererConfigurator extends Java2DRendererConfigurator {
/**
* Default constructor
* @param userAgent user agent
*/
- public BitmapRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public BitmapRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
// ---=== IFDocumentHandler configuration ===---
/** {@inheritDoc} */
public void configure(IFDocumentHandler documentHandler) throws FOPException {
- super.configure(documentHandler);
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- AbstractBitmapDocumentHandler bitmapHandler
- = (AbstractBitmapDocumentHandler)documentHandler;
- BitmapRenderingSettings settings = bitmapHandler.getSettings();
-
- boolean transparent = cfg.getChild(
- Java2DRenderer.JAVA2D_TRANSPARENT_PAGE_BACKGROUND).getValueAsBoolean(
- settings.hasTransparentPageBackground());
- if (transparent) {
- settings.setPageBackgroundColor(null);
- } else {
- String background = cfg.getChild("background-color").getValue(null);
- if (background != null) {
- settings.setPageBackgroundColor(
- ColorUtil.parseColorString(this.userAgent, background));
- }
- }
-
- boolean antiAliasing = cfg.getChild("anti-aliasing").getValueAsBoolean(
- settings.isAntiAliasingEnabled());
- settings.setAntiAliasing(antiAliasing);
-
- String optimization = cfg.getChild("rendering").getValue(null);
- if ("quality".equalsIgnoreCase(optimization)) {
- settings.setQualityRendering(true);
- } else if ("speed".equalsIgnoreCase(optimization)) {
- settings.setQualityRendering(false);
- }
+ AbstractBitmapDocumentHandler bitmapHandler = (AbstractBitmapDocumentHandler) documentHandler;
+ BitmapRenderingSettings settings = bitmapHandler.getSettings();
+ configure(documentHandler, settings,
+ new BitmapRendererConfigParser(MimeConstants.MIME_BITMAP));
+ }
- String color = cfg.getChild("color-mode").getValue(null);
- if (color != null) {
- if ("rgba".equalsIgnoreCase(color)) {
- settings.setBufferedImageType(BufferedImage.TYPE_INT_ARGB);
- } else if ("rgb".equalsIgnoreCase(color)) {
- settings.setBufferedImageType(BufferedImage.TYPE_INT_RGB);
- } else if ("gray".equalsIgnoreCase(color)) {
- settings.setBufferedImageType(BufferedImage.TYPE_BYTE_GRAY);
- } else if ("binary".equalsIgnoreCase(color)) {
- settings.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
- } else if ("bi-level".equalsIgnoreCase(color)) {
- settings.setBufferedImageType(BufferedImage.TYPE_BYTE_BINARY);
- } else {
- throw new FOPException("Invalid value for color-mode: " + color);
- }
- }
- }
+ void configure(IFDocumentHandler documentHandler, BitmapRenderingSettings settings,
+ BitmapRendererConfigParser parser) throws FOPException {
+ BitmapRendererConfig config = (BitmapRendererConfig) userAgent.getRendererConfig(
+ documentHandler.getMimeType(), parser);
+ configure(config, settings);
}
- /** {@inheritDoc} */
- public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
+ private void configure(BitmapRendererConfig config, BitmapRenderingSettings settings)
throws FOPException {
- final FontManager fontManager = userAgent.getFactory().getFontManager();
-
- final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
-
- final List fontCollections = new java.util.ArrayList();
- fontCollections.add(new Base14FontCollection(java2DFontMetrics));
- fontCollections.add(new InstalledFontCollection(java2DFontMetrics));
-
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- FontResolver fontResolver = new DefaultFontResolver(userAgent);
- FontEventListener listener = new FontEventAdapter(
- userAgent.getEventBroadcaster());
- List fontList = buildFontList(cfg, fontResolver, listener);
- fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList,
- userAgent.isComplexScriptFeaturesEnabled()));
+ if (config.hasTransparentBackround()) {
+ settings.setPageBackgroundColor(null);
+ } else if (config.getBackgroundColor() != null) {
+ settings.setPageBackgroundColor(config.getBackgroundColor());
+ }
+ if (config.hasAntiAliasing() != null) {
+ settings.setAntiAliasing(config.hasAntiAliasing());
+ }
+ if (config.isRenderHighQuality() != null) {
+ settings.setQualityRendering(config.isRenderHighQuality());
}
+ if (config.getColorMode() != null) {
+ settings.setBufferedImageType(config.getColorMode());
+ }
+ }
- fontManager.setup(fontInfo,
- (FontCollection[])fontCollections.toArray(
- new FontCollection[fontCollections.size()]));
- documentHandler.setFontInfo(fontInfo);
+ @Override
+ protected FontCollection createCollectionFromFontList(InternalResourceResolver resourceResolver,
+ List<EmbedFontInfo> fontList) {
+ return new ConfiguredFontCollection(resourceResolver, fontList, userAgent.isComplexScriptFeaturesEnabled());
}
+ @Override
+ protected List<FontCollection> getDefaultFontCollection() {
+ final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
+ final List<FontCollection> fontCollection = new ArrayList<FontCollection>();
+ fontCollection.add(new Base14FontCollection(java2DFontMetrics));
+ fontCollection.add(new InstalledFontCollection(java2DFontMetrics));
+ return fontCollection;
+ }
}
diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRendererOption.java b/src/java/org/apache/fop/render/bitmap/BitmapRendererOption.java
new file mode 100644
index 000000000..d6030b5ac
--- /dev/null
+++ b/src/java/org/apache/fop/render/bitmap/BitmapRendererOption.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.bitmap;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * An enumeration of the Bitmap renderer configuration opetions available to the user via the FOP
+ * conf.
+ */
+public enum BitmapRendererOption implements RendererConfigOption {
+ JAVA2D_TRANSPARENT_PAGE_BACKGROUND("transparent-page-background", false),
+ BACKGROUND_COLOR("background-color", Color.WHITE),
+ ANTI_ALIASING("anti-aliasing", true),
+ RENDERING_QUALITY_ELEMENT("rendering"),
+ RENDERING_QUALITY("quality", true),
+ RENDERING_SPEED("speed"),
+ COLOR_MODE("color-mode", BufferedImage.TYPE_INT_ARGB),
+ COLOR_MODE_RGBA("rgba"),
+ COLOR_MODE_RGB("rgb"),
+ COLOR_MODE_GRAY("gray"),
+ COLOR_MODE_BINARY("binary"),
+ COLOR_MODE_BILEVEL("bi-level");
+
+ private final String name;
+ private final Object defaultValue;
+
+ private BitmapRendererOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ private BitmapRendererOption(String name) {
+ this(name, null);
+ }
+
+ /** {@inheritDoc} */
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
+ public static BitmapRendererOption getValue(String str) {
+ for (BitmapRendererOption opt : BitmapRendererOption.values()) {
+ if (opt.getName().equalsIgnoreCase(str)) {
+ return opt;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/java/org/apache/fop/render/bitmap/BitmapRenderingSettings.java b/src/java/org/apache/fop/render/bitmap/BitmapRenderingSettings.java
index 278cd6c48..d239fe0fd 100644
--- a/src/java/org/apache/fop/render/bitmap/BitmapRenderingSettings.java
+++ b/src/java/org/apache/fop/render/bitmap/BitmapRenderingSettings.java
@@ -19,28 +19,30 @@
package org.apache.fop.render.bitmap;
-import java.awt.image.BufferedImage;
-
import org.apache.xmlgraphics.image.writer.ImageWriterParams;
import org.apache.fop.render.java2d.Java2DRenderingSettings;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.ANTI_ALIASING;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE;
+import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY;
+
/**
* This class holds settings used when rendering to bitmaps.
*/
-public class BitmapRenderingSettings extends Java2DRenderingSettings implements TIFFConstants {
+public class BitmapRenderingSettings extends Java2DRenderingSettings {
/** ImageWriter parameters */
private ImageWriterParams writerParams;
/** Image Type as parameter for the BufferedImage constructor (see BufferedImage.TYPE_*) */
- private int bufferedImageType = BufferedImage.TYPE_INT_ARGB;
+ private int bufferedImageType = (Integer) COLOR_MODE.getDefaultValue();
/** true if anti-aliasing is set */
- private boolean antialiasing = true;
+ private boolean antialiasing = (Boolean) ANTI_ALIASING.getDefaultValue();
/** true if qualityRendering is set */
- private boolean qualityRendering = true;
+ private boolean qualityRendering = (Boolean) RENDERING_QUALITY.getDefaultValue();
/**
* Default constructor. Initializes the settings to their default values.
diff --git a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
index ed92b852f..c63cd3a4d 100644
--- a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
@@ -20,6 +20,8 @@
package org.apache.fop.render.bitmap;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.bitmap.PNGRendererConfig.PNGRendererConfigParser;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
/**
@@ -28,6 +30,11 @@ import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
*/
public class PNGDocumentHandler extends AbstractBitmapDocumentHandler {
+
+ PNGDocumentHandler(IFContext context) {
+ super(context);
+ }
+
/** {@inheritDoc} */
public String getMimeType() {
return MimeConstants.MIME_PNG;
@@ -40,7 +47,7 @@ public class PNGDocumentHandler extends AbstractBitmapDocumentHandler {
/** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new BitmapRendererConfigurator(getUserAgent());
+ return new BitmapRendererConfigurator(getUserAgent(), new PNGRendererConfigParser());
}
}
diff --git a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandlerMaker.java b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandlerMaker.java
index d5a299528..7f820f71e 100644
--- a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.bitmap;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
@@ -33,10 +32,8 @@ public class PNGDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PNG};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- PNGDocumentHandler handler = new PNGDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new PNGDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java b/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java
new file mode 100644
index 000000000..699faea51
--- /dev/null
+++ b/src/java/org/apache/fop/render/bitmap/PNGRendererConfig.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.bitmap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.xmlgraphics.util.MimeConstants;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+
+/**
+ * The PNG renderer configuration data object.
+ */
+public final class PNGRendererConfig extends BitmapRendererConfig {
+
+ private PNGRendererConfig(DefaultFontConfig fontConfig) {
+ super(fontConfig);
+ }
+
+ /**
+ * The PNG renderer configuration parser.
+ */
+ public static class PNGRendererConfigParser implements RendererConfigParser {
+
+ public PNGRendererConfig build(FOUserAgent userAgent, Configuration cfg)
+ throws FOPException {
+ return new PNGRendererConfig(new DefaultFontConfigParser().parse(cfg,
+ userAgent.validateStrictly()));
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_PNG;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/bitmap/PNGRendererMaker.java b/src/java/org/apache/fop/render/bitmap/PNGRendererMaker.java
index da19b2986..fb38b61f6 100644
--- a/src/java/org/apache/fop/render/bitmap/PNGRendererMaker.java
+++ b/src/java/org/apache/fop/render/bitmap/PNGRendererMaker.java
@@ -19,11 +19,12 @@
package org.apache.fop.render.bitmap;
+import org.apache.fop.apps.FOPException;
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;
+import org.apache.fop.render.bitmap.PNGRendererConfig.PNGRendererConfigParser;
import org.apache.fop.render.java2d.Java2DRendererConfigurator;
/**
@@ -33,23 +34,22 @@ public class PNGRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PNG};
-
- /** {@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent ua) {
return new PNGRenderer(ua);
}
- /** {@inheritDoc} */
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return new Java2DRendererConfigurator(userAgent);
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ new Java2DRendererConfigurator(userAgent, new PNGRendererConfigParser()).configure(renderer);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFConstants.java b/src/java/org/apache/fop/render/bitmap/TIFFCompressionValues.java
index 437cf536a..71649022e 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFConstants.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFCompressionValues.java
@@ -19,31 +19,43 @@
package org.apache.fop.render.bitmap;
-import org.apache.fop.apps.MimeConstants;
-
/**
* Constants for TIFF output.
*/
-public interface TIFFConstants {
-
- /** The MIME type for tiff-Rendering */
- String MIME_TYPE = MimeConstants.MIME_TIFF;
-
+public enum TIFFCompressionValues {
/** No compression */
- String COMPRESSION_NONE = "NONE";
+ NONE("NONE"),
/** JPEG compression */
- String COMPRESSION_JPEG = "JPEG";
+ JPEG("JPEG"),
/** Packbits (RLE) compression */
- String COMPRESSION_PACKBITS = "PackBits";
+ PACKBITS("PackBits"),
/** Deflate compression */
- String COMPRESSION_DEFLATE = "Deflate";
+ DEFLATE("Deflate"),
/** LZW compression */
- String COMPRESSION_LZW = "LZW";
+ LZW("LZW"),
/** ZLib compression */
- String COMPRESSION_ZLIB = "ZLib";
+ ZLIB("ZLib"),
/** CCITT Group 4 (T.6) compression */
- String COMPRESSION_CCITT_T6 = "CCITT T.6"; //CCITT Group 4
+ CCITT_T6("CCITT T.6"), //CCITT Group 4
/** CCITT Group 3 (T.4) compression */
- String COMPRESSION_CCITT_T4 = "CCITT T.4"; //CCITT Group 3
+ CCITT_T4("CCITT T.4"); //CCITT Group 3
+
+ private final String name;
+
+ private TIFFCompressionValues(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public static TIFFCompressionValues getValue(String name) {
+ for (TIFFCompressionValues tiffConst : TIFFCompressionValues.values()) {
+ if (tiffConst.name.equalsIgnoreCase(name)) {
+ return tiffConst;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
index 1c9a39bbe..48e79520f 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
@@ -20,6 +20,8 @@
package org.apache.fop.render.bitmap;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
/**
@@ -28,11 +30,16 @@ import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
*/
public class TIFFDocumentHandler extends AbstractBitmapDocumentHandler {
+ TIFFDocumentHandler(IFContext context) {
+ super(context);
+ }
+
/** {@inheritDoc} */
public String getMimeType() {
return MimeConstants.MIME_TIFF;
}
+
/** {@inheritDoc} */
public String getDefaultExtension() {
return "tif";
@@ -40,7 +47,6 @@ public class TIFFDocumentHandler extends AbstractBitmapDocumentHandler {
/** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new TIFFRendererConfigurator(getUserAgent());
+ return new TIFFRendererConfigurator(getUserAgent(), new TIFFRendererConfigParser());
}
-
}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandlerMaker.java b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandlerMaker.java
index b14ba3c18..ab8c7306a 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.bitmap;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
@@ -33,10 +32,8 @@ public class TIFFDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_TIFF};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- TIFFDocumentHandler handler = new TIFFDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new TIFFDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
index 3cdcf2cdc..5b75a372c 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRenderer.java
@@ -44,8 +44,13 @@ import org.apache.xmlgraphics.image.writer.MultiImageWriter;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.java2d.Java2DRenderer;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T4;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T6;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.PACKBITS;
+
/**
* <p>
* This class represents renderer to TIFF (Tagged Image File Format) format. It
@@ -67,7 +72,7 @@ import org.apache.fop.render.java2d.Java2DRenderer;
* <code>org.apache.fop.render.java2D.Java2DRenderer</code> and just encode
* rendering results into TIFF format using Batik's image codec
*/
-public class TIFFRenderer extends Java2DRenderer implements TIFFConstants {
+public class TIFFRenderer extends Java2DRenderer {
/** ImageWriter parameters */
private ImageWriterParams writerParams;
@@ -79,7 +84,7 @@ public class TIFFRenderer extends Java2DRenderer implements TIFFConstants {
/** {@inheritDoc} */
public String getMimeType() {
- return MIME_TYPE;
+ return MimeConstants.MIME_TIFF;
}
/**
@@ -90,7 +95,7 @@ public class TIFFRenderer extends Java2DRenderer implements TIFFConstants {
public TIFFRenderer(FOUserAgent userAgent) {
super(userAgent);
writerParams = new ImageWriterParams();
- writerParams.setCompressionMethod(COMPRESSION_PACKBITS);
+ writerParams.setCompressionMethod(PACKBITS.getName());
int dpi = Math.round(userAgent.getTargetResolution());
writerParams.setResolution(dpi);
@@ -190,8 +195,8 @@ public class TIFFRenderer extends Java2DRenderer implements TIFFConstants {
throw new NoSuchElementException(e.getMessage());
}
- if (COMPRESSION_CCITT_T4.equalsIgnoreCase(writerParams.getCompressionMethod())
- || COMPRESSION_CCITT_T6.equalsIgnoreCase(writerParams.getCompressionMethod())) {
+ TIFFCompressionValues compression = TIFFCompressionValues.getValue(writerParams.getCompressionMethod());
+ if (compression == CCITT_T4 || compression == CCITT_T6) {
return pageImage;
} else {
//Decorate the image with a packed sample model for encoding by the codec
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java
new file mode 100644
index 000000000..5417ecc1e
--- /dev/null
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfig.java
@@ -0,0 +1,102 @@
+/*
+ * 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.util.EnumMap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.xmlgraphics.util.MimeConstants;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * The renderer configuration object for the TIFF renderer.
+ */
+public final class TIFFRendererConfig extends BitmapRendererConfig {
+
+ public enum TIFFRendererOption implements RendererConfigOption {
+ COMPRESSION("compression", TIFFCompressionValues.PACKBITS);
+
+ private final String name;
+ private final Object defaultValue;
+
+ private TIFFRendererOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+ }
+
+ private final EnumMap<TIFFRendererOption, Object> params
+ = new EnumMap<TIFFRendererOption, Object>(TIFFRendererOption.class);
+
+ private TIFFRendererConfig(DefaultFontConfig fontConfig) {
+ super(fontConfig);
+ }
+
+ public TIFFCompressionValues getCompressionType() {
+ return (TIFFCompressionValues) params.get(TIFFRendererOption.COMPRESSION);
+ }
+
+ /**
+ * The TIFF renderer configuration parser.
+ */
+ public static final class TIFFRendererConfigParser extends BitmapRendererConfigParser {
+
+ public TIFFRendererConfigParser() {
+ super(MimeConstants.MIME_TIFF);
+ }
+
+ private TIFFRendererConfig config;
+
+ private void setParam(TIFFRendererOption option, Object value) {
+ config.params.put(option, value != null ? value : option.getDefaultValue());
+ }
+
+ private String getValue(Configuration cfg, TIFFRendererOption option) {
+ return cfg.getChild(option.getName()).getValue(null);
+ }
+
+ /** {@inheritDoc} */
+ public TIFFRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ config = new TIFFRendererConfig(new DefaultFontConfigParser()
+ .parse(cfg, userAgent.validateStrictly()));
+ super.build(config, userAgent, cfg);
+ if (cfg != null) {
+ setParam(TIFFRendererOption.COMPRESSION,
+ TIFFCompressionValues.getValue(getValue(cfg,
+ TIFFRendererOption.COMPRESSION)));
+ }
+ return config;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java
index f78605a15..b10f2a381 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRendererConfigurator.java
@@ -21,24 +21,34 @@ package org.apache.fop.render.bitmap;
import java.awt.image.BufferedImage;
-import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.image.writer.ImageWriterParams;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
+import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T4;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.CCITT_T6;
+import static org.apache.fop.render.bitmap.TIFFCompressionValues.NONE;
+
/**
* TIFF Renderer configurator
*/
public class TIFFRendererConfigurator extends BitmapRendererConfigurator {
+ private static final Log LOG = LogFactory.getLog(TIFFRendererConfigurator.class);
/**
* Default constructor
* @param userAgent user agent
*/
- public TIFFRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public TIFFRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
/**
@@ -49,58 +59,46 @@ public class TIFFRendererConfigurator extends BitmapRendererConfigurator {
* {@inheritDoc}
*/
public void configure(Renderer renderer) throws FOPException {
- Configuration cfg = super.getRendererConfig(renderer);
- if (cfg != null) {
- TIFFRenderer tiffRenderer = (TIFFRenderer)renderer;
+ final TIFFRendererConfig config = (TIFFRendererConfig) getRendererConfig(renderer);
+ if (config != null) {
+ TIFFRenderer tiffRenderer = (TIFFRenderer) renderer;
//set compression
- String name = cfg.getChild("compression").getValue(TIFFConstants.COMPRESSION_PACKBITS);
- //Some compression formats need a special image format:
- tiffRenderer.setBufferedImageType(getBufferedImageTypeFor(name));
- if (!"NONE".equalsIgnoreCase(name)) {
- tiffRenderer.getWriterParams().setCompressionMethod(name);
+ tiffRenderer.setBufferedImageType(getCompressionType(config, tiffRenderer.getWriterParams()));
+ }
+ super.configure(renderer);
+ }
+
+ private int getCompressionType(TIFFRendererConfig config, ImageWriterParams writerParms)
+ throws FOPException {
+ //Some compression formats need a special image format:
+ TIFFCompressionValues compression = config.getCompressionType();
+ if (compression != null) {
+ if (compression != NONE) {
+ writerParms.setCompressionMethod(compression.getName());
}
- if (log.isInfoEnabled()) {
- log.info("TIFF compression set to " + name);
+ if (LOG.isInfoEnabled()) {
+ LOG.info("TIFF compression set to " + compression.getName());
}
}
- super.configure(renderer);
+ return getBufferedImageTypeFor(compression);
}
- /**
- * Determines the type value for the BufferedImage to be produced for rendering
- * the bitmap image.
- * @param compressionName the compression name
- * @return a value from the {@link BufferedImage}.TYPE_* constants
- */
- private int getBufferedImageTypeFor(String compressionName) {
- if (compressionName.equalsIgnoreCase(TIFFConstants.COMPRESSION_CCITT_T6)) {
- return BufferedImage.TYPE_BYTE_BINARY;
- } else if (compressionName.equalsIgnoreCase(TIFFConstants.COMPRESSION_CCITT_T4)) {
+ private int getBufferedImageTypeFor(TIFFCompressionValues compressionType) {
+ if (compressionType == CCITT_T6 || compressionType == CCITT_T4) {
return BufferedImage.TYPE_BYTE_BINARY;
} else {
return BufferedImage.TYPE_INT_ARGB;
}
}
- // ---=== IFDocumentHandler configuration ===---
-
/** {@inheritDoc} */
public void configure(IFDocumentHandler documentHandler) throws FOPException {
- super.configure(documentHandler);
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- TIFFDocumentHandler tiffHandler = (TIFFDocumentHandler)documentHandler;
+ final TIFFRendererConfig tiffConfig = (TIFFRendererConfig) getRendererConfig(documentHandler);
+ if (tiffConfig != null) {
+ TIFFDocumentHandler tiffHandler = (TIFFDocumentHandler) documentHandler;
BitmapRenderingSettings settings = tiffHandler.getSettings();
- //set compression
- String name = cfg.getChild("compression").getValue(TIFFConstants.COMPRESSION_PACKBITS);
- //Some compression formats need a special image format:
- settings.setBufferedImageType(getBufferedImageTypeFor(name));
- if (!"NONE".equalsIgnoreCase(name)) {
- settings.getWriterParams().setCompressionMethod(name);
- }
- if (log.isInfoEnabled()) {
- log.info("TIFF compression set to " + name);
- }
+ configure(documentHandler, settings, new TIFFRendererConfigParser());
+ settings.setBufferedImageType(getCompressionType(tiffConfig, settings.getWriterParams()));
}
}
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java b/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
index 852e6ba04..f4cb78285 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFRendererMaker.java
@@ -19,11 +19,12 @@
package org.apache.fop.render.bitmap;
+import org.apache.fop.apps.FOPException;
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;
+import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser;
/**
* RendererMaker for the TIFF Renderer.
@@ -32,24 +33,24 @@ public class TIFFRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_TIFF};
- /** {@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent userAgent) {
return new TIFFRenderer(userAgent);
}
- /** {@inheritDoc} */
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return new TIFFRendererConfigurator(userAgent);
- }
-
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ new TIFFRendererConfigurator(userAgent, new TIFFRendererConfigParser()).configure(renderer);
+ }
+
}
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java b/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java
index cc5406acf..e0ee5b3b3 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractBinaryWritingIFDocumentHandler.java
@@ -19,15 +19,14 @@
package org.apache.fop.render.intermediate;
-import java.io.File;
+import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.net.URL;
+import java.net.URI;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
-import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.fop.fonts.FontCollection;
@@ -49,10 +48,14 @@ public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFD
/** Font configuration */
protected FontInfo fontInfo;
+ public AbstractBinaryWritingIFDocumentHandler(IFContext ifContext) {
+ super(ifContext);
+ }
+
/** {@inheritDoc} */
public void setResult(Result result) throws IFException {
if (result instanceof StreamResult) {
- StreamResult streamResult = (StreamResult)result;
+ StreamResult streamResult = (StreamResult) result;
OutputStream out = streamResult.getOutputStream();
if (out == null) {
if (streamResult.getWriter() != null) {
@@ -60,22 +63,13 @@ public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFD
"FOP cannot use a Writer. Please supply an OutputStream!");
}
try {
- URL url = new URL(streamResult.getSystemId());
- File f = FileUtils.toFile(url);
- if (f != null) {
- out = new java.io.FileOutputStream(f);
- } else {
- out = url.openConnection().getOutputStream();
- }
+ URI resultURI = URI.create(streamResult.getSystemId());
+ out = new BufferedOutputStream(getUserAgent().getResourceResolver().getOutputStream(resultURI));
} catch (IOException ioe) {
throw new IFException("I/O error while opening output stream" , ioe);
}
- out = new java.io.BufferedOutputStream(out);
this.ownOutputStream = true;
}
- if (out == null) {
- throw new IllegalArgumentException("Need a StreamResult with an OutputStream");
- }
this.outputStream = out;
} else {
throw new UnsupportedOperationException(
@@ -95,7 +89,7 @@ public abstract class AbstractBinaryWritingIFDocumentHandler extends AbstractIFD
/** {@inheritDoc} */
public void setDefaultFontInfo(FontInfo fontInfo) {
- FontManager fontManager = getUserAgent().getFactory().getFontManager();
+ FontManager fontManager = getUserAgent().getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
new Base14FontCollection(fontManager.isBase14KerningEnabled())
};
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java b/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java
index 2b90e4a7b..0a949e777 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandler.java
@@ -30,19 +30,16 @@ import org.apache.fop.apps.FOUserAgent;
*/
public abstract class AbstractIFDocumentHandler implements IFDocumentHandler {
- private IFContext ifContext;
+ private final IFContext ifContext;
/**
* Default constructor.
*/
- public AbstractIFDocumentHandler() {
- }
-
- /** {@inheritDoc} */
- public void setContext(IFContext context) {
+ protected AbstractIFDocumentHandler(IFContext context) {
this.ifContext = context;
}
+
/** {@inheritDoc} */
public IFContext getContext() {
return this.ifContext;
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java b/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java
index 204faad00..610f522c2 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractIFDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.intermediate;
-import org.apache.fop.apps.FOUserAgent;
/**
* Base class for factory classes which instantiate {@link IFDocumentHandler}s and provide
@@ -29,10 +28,10 @@ public abstract class AbstractIFDocumentHandlerMaker {
/**
* Instantiates a new {@link IFDocumentHandler}.
- * @param userAgent the user agent
+ * @param ifContext the user agent
* @return the newly instantiated document handler
*/
- public abstract IFDocumentHandler makeIFDocumentHandler(FOUserAgent userAgent);
+ public abstract IFDocumentHandler makeIFDocumentHandler(IFContext ifContext);
/**
* @return Indicates whether this document handler requires an OutputStream to work with.
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java b/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
index 9651cf446..2205aea4c 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
@@ -45,8 +45,9 @@ import org.apache.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.FopFactory;
import org.apache.fop.fo.Constants;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.render.ImageHandler;
import org.apache.fop.render.ImageHandlerRegistry;
import org.apache.fop.render.ImageHandlerUtil;
@@ -57,7 +58,7 @@ import org.apache.fop.traits.RuleStyle;
/**
* Abstract base class for IFPainter implementations.
*/
-public abstract class AbstractIFPainter implements IFPainter {
+public abstract class AbstractIFPainter<T extends IFDocumentHandler> implements IFPainter {
/** logging instance */
private static Log log = LogFactory.getLog(AbstractIFPainter.class);
@@ -68,18 +69,39 @@ public abstract class AbstractIFPainter implements IFPainter {
/** Holds the intermediate format state */
protected IFState state;
+ private final T documentHandler;
/**
* Default constructor.
*/
- public AbstractIFPainter() {
+ public AbstractIFPainter(T documentHandler) {
+ this.documentHandler = documentHandler;
+ }
+
+ protected String getFontKey(FontTriplet triplet) throws IFException {
+ String key = getFontInfo().getInternalFontKey(triplet);
+ if (key == null) {
+ throw new IFException("The font triplet is not available: \"" + triplet + "\" "
+ + "for the MIME type: \"" + documentHandler.getMimeType() + "\"");
+ }
+ return key;
}
/**
* Returns the intermediate format context object.
* @return the context object
*/
- protected abstract IFContext getContext();
+ protected IFContext getContext() {
+ return documentHandler.getContext();
+ }
+
+ protected FontInfo getFontInfo() {
+ return documentHandler.getFontInfo();
+ }
+
+ protected T getDocumentHandler() {
+ return documentHandler;
+ }
/**
* Returns the user agent.
@@ -89,14 +111,6 @@ public abstract class AbstractIFPainter implements IFPainter {
return getContext().getUserAgent();
}
- /**
- * Returns the FOP factory.
- * @return the FOP factory.
- */
- protected FopFactory getFopFactory() {
- return getUserAgent().getFactory();
- }
-
private AffineTransform combine(AffineTransform[] transforms) {
AffineTransform at = new AffineTransform();
for (int i = 0, c = transforms.length; i < c; i++) {
@@ -131,9 +145,9 @@ public abstract class AbstractIFPainter implements IFPainter {
*/
protected void drawImageUsingImageHandler(ImageInfo info, Rectangle rect)
throws ImageException, IOException {
- ImageManager manager = getFopFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
- ImageHandlerRegistry imageHandlerRegistry = getFopFactory().getImageHandlerRegistry();
+ ImageHandlerRegistry imageHandlerRegistry = getUserAgent().getImageHandlerRegistry();
//Load and convert the image to a supported format
RenderingContext context = createRenderingContext();
@@ -197,8 +211,8 @@ public abstract class AbstractIFPainter implements IFPainter {
protected void drawImage(Image image, Rectangle rect,
RenderingContext context, boolean convert, Map additionalHints)
throws IOException, ImageException {
- ImageManager manager = getFopFactory().getImageManager();
- ImageHandlerRegistry imageHandlerRegistry = getFopFactory().getImageHandlerRegistry();
+ ImageManager manager = getUserAgent().getImageManager();
+ ImageHandlerRegistry imageHandlerRegistry = getUserAgent().getImageHandlerRegistry();
Image effImage;
context.putHints(additionalHints);
@@ -236,7 +250,7 @@ public abstract class AbstractIFPainter implements IFPainter {
* @return the ImageInfo instance or null if there has been an error.
*/
protected ImageInfo getImageInfo(String uri) {
- ImageManager manager = getFopFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
return manager.getImageInfo(uri, sessionContext);
@@ -262,7 +276,7 @@ public abstract class AbstractIFPainter implements IFPainter {
* @param rect the rectangle in which to paint the image
*/
protected void drawImageUsingURI(String uri, Rectangle rect) {
- ImageManager manager = getFopFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
ImageInfo info = null;
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
@@ -290,7 +304,7 @@ public abstract class AbstractIFPainter implements IFPainter {
* @param rect the rectangle in which to paint the image
*/
protected void drawImageUsingDocument(Document doc, Rectangle rect) {
- ImageManager manager = getFopFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
ImageInfo info = null;
try {
info = manager.preloadImage(null, new DOMSource(doc));
diff --git a/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java b/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java
index be65e1317..fcf8554a6 100644
--- a/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/intermediate/AbstractXMLWritingIFDocumentHandler.java
@@ -45,6 +45,10 @@ public abstract class AbstractXMLWritingIFDocumentHandler extends AbstractIFDocu
/** Main SAX ContentHandler to receive the generated SAX events. */
protected GenerationHelperContentHandler handler;
+ protected AbstractXMLWritingIFDocumentHandler(IFContext context) {
+ super(context);
+ }
+
/** {@inheritDoc} */
public void setResult(Result result) throws IFException {
if (result instanceof SAXResult) {
diff --git a/src/java/org/apache/fop/render/intermediate/IFDocumentHandler.java b/src/java/org/apache/fop/render/intermediate/IFDocumentHandler.java
index 6cb8f2795..5342f09aa 100644
--- a/src/java/org/apache/fop/render/intermediate/IFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/intermediate/IFDocumentHandler.java
@@ -78,12 +78,6 @@ import org.apache.fop.fonts.FontInfo;
public interface IFDocumentHandler {
/**
- * Sets the intermediate format context object.
- * @param context the context object
- */
- void setContext(IFContext context);
-
- /**
* Returns the associated intermediate format context object.
* @return the context object
*/
@@ -274,4 +268,5 @@ public interface IFDocumentHandler {
* @throws IFException if an error occurs while handling this event
*/
void handleExtensionObject(Object extension) throws IFException;
+
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java b/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
index 3a42918f3..c00ebe29e 100644
--- a/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
+++ b/src/java/org/apache/fop/render/intermediate/IFDocumentHandlerConfigurator.java
@@ -40,6 +40,6 @@ public interface IFDocumentHandlerConfigurator {
* @param fontInfo the font info object to set up
* @throws FOPException if an error occurs while configuring the object
*/
- void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo) throws FOPException;
+ void setupFontInfo(String mimeType, FontInfo fontInfo) throws FOPException;
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFException.java b/src/java/org/apache/fop/render/intermediate/IFException.java
index 7e12c301b..5f35c3e3a 100644
--- a/src/java/org/apache/fop/render/intermediate/IFException.java
+++ b/src/java/org/apache/fop/render/intermediate/IFException.java
@@ -27,32 +27,27 @@ public class IFException extends Exception {
private static final long serialVersionUID = 0L;
/**
- * Constructs a new exception with the specified detail message and
- * cause. <p>Note that the detail message associated with
- * <code>cause</code> is <i>not</i> automatically incorporated in
+ * Constructs a new exception with the specified detail message and cause. <p>Note that the
+ * detail message associated with <code>cause</code> is <i>not</i> automatically incorporated in
* this exception's detail message.
*
- * @param message the detail message (which is saved for later retrieval
- * by the {@link #getMessage()} method).
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <code>null</code> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
+ * @param message the detail message (which is saved for later retrieval by the
+ * {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the {@link #getCause()}
+ * method). (A <code>null</code> value is permitted, and indicates that the cause is
+ * nonexistent or unknown.)
*/
public IFException(String message, Exception cause) {
super(message, cause);
}
/**
- * Constructs a new exception with the cause.
+ * Constructs a new exception with the specified detail message.
*
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <code>null</code> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
+ * @param message the detail message (which is saved for later retrieval by the
+ * {@link #getMessage()} method).
*/
- /*public IFException( Exception cause) {
- super(cause);
- }*/
-
+ public IFException(String message) {
+ super(message);
+ }
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java
index 293487ac2..24b7a924c 100644
--- a/src/java/org/apache/fop/render/intermediate/IFParser.java
+++ b/src/java/org/apache/fop/render/intermediate/IFParser.java
@@ -130,7 +130,7 @@ public class IFParser implements IFConstants {
public ContentHandler getContentHandler(IFDocumentHandler documentHandler,
FOUserAgent userAgent) {
ElementMappingRegistry elementMappingRegistry
- = userAgent.getFactory().getElementMappingRegistry();
+ = userAgent.getElementMappingRegistry();
return new Handler(documentHandler, userAgent, elementMappingRegistry);
}
@@ -306,7 +306,7 @@ public class IFParser implements IFConstants {
delegate.startElement(uri, localName, qName, attributes);
} else {
ContentHandlerFactoryRegistry registry
- = userAgent.getFactory().getContentHandlerFactoryRegistry();
+ = userAgent.getContentHandlerFactoryRegistry();
ContentHandlerFactory factory = registry.getFactory(uri);
if (factory == null) {
DOMImplementation domImplementation
diff --git a/src/java/org/apache/fop/render/intermediate/IFRenderer.java b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
index 45b0c3a93..47a53deca 100644
--- a/src/java/org/apache/fop/render/intermediate/IFRenderer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFRenderer.java
@@ -231,9 +231,8 @@ public class IFRenderer extends AbstractPathOrientedRenderer {
* @return the default IFDocumentHandler
*/
protected IFDocumentHandler createDefaultDocumentHandler() {
- IFSerializer serializer = new IFSerializer();
FOUserAgent userAgent = getUserAgent();
- serializer.setContext(new IFContext(userAgent));
+ IFSerializer serializer = new IFSerializer(new IFContext(userAgent));
if (userAgent.isAccessibilityEnabled()) {
userAgent.setStructureTreeEventHandler(serializer.getStructureTreeEventHandler());
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFRendererConfig.java b/src/java/org/apache/fop/render/intermediate/IFRendererConfig.java
new file mode 100644
index 000000000..753d9ff30
--- /dev/null
+++ b/src/java/org/apache/fop/render/intermediate/IFRendererConfig.java
@@ -0,0 +1,63 @@
+/*
+ * 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.intermediate;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.fonts.FontConfig;
+import org.apache.fop.render.RendererConfig;
+
+/**
+ * The Intermediate Format renderer configuration data object.
+ */
+public final class IFRendererConfig implements RendererConfig {
+
+ private final DefaultFontConfig fontConfig;
+
+ private IFRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public FontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ /**
+ * The Intermediate Format configuration data parser.
+ */
+ public static final class IFRendererConfigParser implements RendererConfigParser {
+
+ /** {@inheritDoc} */
+ public RendererConfig build(FOUserAgent userAgent, Configuration cfg)
+ throws FOPException {
+ return new IFRendererConfig(new DefaultFontConfigParser().parse(cfg,
+ userAgent.validateStrictly()));
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return "application/X-fop-intermediate-format";
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
index 4c6781706..749f68d78 100644
--- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
@@ -40,8 +40,9 @@ import org.apache.xmlgraphics.util.XMLizable;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.render.PrintRendererConfigurator;
+import org.apache.fop.render.DefaultRendererConfigurator;
import org.apache.fop.render.RenderingContext;
+import org.apache.fop.render.intermediate.IFRendererConfig.IFRendererConfigParser;
import org.apache.fop.render.intermediate.IFStructureTreeBuilder.IFStructureTreeElement;
import org.apache.fop.render.intermediate.extensions.AbstractAction;
import org.apache.fop.render.intermediate.extensions.Bookmark;
@@ -62,7 +63,7 @@ import org.apache.fop.util.XMLUtil;
* IFPainter implementation that serializes the intermediate format to XML.
*/
public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
- implements IFConstants, IFPainter, IFDocumentNavigationHandler {
+implements IFConstants, IFPainter, IFDocumentNavigationHandler {
/**
* Intermediate Format (IF) version, used to express an @version attribute
@@ -83,6 +84,10 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
private IFStructureTreeBuilder structureTreeBuilder;
+ public IFSerializer(IFContext context) {
+ super(context);
+ }
+
/** {@inheritDoc} */
@Override
protected String getMainNamespace() {
@@ -106,7 +111,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
if (this.mimicHandler != null) {
return getMimickedDocumentHandler().getConfigurator();
} else {
- return new PrintRendererConfigurator(getUserAgent());
+ return new DefaultRendererConfigurator(getUserAgent(), new IFRendererConfigParser());
}
}
@@ -284,7 +289,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
/** {@inheritDoc} */
public void startPage(int index, String name, String pageMasterName, Dimension size)
- throws IFException {
+ throws IFException {
try {
AttributesImpl atts = new AttributesImpl();
addAttribute(atts, "index", Integer.toString(index));
@@ -386,7 +391,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
}
private void startViewport(String transform, Dimension size, Rectangle clipRect)
- throws IFException {
+ throws IFException {
try {
AttributesImpl atts = new AttributesImpl();
if (transform != null && transform.length() > 0) {
@@ -750,7 +755,7 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
} else {
throw new UnsupportedOperationException(
"Extension must implement XMLizable: "
- + extension + " (" + extension.getClass().getName() + ")");
+ + extension + " (" + extension.getClass().getName() + ")");
}
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializerMaker.java b/src/java/org/apache/fop/render/intermediate/IFSerializerMaker.java
index c0060ab8e..fa375fb94 100644
--- a/src/java/org/apache/fop/render/intermediate/IFSerializerMaker.java
+++ b/src/java/org/apache/fop/render/intermediate/IFSerializerMaker.java
@@ -28,9 +28,9 @@ import org.apache.fop.apps.MimeConstants;
public class IFSerializerMaker extends AbstractIFDocumentHandlerMaker {
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- IFSerializer handler = new IFSerializer();
- handler.setContext(new IFContext(ua));
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ IFSerializer handler = new IFSerializer(ifContext);
+ FOUserAgent ua = ifContext.getUserAgent();
if (ua.isAccessibilityEnabled()) {
ua.setStructureTreeEventHandler(handler.getStructureTreeEventHandler());
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFUtil.java b/src/java/org/apache/fop/render/intermediate/IFUtil.java
index c4f681936..bdd7eb8a0 100644
--- a/src/java/org/apache/fop/render/intermediate/IFUtil.java
+++ b/src/java/org/apache/fop/render/intermediate/IFUtil.java
@@ -167,7 +167,8 @@ public final class IFUtil {
}
IFDocumentHandlerConfigurator configurator = documentHandler.getConfigurator();
if (configurator != null) {
- configurator.setupFontInfo(documentHandler, fontInfo);
+ configurator.setupFontInfo(documentHandler.getMimeType(), fontInfo);
+ documentHandler.setFontInfo(fontInfo);
} else {
documentHandler.setDefaultFontInfo(fontInfo);
}
diff --git a/src/java/org/apache/fop/render/intermediate/util/IFDocumentHandlerProxy.java b/src/java/org/apache/fop/render/intermediate/util/IFDocumentHandlerProxy.java
index dde744180..b88e75206 100644
--- a/src/java/org/apache/fop/render/intermediate/util/IFDocumentHandlerProxy.java
+++ b/src/java/org/apache/fop/render/intermediate/util/IFDocumentHandlerProxy.java
@@ -61,11 +61,6 @@ public class IFDocumentHandlerProxy implements IFDocumentHandler {
}
/** {@inheritDoc} */
- public void setContext(IFContext context) {
- this.delegate.setContext(context);
- }
-
- /** {@inheritDoc} */
public IFContext getContext() {
return this.delegate.getContext();
}
diff --git a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
index 9c404be3e..0b410873b 100644
--- a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
+++ b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
@@ -19,21 +19,19 @@
package org.apache.fop.render.java2d;
+import java.io.InputStream;
+import java.net.URI;
import java.util.List;
-import javax.xml.transform.Source;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.EmbedFontInfo;
-import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontLoader;
-import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
@@ -44,23 +42,21 @@ public class ConfiguredFontCollection implements FontCollection {
private static Log log = LogFactory.getLog(ConfiguredFontCollection.class);
- private FontResolver fontResolver;
- private List/*<EmbedFontInfo>*/ embedFontInfoList;
+ private final InternalResourceResolver resourceResolver;
+ private final List<EmbedFontInfo> embedFontInfoList;
+ private final boolean useComplexScripts;
/**
* Main constructor
- * @param fontResolver a font resolver
+ * @param resourceResolver a font resolver
* @param customFonts the list of custom fonts
* @param useComplexScriptFeatures true if complex script features enabled
*/
- public ConfiguredFontCollection(FontResolver fontResolver,
- List/*<EmbedFontInfo>*/ customFonts, boolean useComplexScriptFeatures) {
- this.fontResolver = fontResolver;
- if (this.fontResolver == null) {
- //Ensure that we have minimal font resolution capabilities
- this.fontResolver = FontManager.createMinimalFontResolver(useComplexScriptFeatures);
- }
+ public ConfiguredFontCollection(InternalResourceResolver resourceResolver,
+ List<EmbedFontInfo> customFonts, boolean useComplexScriptFeatures) {
+ this.resourceResolver = resourceResolver;
this.embedFontInfoList = customFonts;
+ this.useComplexScripts = useComplexScriptFeatures;
}
/** {@inheritDoc} */
@@ -72,43 +68,37 @@ public class ConfiguredFontCollection implements FontCollection {
}
String internalName = null;
- for (int i = 0; i < embedFontInfoList.size(); i++) {
-
- EmbedFontInfo configFontInfo = (EmbedFontInfo) embedFontInfoList.get(i);
- String fontFile = configFontInfo.getEmbedFile();
- internalName = "F" + num;
- num++;
+ for (EmbedFontInfo configFontInfo : embedFontInfoList) {
+ internalName = "F" + num++;
try {
+ URI fontURI = configFontInfo.getEmbedURI();
FontMetricsMapper font = null;
- String metricsUrl = configFontInfo.getMetricsFile();
+ URI metricsURI = configFontInfo.getMetricsURI();
// If the user specified an XML-based metrics file, we'll use it
// Otherwise, calculate metrics directly from the font file.
- if (metricsUrl != null) {
- LazyFont fontMetrics = new LazyFont(configFontInfo, fontResolver);
- Source fontSource = fontResolver.resolve(configFontInfo.getEmbedFile());
+ if (metricsURI != null) {
+ LazyFont fontMetrics = new LazyFont(configFontInfo, resourceResolver, useComplexScripts);
+ InputStream fontSource = resourceResolver.getResource(fontURI);
font = new CustomFontMetricsMapper(fontMetrics, fontSource);
} else {
- CustomFont fontMetrics = FontLoader.loadFont(
- fontFile, null, true, configFontInfo.getEmbeddingMode(),
- EncodingMode.AUTO,
- configFontInfo.getKerning(),
- configFontInfo.getAdvanced(), fontResolver);
+ CustomFont fontMetrics = FontLoader.loadFont(fontURI, null, true,
+ configFontInfo.getEmbeddingMode(), configFontInfo.getEncodingMode(),
+ configFontInfo.getKerning(), configFontInfo.getAdvanced(),
+ resourceResolver);
font = new CustomFontMetricsMapper(fontMetrics);
}
fontInfo.addMetrics(internalName, font);
- List<FontTriplet> triplets = configFontInfo.getFontTriplets();
- for (int c = 0; c < triplets.size(); c++) {
- FontTriplet triplet = (FontTriplet) triplets.get(c);
-
+ for (FontTriplet triplet : configFontInfo.getFontTriplets()) {
if (log.isDebugEnabled()) {
log.debug("Registering: " + triplet + " under " + internalName);
}
fontInfo.addFontProperties(internalName, triplet);
}
} catch (Exception e) {
- log.warn("Unable to load custom font from file '" + fontFile + "'", e);
+ log.warn("Unable to load custom font from file '" + configFontInfo.getEmbedURI()
+ + "'", e);
}
}
return num;
diff --git a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
index 36df00f20..e821e635d 100644
--- a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
+++ b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
@@ -26,9 +26,6 @@ import java.io.InputStream;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.LazyFont;
@@ -67,7 +64,7 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
public CustomFontMetricsMapper(final CustomFont fontMetrics)
throws FontFormatException, IOException {
this.typeface = fontMetrics;
- initialize(fontMetrics.getEmbedFileSource());
+ initialize(fontMetrics.getInputStream());
}
/**
@@ -78,7 +75,7 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
* @throws FontFormatException if a bad font is loaded
* @throws IOException if an I/O error occurs
*/
- public CustomFontMetricsMapper(final LazyFont fontMetrics, final Source fontSource)
+ public CustomFontMetricsMapper(final LazyFont fontMetrics, final InputStream fontSource)
throws FontFormatException, IOException {
this.typeface = fontMetrics;
initialize(fontSource);
@@ -88,29 +85,18 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
/**
* Loads the java.awt.Font
- * @param source
+ * @param inStream
* @throws FontFormatException
* @throws IOException
*/
- private void initialize(final Source source)
+ private void initialize(final InputStream inStream)
throws FontFormatException, IOException {
int type = Font.TRUETYPE_FONT;
if (FontType.TYPE1.equals(typeface.getFontType())) {
type = TYPE1_FONT; //Font.TYPE1_FONT; only available in Java 1.5
}
-
- InputStream is = null;
- if (source instanceof StreamSource) {
- is = ((StreamSource) source).getInputStream();
- } else if (source.getSystemId() != null) {
- is = new java.net.URL(source.getSystemId()).openStream();
- } else {
- throw new IllegalArgumentException("No font source provided.");
- }
-
- this.font = Font.createFont(type, is);
- is.close();
-
+ this.font = Font.createFont(type, inStream);
+ inStream.close();
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/java2d/Java2DDocumentHandler.java b/src/java/org/apache/fop/render/java2d/Java2DDocumentHandler.java
new file mode 100644
index 000000000..87003f077
--- /dev/null
+++ b/src/java/org/apache/fop/render/java2d/Java2DDocumentHandler.java
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.java2d;
+
+import java.awt.Dimension;
+import java.util.Locale;
+
+import javax.xml.transform.Result;
+
+import org.apache.fop.accessibility.StructureTreeEventHandler;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.intermediate.IFContext;
+import org.apache.fop.render.intermediate.IFDocumentHandler;
+import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+import org.apache.fop.render.intermediate.IFDocumentNavigationHandler;
+import org.apache.fop.render.intermediate.IFException;
+import org.apache.fop.render.intermediate.IFPainter;
+
+/**
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation that produces
+ * Graphics2D instance.
+ */
+public class Java2DDocumentHandler implements IFDocumentHandler {
+
+ public void setContext(IFContext context) {
+ throw new UnsupportedOperationException();
+ }
+
+ public IFContext getContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setResult(Result result) throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setFontInfo(FontInfo fontInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ public FontInfo getFontInfo() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setDefaultFontInfo(FontInfo fontInfo) {
+ throw new UnsupportedOperationException();
+ }
+
+ public IFDocumentHandlerConfigurator getConfigurator() {
+ throw new UnsupportedOperationException();
+ }
+
+ public StructureTreeEventHandler getStructureTreeEventHandler() {
+ throw new UnsupportedOperationException();
+ }
+
+ public IFDocumentNavigationHandler getDocumentNavigationHandler() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean supportsPagesOutOfOrder() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getMimeType() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startDocument() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endDocument() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setDocumentLocale(Locale locale) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startDocumentHeader() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endDocumentHeader() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startDocumentTrailer() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endDocumentTrailer() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startPageSequence(String id) throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endPageSequence() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startPage(int index, String name, String pageMasterName, Dimension size)
+ throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endPage() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startPageHeader() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endPageHeader() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public IFPainter startPageContent() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endPageContent() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void startPageTrailer() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void endPageTrailer() throws IFException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void handleExtensionObject(Object extension) throws IFException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java b/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java
index b0c003b91..70fe0b449 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DGraphicsState.java
@@ -130,7 +130,7 @@ public class Java2DGraphicsState {
*/
public boolean updateFont(String name, int size) {
- FontMetricsMapper mapper = (FontMetricsMapper)fontInfo.getMetricsFor(name);
+ FontMetricsMapper mapper = (FontMetricsMapper) fontInfo.getMetricsFor(name);
boolean updateName = (!mapper.getFontName().equals(
getGraph().getFont().getFontName()));
boolean updateSize = (size != (getGraph().getFont().getSize() * 1000));
diff --git a/src/java/org/apache/fop/render/java2d/Java2DPainter.java b/src/java/org/apache/fop/render/java2d/Java2DPainter.java
index 7e4d72c14..7b8a96b99 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DPainter.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DPainter.java
@@ -47,10 +47,10 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
/**
- * {@link org.apache.fop.render.intermediate.IFPainter} implementation
- * that paints on a Graphics2D instance.
+ * {@link org.apache.fop.render.intermediate.IFPainter} implementation that paints on a Graphics2D
+ * instance.
*/
-public class Java2DPainter extends AbstractIFPainter {
+public class Java2DPainter extends AbstractIFPainter<Java2DDocumentHandler> {
/** the IF context */
protected IFContext ifContext;
@@ -62,7 +62,7 @@ public class Java2DPainter extends AbstractIFPainter {
/** The current state, holds a Graphics2D and its context */
protected Java2DGraphicsState g2dState;
- private Stack g2dStateStack = new Stack();
+ private Stack<Java2DGraphicsState> g2dStateStack = new Stack<Java2DGraphicsState>();
/**
* Main constructor.
@@ -83,7 +83,7 @@ public class Java2DPainter extends AbstractIFPainter {
* @param state the IF state object
*/
public Java2DPainter(Graphics2D g2d, IFContext context, FontInfo fontInfo, IFState state) {
- super();
+ super(new Java2DDocumentHandler());
this.ifContext = context;
if (state != null) {
this.state = state.push();
@@ -258,7 +258,7 @@ public class Java2DPainter extends AbstractIFPainter {
/** Restores the last graphics state from the stack. */
protected void restoreGraphicsState() {
g2dState.dispose();
- g2dState = (Java2DGraphicsState)g2dStateStack.pop();
+ g2dState = g2dStateStack.pop();
}
private void concatenateTransformationMatrix(AffineTransform transform) throws IOException {
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
index 8b60df746..91d38675d 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderer.java
@@ -58,7 +58,7 @@ import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.ResourceEventProducer;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.FopFactoryConfigurator;
+import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.area.CTM;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.Trait;
@@ -73,6 +73,7 @@ import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCollection;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.AbstractPathOrientedRenderer;
import org.apache.fop.render.Graphics2DAdapter;
@@ -83,6 +84,8 @@ import org.apache.fop.render.pdf.CTMHelper;
import org.apache.fop.util.CharUtilities;
import org.apache.fop.util.ColorUtil;
+import static org.apache.fop.render.java2d.Java2DRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND;
+
/**
* The <code>Java2DRenderer</code> class provides the abstract technical
* foundation for all rendering with the Java2D API. Renderers like
@@ -109,9 +112,6 @@ import org.apache.fop.util.ColorUtil;
*/
public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implements Printable {
- /** Rendering Options key for the controlling the transparent page background option. */
- public static final String JAVA2D_TRANSPARENT_PAGE_BACKGROUND = "transparent-page-background";
-
/** The scale factor for the image size, values: ]0 ; 1] */
protected double scaleFactor = 1;
@@ -157,7 +157,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
// MH: necessary? the caller has access to FOUserAgent
userAgent.setRendererOverride(this); // for document regeneration
- String s = (String) userAgent.getRendererOptions().get(JAVA2D_TRANSPARENT_PAGE_BACKGROUND);
+ String s = (String) userAgent.getRendererOption(JAVA2D_TRANSPARENT_PAGE_BACKGROUND);
if (s != null) {
this.transparentPageBackground = "true".equalsIgnoreCase(s);
}
@@ -175,14 +175,15 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
this.fontInfo = inFontInfo;
final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
+ FontManager fontManager = userAgent.getFontManager();
+
FontCollection[] fontCollections = new FontCollection[] {
new Base14FontCollection(java2DFontMetrics),
new InstalledFontCollection(java2DFontMetrics),
- new ConfiguredFontCollection(getFontResolver(), getFontList(),
- userAgent.isComplexScriptFeaturesEnabled())
+ new ConfiguredFontCollection(fontManager.getResourceResolver(), getFontList(),
+ userAgent.isComplexScriptFeaturesEnabled())
};
- userAgent.getFactory().getFontManager().setup(
- getFontInfo(), fontCollections);
+ fontManager.setup(getFontInfo(), fontCollections);
}
/** {@inheritDoc} */
@@ -317,7 +318,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
// set scale factor
double scaleX = scaleFactor;
double scaleY = scaleFactor;
- String scale = (String) currentPageViewport.getForeignAttributes().get(
+ String scale = currentPageViewport.getForeignAttributes().get(
PageScale.EXT_PAGE_SCALE);
Point2D scales = PageScale.getScale(scale);
if (scales != null) {
@@ -326,10 +327,10 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
}
scaleX = scaleX
- * (UnitConv.IN2MM / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+ * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION)
/ userAgent.getTargetPixelUnitToMillimeter();
scaleY = scaleY
- * (UnitConv.IN2MM / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION)
+ * (UnitConv.IN2MM / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION)
/ userAgent.getTargetPixelUnitToMillimeter();
int bitmapWidth = (int) ((pageWidth * scaleX) + 0.5);
int bitmapHeight = (int) ((pageHeight * scaleY) + 0.5);
@@ -737,7 +738,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
//super.renderText(text);
// rendering text decorations
- Typeface tf = (Typeface) fontInfo.getFonts().get(font.getFontName());
+ Typeface tf = fontInfo.getFonts().get(font.getFontName());
int fontsize = text.getTraitAsInteger(Trait.FONT_SIZE);
renderTextDecoration(tf, fontsize, text, bl, rx);
}
@@ -918,7 +919,7 @@ public abstract class Java2DRenderer extends AbstractPathOrientedRenderer implem
int y = currentBPPosition + (int)Math.round(pos.getY());
uri = URISpecification.getURL(uri);
- ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
ImageInfo info = null;
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRendererConfig.java b/src/java/org/apache/fop/render/java2d/Java2DRendererConfig.java
new file mode 100644
index 000000000..1ed0aec96
--- /dev/null
+++ b/src/java/org/apache/fop/render/java2d/Java2DRendererConfig.java
@@ -0,0 +1,83 @@
+/*
+ * 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 java.util.EnumMap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfig;
+
+import static org.apache.fop.render.java2d.Java2DRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND;
+
+/**
+ * The Java2D renderer configuration data object.
+ */
+public final class Java2DRendererConfig implements RendererConfig {
+
+ private final EnumMap<Java2DRendererOption, Object> params
+ = new EnumMap<Java2DRendererOption, Object>(Java2DRendererOption.class);
+
+ private final DefaultFontConfig fontConfig;
+
+ private Java2DRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public Boolean isPageBackgroundTransparent() {
+ return Boolean.class.cast(params.get(JAVA2D_TRANSPARENT_PAGE_BACKGROUND));
+ }
+
+ /**
+ * The Java2D renderer configuration data parser.
+ */
+ public static class Java2DRendererConfigParser implements RendererConfigParser {
+
+ private final String mimeType;
+
+ public Java2DRendererConfigParser(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ /** {@inheritDoc} */
+ public Java2DRendererConfig build(FOUserAgent userAgent, Configuration cfg)
+ throws FOPException {
+ Java2DRendererConfig config = new Java2DRendererConfig(new DefaultFontConfigParser()
+ .parse(cfg, userAgent.validateStrictly()));
+ boolean value = cfg.getChild(
+ JAVA2D_TRANSPARENT_PAGE_BACKGROUND.getName(), true).getValueAsBoolean(false);
+ config.params.put(JAVA2D_TRANSPARENT_PAGE_BACKGROUND, value);
+ return config;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return mimeType;
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java b/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java
index a12cb3898..9ff2ccdbd 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRendererConfigurator.java
@@ -19,24 +19,23 @@
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.DefaultRendererConfigurator;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
/**
* Configurerer for Java 2D renderer
*/
-public class Java2DRendererConfigurator extends PrintRendererConfigurator {
+public class Java2DRendererConfigurator extends DefaultRendererConfigurator {
/**
* Default constructor
* @param userAgent user agent
*/
- public Java2DRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public Java2DRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
/**
@@ -45,15 +44,14 @@ public class Java2DRendererConfigurator extends PrintRendererConfigurator {
* @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));
+ Java2DRendererConfig config = (Java2DRendererConfig) getRendererConfig(renderer);
+ if (config != null) {
+ Java2DRenderer java2dRenderer = (Java2DRenderer) renderer;
+ // new Java2DRendererConfigParser(renderer.getMimeType()));
+ if (config.isPageBackgroundTransparent() != null) {
+ java2dRenderer.setTransparentPageBackground(config.isPageBackgroundTransparent());
}
+ super.configure(renderer);
}
- super.configure(renderer);
}
}
diff --git a/src/java/org/apache/fop/render/ps/PSConfigurationConstants.java b/src/java/org/apache/fop/render/java2d/Java2DRendererOption.java
index 6b3550f57..b25f05889 100644
--- a/src/java/org/apache/fop/render/ps/PSConfigurationConstants.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRendererOption.java
@@ -17,17 +17,21 @@
/* $Id$ */
-package org.apache.fop.render.ps;
+package org.apache.fop.render.java2d;
-/**
- * Constants used for configuring PostScript output.
- */
-public interface PSConfigurationConstants {
+import org.apache.fop.render.RendererConfigOption;
+
+public enum Java2DRendererOption implements RendererConfigOption {
+ /** Rendering Options key for the controlling the transparent page background option. */
+ JAVA2D_TRANSPARENT_PAGE_BACKGROUND("transparent-page-background");
+
+ private final String name;
+
+ private Java2DRendererOption(String name) {
+ this.name = name;
+ }
- /** Controls the behaviour for landscape pages */
- String AUTO_ROTATE_LANDSCAPE = "auto-rotate-landscape";
- /** Controls whether resources are optimized (rather than inlined) */
- String OPTIMIZE_RESOURCES = "optimize-resources";
- /** Determines the PostScript language level to be generated */
- String LANGUAGE_LEVEL = "language-level";
+ public String getName() {
+ return name;
+ }
}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DRenderingSettings.java b/src/java/org/apache/fop/render/java2d/Java2DRenderingSettings.java
index f7bad64a7..06ea8a3cf 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DRenderingSettings.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DRenderingSettings.java
@@ -53,6 +53,4 @@ public class Java2DRenderingSettings {
public boolean hasTransparentPageBackground() {
return this.pageBackgroundColor == null;
}
-
-
}
diff --git a/src/java/org/apache/fop/render/java2d/Java2DUtil.java b/src/java/org/apache/fop/render/java2d/Java2DUtil.java
index 924460bd8..c17ad2994 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DUtil.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DUtil.java
@@ -44,7 +44,7 @@ public final class Java2DUtil {
FontInfo fontInfo, FOUserAgent userAgent) {
Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
- FontManager fontManager = userAgent.getFactory().getFontManager();
+ FontManager fontManager = userAgent.getFontManager();
FontCollection[] fontCollections = new FontCollection[] {
new org.apache.fop.render.java2d.Base14FontCollection(java2DFontMetrics),
new InstalledFontCollection(java2DFontMetrics)
diff --git a/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java b/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java
new file mode 100644
index 000000000..cb23f7191
--- /dev/null
+++ b/src/java/org/apache/fop/render/pcl/Java2DRendererOption.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package org.apache.fop.render.pcl;
+
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * An enumeration of the renderer configuration options available to the Java2D renderer via the
+ * FOP conf.
+ */
+public enum Java2DRendererOption implements RendererConfigOption {
+
+ RENDERING_MODE("rendering", PCLRenderingMode.class),
+ TEXT_RENDERING("text-rendering", Boolean.class),
+ DISABLE_PJL("disable-pjl", Boolean.class);
+
+ private final String name;
+
+ private final Class<?> type;
+
+ private Java2DRendererOption(String name, Class<?> type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ /** {@inheritDoc} */
+ public String getName() {
+ return name;
+ }
+
+ Class<?> getType() {
+ return type;
+ }
+}
diff --git a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
index 332b4a77d..a44205d06 100644
--- a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
+++ b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
@@ -32,7 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.util.UnitConv;
-import org.apache.fop.apps.FopFactoryConfigurator;
+import org.apache.fop.apps.FopFactoryConfig;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
@@ -42,6 +42,7 @@ import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.render.java2d.Java2DPainter;
import org.apache.fop.render.java2d.Java2DUtil;
+import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser;
import org.apache.fop.render.pcl.extensions.PCLElementMapping;
/**
@@ -74,7 +75,9 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
/**
* Default constructor.
*/
- public PCLDocumentHandler() {
+ public PCLDocumentHandler(IFContext context) {
+ super(context);
+ this.pclUtil = new PCLRenderingUtil(context.getUserAgent());
}
/** {@inheritDoc} */
@@ -88,15 +91,8 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
/** {@inheritDoc} */
- @Override
- public void setContext(IFContext context) {
- super.setContext(context);
- this.pclUtil = new PCLRenderingUtil(context.getUserAgent());
- }
-
- /** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new PCLRendererConfigurator(getUserAgent());
+ return new PCLRendererConfigurator(getUserAgent(), new PCLRendererConfigParser());
}
/** {@inheritDoc} */
@@ -227,7 +223,7 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
private IFPainter createAllBitmapPainter() {
double scale = gen.getMaximumBitmapResolution()
- / FopFactoryConfigurator.DEFAULT_TARGET_RESOLUTION;
+ / FopFactoryConfig.DEFAULT_TARGET_RESOLUTION;
Rectangle printArea = this.currentPageDefinition.getLogicalPageRect();
int bitmapWidth = (int)Math.ceil(
UnitConv.mpt2px(printArea.width, gen.getMaximumBitmapResolution()));
@@ -276,7 +272,6 @@ public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
public void endPageContent() throws IFException {
if (this.currentImage != null) {
try {
- //ImageWriterUtil.saveAsPNG(this.currentImage, new java.io.File("D:/page.png"));
Rectangle printArea = this.currentPageDefinition.getLogicalPageRect();
gen.setCursorPos(0, 0);
gen.paintBitmap(this.currentImage, printArea.getSize(), true);
diff --git a/src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java b/src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java
index 85653e423..affe2abae 100644
--- a/src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/pcl/PCLDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.pcl;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
@@ -36,10 +35,8 @@ public class PCLDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- PCLDocumentHandler handler = new PCLDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new PCLDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pcl/PCLGenerator.java b/src/java/org/apache/fop/render/pcl/PCLGenerator.java
index 29fe77323..0db295a5a 100644
--- a/src/java/org/apache/fop/render/pcl/PCLGenerator.java
+++ b/src/java/org/apache/fop/render/pcl/PCLGenerator.java
@@ -677,13 +677,6 @@ public class PCLGenerator {
} finally {
g2d.dispose();
}
- /*
- try {
- BatchDiffer.saveAsPNG(alpha, new java.io.File("D:/out-alpha.png"));
- BatchDiffer.saveAsPNG(mask, new java.io.File("D:/out-mask.png"));
- } catch (IOException e) {
- e.printStackTrace();
- }*/
return mask;
} else {
return null;
@@ -715,7 +708,6 @@ public class PCLGenerator {
(int)Math.ceil(UnitConv.mpt2px(targetDim.height, effResolution)));
}
boolean scaled = !orgDim.equals(effDim);
- //ImageWriterUtil.saveAsPNG(img, new java.io.File("D:/text-0-org.png"));
boolean monochrome = isMonochromeImage(img);
if (!monochrome) {
diff --git a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java
index 25249caf6..014bc47a1 100644
--- a/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java
+++ b/src/java/org/apache/fop/render/pcl/PCLImageHandlerGraphics2D.java
@@ -127,7 +127,7 @@ public class PCLImageHandlerGraphics2D implements ImageHandler {
if (!painted) {
//Fallback solution: Paint to a BufferedImage
FOUserAgent ua = context.getUserAgent();
- ImageManager imageManager = ua.getFactory().getImageManager();
+ ImageManager imageManager = ua.getImageManager();
ImageRendered imgRend;
try {
imgRend = (ImageRendered)imageManager.convertImage(
diff --git a/src/java/org/apache/fop/render/pcl/PCLPainter.java b/src/java/org/apache/fop/render/pcl/PCLPainter.java
index a057252d6..179a4f527 100644
--- a/src/java/org/apache/fop/render/pcl/PCLPainter.java
+++ b/src/java/org/apache/fop/render/pcl/PCLPainter.java
@@ -47,7 +47,6 @@ import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.render.ImageHandlerUtil;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
-import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -58,15 +57,12 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
/**
- * {@link org.apache.fop.render.intermediate.IFPainter} implementation
- * that produces PCL 5.
+ * {@link org.apache.fop.render.intermediate.IFPainter} implementation that produces PCL 5.
*/
-public class PCLPainter extends AbstractIFPainter implements PCLConstants {
+public class PCLPainter extends AbstractIFPainter<PCLDocumentHandler> implements PCLConstants {
private static final boolean DEBUG = false;
- private PCLDocumentHandler parent;
-
/** The PCL generator */
private PCLGenerator gen;
@@ -74,7 +70,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
private int currentPrintDirection = 0;
//private GeneralPath currentPath = null;
- private Stack graphicContextStack = new Stack();
+ private Stack<GraphicContext> graphicContextStack = new Stack<GraphicContext>();
private GraphicContext graphicContext = new GraphicContext();
/**
@@ -83,19 +79,14 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
* @param pageDefinition the page definition describing the page to be rendered
*/
public PCLPainter(PCLDocumentHandler parent, PCLPageDefinition pageDefinition) {
- this.parent = parent;
+ super(parent);
this.gen = parent.getPCLGenerator();
this.state = IFState.create();
this.currentPageDefinition = pageDefinition;
}
- /** {@inheritDoc} */
- public IFContext getContext() {
- return this.parent.getContext();
- }
-
PCLRenderingUtil getPCLUtil() {
- return this.parent.getPCLUtil();
+ return getDocumentHandler().getPCLUtil();
}
/** @return the target resolution */
@@ -231,7 +222,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
g2d.translate(-rect.x, -rect.y);
Java2DPainter painter = new Java2DPainter(g2d,
- getContext(), parent.getFontInfo(), state);
+ getContext(), getFontInfo(), state);
try {
painter.drawBorderRect(rect, top, bottom, left, right);
} catch (IFException e) {
@@ -266,7 +257,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
g2d.translate(-boundingBox.x, -boundingBox.y);
Java2DPainter painter = new Java2DPainter(g2d,
- getContext(), parent.getFontInfo(), state);
+ getContext(), getFontInfo(), state);
try {
painter.drawLine(start, end, width, color, style);
} catch (IFException e) {
@@ -323,9 +314,8 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
//TODO Ignored: state.getFontVariant()
//TODO Opportunity for font caching if font state is more heavily used
- String fontKey = parent.getFontInfo().getInternalFontKey(triplet);
- boolean pclFont = getPCLUtil().isAllTextAsBitmaps()
- ? false
+ String fontKey = getFontKey(triplet);
+ boolean pclFont = getPCLUtil().isAllTextAsBitmaps() ? false
: HardcodedFonts.setFont(gen, fontKey, state.getFontSize(), text);
if (pclFont) {
drawTextNative(x, y, letterSpacing, wordSpacing, dp, text, triplet);
@@ -354,7 +344,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
setCursorPos(x, y);
float fontSize = state.getFontSize() / 1000f;
- Font font = parent.getFontInfo().getFontInstance(triplet, state.getFontSize());
+ Font font = getFontInfo().getFontInstance(triplet, state.getFontSize());
int l = text.length();
int[] dx = IFUtil.convertDPToDX ( dp );
int dxl = (dx != null ? dx.length : 0);
@@ -446,11 +436,15 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
final int letterSpacing, final int wordSpacing, final int[][] dp,
final String text, FontTriplet triplet) throws IFException {
//Use Java2D to paint different fonts via bitmap
- final Font font = parent.getFontInfo().getFontInstance(triplet, state.getFontSize());
+ final Font font = getFontInfo().getFontInstance(triplet, state.getFontSize());
//for cursive fonts, so the text isn't clipped
- final FontMetricsMapper mapper = (FontMetricsMapper)parent.getFontInfo().getMetricsFor(
- font.getFontName());
+ FontMetricsMapper mapper;
+ try {
+ mapper = (FontMetricsMapper) getFontInfo().getMetricsFor(font.getFontName());
+ } catch (Exception t) {
+ throw new RuntimeException(t);
+ }
final int maxAscent = mapper.getMaxAscent(font.getFontSize()) / 1000;
final int ascent = mapper.getAscender(font.getFontSize()) / 1000;
final int descent = mapper.getDescender(font.getFontSize()) / 1000;
@@ -478,8 +472,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
rect = new Rectangle(x, y, 1000, -descent);
g2d.draw(rect);
}
- Java2DPainter painter = new Java2DPainter(g2d,
- getContext(), parent.getFontInfo(), state);
+ Java2DPainter painter = new Java2DPainter(g2d, getContext(), getFontInfo(), state);
try {
painter.drawText(x, y, letterSpacing, wordSpacing, dp, text);
} catch (IFException e) {
@@ -504,7 +497,7 @@ public class PCLPainter extends AbstractIFPainter implements PCLConstants {
/** Restores the last graphics state from the stack. */
private void restoreGraphicsState() {
- graphicContext = (GraphicContext)graphicContextStack.pop();
+ graphicContext = graphicContextStack.pop();
}
private void concatenateTransformationMatrix(AffineTransform transform) throws IOException {
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java
new file mode 100644
index 000000000..29fccc2c8
--- /dev/null
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfig.java
@@ -0,0 +1,123 @@
+/*
+ * 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 java.util.EnumMap;
+import java.util.Map;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfig;
+
+import static org.apache.fop.render.pcl.Java2DRendererOption.DISABLE_PJL;
+import static org.apache.fop.render.pcl.Java2DRendererOption.RENDERING_MODE;
+import static org.apache.fop.render.pcl.Java2DRendererOption.TEXT_RENDERING;
+
+/**
+ * The PCL renderer configuration data object.
+ */
+public final class PCLRendererConfig implements RendererConfig {
+
+ private final Map<Java2DRendererOption, Object> params
+ = new EnumMap<Java2DRendererOption, Object>(Java2DRendererOption.class);
+
+ private final DefaultFontConfig fontConfig;
+
+ private PCLRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public PCLRenderingMode getRenderingMode() {
+ return getParam(RENDERING_MODE, PCLRenderingMode.class);
+ }
+
+ public Boolean isTextRendering() {
+ return getParam(TEXT_RENDERING, Boolean.class);
+ }
+
+ public Boolean isDisablePjl() {
+ return getParam(DISABLE_PJL, Boolean.class);
+ }
+
+ private <T> T getParam(Java2DRendererOption option, Class<T> type) {
+ assert option.getType().equals(type);
+ return type.cast(params.get(option));
+ }
+
+ private <T> void setParam(Java2DRendererOption option, T value) {
+ assert option.getType().isInstance(value);
+ params.put(option, value);
+ }
+
+ /**
+ * The PCL renderer configuration data parser.
+ */
+ public static final class PCLRendererConfigParser implements RendererConfigParser {
+
+ /** {@inheritDoc} */
+ public PCLRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ PCLRendererConfig config = new PCLRendererConfig(new DefaultFontConfigParser()
+ .parse(cfg, userAgent.validateStrictly()));
+ configure(cfg, config);
+ return config;
+ }
+
+ private void configure(Configuration cfg, PCLRendererConfig config) throws FOPException {
+ if (cfg != null) {
+ String rendering = cfg.getChild(RENDERING_MODE.getName()).getValue(null);
+ if (rendering != null) {
+ try {
+ config.setParam(RENDERING_MODE, PCLRenderingMode.getValueOf(rendering));
+ } catch (IllegalArgumentException e) {
+ throw new FOPException("Valid values for 'rendering' are 'quality', 'speed' and 'bitmap'."
+ + " Value found: " + rendering);
+ }
+ }
+ String textRendering = cfg.getChild(TEXT_RENDERING.getName()).getValue(null);
+ if ("bitmap".equalsIgnoreCase(textRendering)) {
+ config.setParam(TEXT_RENDERING, true);
+ } else if (textRendering == null || "auto".equalsIgnoreCase(textRendering)) {
+ config.setParam(TEXT_RENDERING, false);
+ } else {
+ throw new FOPException(
+ "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: "
+ + textRendering);
+ }
+ config.setParam(DISABLE_PJL,
+ cfg.getChild(DISABLE_PJL.getName()).getValueAsBoolean(false));
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_PCL;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
index bc4cdc567..d103b4796 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRendererConfigurator.java
@@ -21,19 +21,13 @@ package org.apache.fop.render.pcl;
import java.util.List;
-import org.apache.avalon.framework.configuration.Configuration;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.FontCollection;
-import org.apache.fop.fonts.FontEventAdapter;
-import org.apache.fop.fonts.FontEventListener;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontResolver;
-import org.apache.fop.render.DefaultFontResolver;
import org.apache.fop.render.PrintRendererConfigurator;
-import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.java2d.Base14FontCollection;
@@ -45,88 +39,52 @@ import org.apache.fop.render.java2d.Java2DFontMetrics;
* PCL Renderer configurator
*/
public class PCLRendererConfigurator extends PrintRendererConfigurator
- implements IFDocumentHandlerConfigurator {
+ implements IFDocumentHandlerConfigurator {
/**
* Default constructor
* @param userAgent user agent
*/
- public PCLRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
- }
-
- /**
- * Throws an UnsupportedOperationException.
- *
- * @param renderer not used
- */
- public void configure(Renderer renderer) {
- throw new UnsupportedOperationException();
- }
-
- private void configure(Configuration cfg, PCLRenderingUtil pclUtil) throws FOPException {
- String rendering = cfg.getChild("rendering").getValue(null);
- if (rendering != null) {
- try {
- pclUtil.setRenderingMode(PCLRenderingMode.valueOf(rendering));
- } catch (IllegalArgumentException e) {
- throw new FOPException(
- "Valid values for 'rendering' are 'quality', 'speed' and 'bitmap'."
- + " Value found: " + rendering);
- }
- }
-
- String textRendering = cfg.getChild("text-rendering").getValue(null);
- if ("bitmap".equalsIgnoreCase(textRendering)) {
- pclUtil.setAllTextAsBitmaps(true);
- } else if ("auto".equalsIgnoreCase(textRendering)) {
- pclUtil.setAllTextAsBitmaps(false);
- } else if (textRendering != null) {
- throw new FOPException(
- "Valid values for 'text-rendering' are 'auto' and 'bitmap'. Value found: "
- + textRendering);
- }
-
- pclUtil.setPJLDisabled(cfg.getChild("disable-pjl").getValueAsBoolean(false));
+ public PCLRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
- // ---=== IFDocumentHandler configuration ===---
-
/** {@inheritDoc} */
public void configure(IFDocumentHandler documentHandler) throws FOPException {
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- PCLDocumentHandler pclDocumentHandler = (PCLDocumentHandler)documentHandler;
+ PCLRendererConfig pdfConfig = (PCLRendererConfig) getRendererConfig(documentHandler);
+ if (pdfConfig != null) {
+ PCLDocumentHandler pclDocumentHandler = (PCLDocumentHandler) documentHandler;
PCLRenderingUtil pclUtil = pclDocumentHandler.getPCLUtil();
- configure(cfg, pclUtil);
+ configure(pdfConfig, pclUtil);
}
}
- /** {@inheritDoc} */
- public void setupFontInfo(IFDocumentHandler documentHandler, FontInfo fontInfo)
- throws FOPException {
- FontManager fontManager = userAgent.getFactory().getFontManager();
+ private void configure(PCLRendererConfig config, PCLRenderingUtil pclUtil) throws FOPException {
+ if (config.getRenderingMode() != null) {
+ pclUtil.setRenderingMode(config.getRenderingMode());
+ }
+ if (config.isDisablePjl() != null) {
+ pclUtil.setPJLDisabled(config.isDisablePjl());
+ }
+ if (config.isTextRendering() != null) {
+ pclUtil.setAllTextAsBitmaps(config.isTextRendering());
+ }
+ }
+ @Override
+ protected List<FontCollection> getDefaultFontCollection() {
+ final List<FontCollection> fontCollections = new java.util.ArrayList<FontCollection>();
final Java2DFontMetrics java2DFontMetrics = new Java2DFontMetrics();
- final List fontCollections = new java.util.ArrayList();
fontCollections.add(new Base14FontCollection(java2DFontMetrics));
fontCollections.add(new InstalledFontCollection(java2DFontMetrics));
-
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- FontResolver fontResolver = new DefaultFontResolver(userAgent);
- FontEventListener listener = new FontEventAdapter(
- userAgent.getEventBroadcaster());
- List fontList = buildFontList(cfg, fontResolver, listener);
- fontCollections.add(new ConfiguredFontCollection(fontResolver, fontList,
- userAgent.isComplexScriptFeaturesEnabled()));
- }
-
- fontManager.setup(fontInfo,
- (FontCollection[])fontCollections.toArray(
- new FontCollection[fontCollections.size()]));
- documentHandler.setFontInfo(fontInfo);
+ return fontCollections;
}
+ @Override
+ protected FontCollection createCollectionFromFontList(InternalResourceResolver resourceResolver,
+ List<EmbedFontInfo> fontList) {
+ return new ConfiguredFontCollection(resourceResolver, fontList,
+ userAgent.isComplexScriptFeaturesEnabled());
+ }
}
diff --git a/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java b/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
index 6201197cf..afea5a7fe 100644
--- a/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
+++ b/src/java/org/apache/fop/render/pcl/PCLRenderingMode.java
@@ -20,25 +20,22 @@
package org.apache.fop.render.pcl;
import java.io.ObjectStreamException;
-import java.io.Serializable;
/**
* Enumeration class for PCL rendering modes.
*/
-public final class PCLRenderingMode implements Serializable {
-
- private static final long serialVersionUID = 6359884255324755026L;
-
+public enum PCLRenderingMode {
/** "Quality" rendering (mixed native and bitmap for improved quality) */
- public static final PCLRenderingMode QUALITY = new PCLRenderingMode("quality", 1.0f);
+ QUALITY("quality", 1.0f),
/** "Speed" rendering (maximum speed with native rendering, reduced visual quality) */
- public static final PCLRenderingMode SPEED = new PCLRenderingMode("speed", 0.25f);
+ SPEED("speed", 0.25f),
/**
* "Bitmap" rendering (pages are painted entirely as bitmaps, maximum quality,
* reduced performance)
*/
- public static final PCLRenderingMode BITMAP = new PCLRenderingMode("bitmap", 1.0f);
+ BITMAP("bitmap", 1.0f);
+ private static final long serialVersionUID = 6359884255324755026L;
private String name;
private float defaultDitheringQuality;
@@ -70,20 +67,17 @@ public final class PCLRenderingMode implements Serializable {
* @param name the name of the enumeration value
* @return the enumeration object
*/
- public static PCLRenderingMode valueOf(String name) {
- if (QUALITY.getName().equalsIgnoreCase(name)) {
- return QUALITY;
- } else if (SPEED.getName().equalsIgnoreCase(name)) {
- return SPEED;
- } else if (BITMAP.getName().equalsIgnoreCase(name)) {
- return BITMAP;
- } else {
- throw new IllegalArgumentException("Illegal value for enumeration: " + name);
+ public static PCLRenderingMode getValueOf(String name) {
+ for (PCLRenderingMode mode : PCLRenderingMode.values()) {
+ if (mode.getName().equalsIgnoreCase(name)) {
+ return mode;
+ }
}
+ throw new IllegalArgumentException("Illegal value for enumeration: " + name);
}
private Object readResolve() throws ObjectStreamException {
- return valueOf(getName());
+ return getValueOf(getName());
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java b/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
deleted file mode 100644
index 4a8a03b27..000000000
--- a/src/java/org/apache/fop/render/pdf/PDFConfigurationConstants.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.render.pdf;
-
-/**
- * Constants used for configuring PDF output.
- */
-public interface PDFConfigurationConstants {
-
- /** PDF encryption parameter: all parameters as object, datatype: PDFEncryptionParams */
- String ENCRYPTION_PARAMS = "encryption-params";
- /** PDF encryption parameter: user password, datatype: String */
- String USER_PASSWORD = "user-password";
- /** PDF encryption parameter: owner password, datatype: String */
- String OWNER_PASSWORD = "owner-password";
- /** PDF encryption parameter: Forbids printing, datatype: Boolean or "true"/"false" */
- String NO_PRINT = "noprint";
- /** PDF encryption parameter: Forbids copying content, datatype: Boolean or "true"/"false" */
- String NO_COPY_CONTENT = "nocopy";
- /** PDF encryption parameter: Forbids editing content, datatype: Boolean or "true"/"false" */
- String NO_EDIT_CONTENT = "noedit";
- /** PDF encryption parameter: Forbids annotations, datatype: Boolean or "true"/"false" */
- String NO_ANNOTATIONS = "noannotations";
-
- /**
- * PDF encryption parameter: Forbids filling in existing interactive forms, datatype:
- * Boolean or "true"/"false"
- */
- String NO_FILLINFORMS = "nofillinforms";
-
- /**
- * PDF encryption parameter: Forbids extracting text and graphics, datatype: Boolean
- * or "true"/"false"
- */
- String NO_ACCESSCONTENT = "noaccesscontent";
-
- /**
- * PDF encryption parameter: Forbids assembling document, datatype: Boolean or
- * "true"/"false"
- */
- String NO_ASSEMBLEDOC = "noassembledoc";
-
- /**
- * PDF encryption parameter: Forbids printing to high quality, datatype: Boolean or
- * "true"/"false"
- */
- String NO_PRINTHQ = "noprinthq";
-
- /**
- * PDF encryption length parameter: must be a multiple of 8 between 40 and 128,
- * default value 40, datatype: int.
- */
- String ENCRYPTION_LENGTH = "encryption-length";
- /** Rendering Options key for the PDF/A mode. */
- String PDF_A_MODE = "pdf-a-mode";
- /** Rendering Options key for the PDF/X mode. */
- String PDF_X_MODE = "pdf-x-mode";
- /** Rendering Options key for the ICC profile for the output intent. */
- String KEY_OUTPUT_PROFILE = "output-profile";
- /** PDF version entry: specify the version of the PDF document created, datatype: String */
- String PDF_VERSION = "version";
- /**
- * Rendering Options key for disabling the sRGB color space (only possible if no PDF/A or
- * PDF/X profile is active).
- */
- String KEY_DISABLE_SRGB_COLORSPACE = "disable-srgb-colorspace";
-}
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
index 5be8c3001..dd9320571 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
@@ -40,7 +40,6 @@ import org.apache.fop.fo.extensions.xmp.XMPMetadata;
import org.apache.fop.pdf.PDFAnnotList;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFPage;
-import org.apache.fop.pdf.PDFResourceContext;
import org.apache.fop.pdf.PDFResources;
import org.apache.fop.render.extensions.prepress.PageBoundaries;
import org.apache.fop.render.extensions.prepress.PageScale;
@@ -50,6 +49,7 @@ import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.intermediate.IFDocumentNavigationHandler;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment;
/**
@@ -67,31 +67,28 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
private PDFStructureTreeBuilder structureTreeBuilder;
/** the PDF Document being created */
- protected PDFDocument pdfDoc;
+ private PDFDocument pdfDoc;
/**
* Utility class which enables all sorts of features that are not directly connected to the
* normal rendering process.
*/
- protected PDFRenderingUtil pdfUtil;
+ private final PDFRenderingUtil pdfUtil;
/** the /Resources object of the PDF document being created */
- protected PDFResources pdfResources;
+ private PDFResources pdfResources;
/** The current content generator */
- protected PDFContentGenerator generator;
-
- /** the current annotation list to add annotations to */
- protected PDFResourceContext currentContext;
+ private PDFContentGenerator generator;
/** the current page to add annotations to */
- protected PDFPage currentPage;
+ private PDFPage currentPage;
/** the current page's PDF reference */
- protected PageReference currentPageRef;
+ private PageReference currentPageRef;
/** Used for bookmarks/outlines. */
- protected Map<Integer, PageReference> pageReferences = new HashMap<Integer, PageReference>();
+ private Map<Integer, PageReference> pageReferences = new HashMap<Integer, PageReference>();
private final PDFDocumentNavigationHandler documentNavigationHandler
= new PDFDocumentNavigationHandler(this);
@@ -99,7 +96,9 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
/**
* Default constructor.
*/
- public PDFDocumentHandler() {
+ public PDFDocumentHandler(IFContext context) {
+ super(context);
+ this.pdfUtil = new PDFRenderingUtil(context.getUserAgent());
}
/** {@inheritDoc} */
@@ -113,14 +112,8 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
}
/** {@inheritDoc} */
- public void setContext(IFContext context) {
- super.setContext(context);
- this.pdfUtil = new PDFRenderingUtil(context.getUserAgent());
- }
-
- /** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new PDFRendererConfigurator(getUserAgent());
+ return new PDFRendererConfigurator(getUserAgent(), new PDFRendererConfigParser());
}
/** {@inheritDoc} */
@@ -128,14 +121,30 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
return this.documentNavigationHandler;
}
- PDFRenderingUtil getPDFUtil() {
- return this.pdfUtil;
+ void mergeRendererOptionsConfig(PDFRendererOptionsConfig config) {
+ pdfUtil.mergeRendererOptionsConfig(config);
}
PDFLogicalStructureHandler getLogicalStructureHandler() {
return logicalStructureHandler;
}
+ PDFDocument getPDFDocument() {
+ return pdfDoc;
+ }
+
+ PDFPage getCurrentPage() {
+ return currentPage;
+ }
+
+ PageReference getCurrentPageRef() {
+ return currentPageRef;
+ }
+
+ PDFContentGenerator getGenerator() {
+ return generator;
+ }
+
/** {@inheritDoc} */
public void startDocument() throws IFException {
super.startDocument();
@@ -174,7 +183,6 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
pdfResources = null;
this.generator = null;
- currentContext = null;
currentPage = null;
} catch (IOException ioe) {
throw new IFException("I/O error in endDocument()", ioe);
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java b/src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java
index 1186db3ae..ceab6f54a 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentHandlerMaker.java
@@ -32,10 +32,10 @@ public class PDFDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PDF};
- /** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- PDFDocumentHandler handler = new PDFDocumentHandler();
- handler.setContext(new IFContext(ua));
+ @Override
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ PDFDocumentHandler handler = new PDFDocumentHandler(ifContext);
+ FOUserAgent ua = ifContext.getUserAgent();
if (ua.isAccessibilityEnabled()) {
ua.setStructureTreeEventHandler(handler.getStructureTreeEventHandler());
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
index af49fea4c..1ef637726 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentNavigationHandler.java
@@ -63,7 +63,7 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
}
PDFDocument getPDFDoc() {
- return this.documentHandler.pdfDoc;
+ return this.documentHandler.getPDFDocument();
}
/** {@inheritDoc} */
@@ -100,7 +100,7 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
/** {@inheritDoc} */
public void renderLink(Link link) throws IFException {
Rectangle targetRect = link.getTargetRect();
- int pageHeight = documentHandler.currentPageRef.getPageDimension().height;
+ int pageHeight = documentHandler.getCurrentPageRef().getPageDimension().height;
Rectangle2D targetRect2D = new Rectangle2D.Double(
targetRect.getMinX() / 1000.0,
(pageHeight - targetRect.getMinY() - targetRect.getHeight()) / 1000.0,
@@ -116,7 +116,7 @@ public class PDFDocumentNavigationHandler implements IFDocumentNavigationHandler
if (documentHandler.getUserAgent().isAccessibilityEnabled() && structure != null) {
documentHandler.getLogicalStructureHandler().addLinkContentItem(pdfLink, structure);
}
- documentHandler.currentPage.addAnnotation(pdfLink);
+ documentHandler.getCurrentPage().addAnnotation(pdfLink);
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFEncryptionOption.java b/src/java/org/apache/fop/render/pdf/PDFEncryptionOption.java
new file mode 100644
index 000000000..f3e51e34a
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFEncryptionOption.java
@@ -0,0 +1,98 @@
+/*
+ * 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 org.apache.fop.render.RendererConfigOption;
+
+public enum PDFEncryptionOption implements RendererConfigOption {
+
+ /**
+ * PDF encryption length parameter: must be a multiple of 8 between 40 and 128,
+ * default value 40, datatype: int, default: 40
+ */
+ ENCRYPTION_LENGTH("encryption-length", 40),
+ /**
+ * PDF encryption parameter: Forbids printing to high quality, datatype: Boolean or
+ * "true"/"false", default: false
+ */
+ NO_PRINTHQ("noprinthq", 40),
+ /**
+ * PDF encryption parameter: Forbids assembling document, datatype: Boolean or
+ * "true"/"false", default: false
+ */
+ NO_ASSEMBLEDOC("noassembledoc", false),
+ /**
+ * PDF encryption parameter: Forbids extracting text and graphics, datatype: Boolean
+ * or "true"/"false", default: false
+ */
+ NO_ACCESSCONTENT("noaccesscontent", false),
+ /**
+ * PDF encryption parameter: Forbids filling in existing interactive forms, datatype:
+ * Boolean or "true"/"false", default: false
+ */
+ NO_FILLINFORMS("nofillinforms", false),
+ /**
+ * PDF encryption parameter: Forbids annotations, datatype: Boolean or "true"/"false",
+ * default: false
+ */
+ NO_ANNOTATIONS("noannotations", false),
+ /**
+ * PDF encryption parameter: Forbids printing, datatype: Boolean or "true"/"false",
+ * default: false
+ */
+ NO_PRINT("noprint", false),
+ /**
+ * PDF encryption parameter: Forbids copying content, datatype: Boolean or "true"/"false",
+ * default: false
+ */
+ NO_COPY_CONTENT("nocopy", false),
+ /**
+ * PDF encryption parameter: Forbids editing content, datatype: Boolean or "true"/"false",
+ * default: false
+ */
+ NO_EDIT_CONTENT("noedit", false),
+ /** PDF encryption parameter: user password, datatype: String, default: "" */
+ USER_PASSWORD("user-password", ""),
+ /** PDF encryption parameter: owner password, datatype: String, default: "" */
+ OWNER_PASSWORD("owner-password", "");
+
+ public static final String ENCRYPTION_PARAMS = "encryption-params";
+
+ private final String name;
+
+ private final Object defaultValue;
+
+ private PDFEncryptionOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ private PDFEncryptionOption(String name) {
+ this(name, null);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
index bc3b66ece..8eaac923c 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
@@ -86,7 +86,7 @@ public class PDFImageHandlerSVG implements ImageHandler {
BridgeContext ctx = new PDFBridgeContext(ua,
(strokeText ? null : pdfContext.getFontInfo()),
- userAgent.getFactory().getImageManager(),
+ userAgent.getImageManager(),
userAgent.getImageSessionContext(),
new AffineTransform());
diff --git a/src/java/org/apache/fop/render/pdf/PDFPainter.java b/src/java/org/apache/fop/render/pdf/PDFPainter.java
index d7a335dcc..77ec1d3bf 100644
--- a/src/java/org/apache/fop/render/pdf/PDFPainter.java
+++ b/src/java/org/apache/fop/render/pdf/PDFPainter.java
@@ -30,19 +30,16 @@ import java.io.IOException;
import org.w3c.dom.Document;
import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
-import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFNumber;
import org.apache.fop.pdf.PDFStructElem;
import org.apache.fop.pdf.PDFTextUtil;
import org.apache.fop.pdf.PDFXObject;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
-import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -55,9 +52,7 @@ import org.apache.fop.util.CharUtilities;
/**
* IFPainter implementation that produces PDF.
*/
-public class PDFPainter extends AbstractIFPainter {
-
- private final PDFDocumentHandler documentHandler;
+public class PDFPainter extends AbstractIFPainter<PDFDocumentHandler> {
/** The current content generator */
protected PDFContentGenerator generator;
@@ -77,34 +72,15 @@ public class PDFPainter extends AbstractIFPainter {
*/
public PDFPainter(PDFDocumentHandler documentHandler,
PDFLogicalStructureHandler logicalStructureHandler) {
- super();
- this.documentHandler = documentHandler;
+ super(documentHandler);
this.logicalStructureHandler = logicalStructureHandler;
- this.generator = documentHandler.generator;
+ this.generator = documentHandler.getGenerator();
this.borderPainter = new PDFBorderPainter(this.generator);
this.state = IFState.create();
accessEnabled = this.getUserAgent().isAccessibilityEnabled();
}
/** {@inheritDoc} */
- @Override
- protected IFContext getContext() {
- return this.documentHandler.getContext();
- }
-
- PDFRenderingUtil getPDFUtil() {
- return this.documentHandler.pdfUtil;
- }
-
- PDFDocument getPDFDoc() {
- return this.documentHandler.pdfDoc;
- }
-
- FontInfo getFontInfo() {
- return this.documentHandler.getFontInfo();
- }
-
- /** {@inheritDoc} */
public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
throws IFException {
generator.saveGraphicsState();
@@ -133,7 +109,7 @@ public class PDFPainter extends AbstractIFPainter {
/** {@inheritDoc} */
public void drawImage(String uri, Rectangle rect)
throws IFException {
- PDFXObject xobject = getPDFDoc().getXObject(uri);
+ PDFXObject xobject = getDocumentHandler().getPDFDocument().getXObject(uri);
if (xobject != null) {
if (accessEnabled) {
PDFStructElem structElem = (PDFStructElem) getContext().getStructureTreeElement();
@@ -160,7 +136,7 @@ public class PDFPainter extends AbstractIFPainter {
@Override
protected RenderingContext createRenderingContext() {
PDFRenderingContext pdfContext = new PDFRenderingContext(
- getUserAgent(), generator, this.documentHandler.currentPage, getFontInfo());
+ getUserAgent(), generator, getDocumentHandler().getCurrentPage(), getFontInfo());
pdfContext.setMarkedContentInfo(imageMCI);
return pdfContext;
}
@@ -334,12 +310,11 @@ public class PDFPainter extends AbstractIFPainter {
}
}
- private void drawTextWithDX ( int x, int y, String text, FontTriplet triplet,
- int letterSpacing, int wordSpacing, int[] dx ) {
-
+ private void drawTextWithDX(int x, int y, String text, FontTriplet triplet,
+ int letterSpacing, int wordSpacing, int[] dx) throws IFException {
//TODO Ignored: state.getFontVariant()
//TODO Opportunity for font caching if font state is more heavily used
- String fontKey = getFontInfo().getInternalFontKey(triplet);
+ String fontKey = getFontKey(triplet);
int sizeMillipoints = state.getFontSize();
float fontSize = sizeMillipoints / 1000f;
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
new file mode 100644
index 000000000..049345609
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfig.java
@@ -0,0 +1,227 @@
+/*
+ * 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.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+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.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.MimeConstants;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.pdf.PDFEncryptionParams;
+import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.RendererConfigOption;
+import org.apache.fop.util.LogUtil;
+
+import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_LENGTH;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ACCESSCONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ANNOTATIONS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ASSEMBLEDOC;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_COPY_CONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_EDIT_CONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_FILLINFORMS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINTHQ;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.OWNER_PASSWORD;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.USER_PASSWORD;
+import static org.apache.fop.render.pdf.PDFRendererOption.DISABLE_SRGB_COLORSPACE;
+import static org.apache.fop.render.pdf.PDFRendererOption.FILTER_LIST;
+import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
+
+/**
+ * The PDF renderer configuration data object.
+ */
+public final class PDFRendererConfig implements RendererConfig {
+
+ private static final Log LOG = LogFactory.getLog(PDFRendererConfig.class);
+
+ private final PDFRendererOptionsConfig configOption;
+
+ private final DefaultFontConfig fontConfig;
+
+ private PDFRendererConfig(DefaultFontConfig fontConfig, PDFRendererOptionsConfig config) {
+ this.fontConfig = fontConfig;
+ this.configOption = config;
+ }
+
+ public PDFRendererOptionsConfig getConfigOptions() {
+ return configOption;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ /**
+ * The PDF renderer configuration data parser.
+ */
+ public static final class PDFRendererConfigParser implements RendererConfigParser {
+
+ public PDFRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ boolean strict = userAgent != null ? userAgent.validateUserConfigStrictly() : false;
+ return new ParserHelper(cfg, userAgent, strict).pdfConfig;
+ }
+
+ public String getMimeType() {
+ return MimeConstants.MIME_PDF;
+ }
+ }
+
+ private static final class ParserHelper {
+
+ private final Map<PDFRendererOption, Object> configOptions
+ = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
+
+ private PDFEncryptionParams encryptionConfig;
+
+ private PDFRendererConfig pdfConfig;
+
+ private ParserHelper(Configuration cfg, FOUserAgent userAgent, boolean strict) throws FOPException {
+ if (cfg != null) {
+ configure(cfg, userAgent, strict);
+ }
+ pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict),
+ new PDFRendererOptionsConfig(configOptions, encryptionConfig));
+ }
+
+ private void parseAndPut(PDFRendererOption option, Configuration cfg) {
+ put(option, option.parse(parseConfig(cfg, option)));
+ }
+
+ private void put(PDFRendererOption option, Object value) {
+ if (value != null && !value.equals(option.getDefaultValue())) {
+ configOptions.put(option, value);
+ }
+ }
+
+ private void configure(Configuration cfg, FOUserAgent userAgent, boolean strict) throws FOPException {
+ try {
+ buildFilterMapFromConfiguration(cfg);
+ parseAndPut(PDF_A_MODE, cfg);
+ parseAndPut(PDF_X_MODE, cfg);
+ configureEncryptionParams(cfg, userAgent, strict);
+ parseAndPut(OUTPUT_PROFILE, cfg);
+ parseAndPut(DISABLE_SRGB_COLORSPACE, cfg);
+
+ parseAndPut(VERSION, cfg);
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, strict);
+ }
+ }
+
+ private void configureEncryptionParams(Configuration cfg, FOUserAgent userAgent, boolean strict) {
+ Configuration encryptCfg = cfg.getChild(ENCRYPTION_PARAMS, false);
+ if (encryptCfg != null) {
+ encryptionConfig = new PDFEncryptionParams();
+ encryptionConfig.setOwnerPassword(parseConfig(encryptCfg, OWNER_PASSWORD));
+ encryptionConfig.setUserPassword(parseConfig(encryptCfg, USER_PASSWORD));
+ encryptionConfig.setAllowPrint(!doesValueExist(encryptCfg, NO_PRINT));
+ encryptionConfig.setAllowCopyContent(!doesValueExist(encryptCfg, NO_COPY_CONTENT));
+ encryptionConfig.setAllowEditContent(!doesValueExist(encryptCfg, NO_EDIT_CONTENT));
+ encryptionConfig.setAllowEditAnnotations(!doesValueExist(encryptCfg, NO_ANNOTATIONS));
+ encryptionConfig.setAllowFillInForms(!doesValueExist(encryptCfg, NO_FILLINFORMS));
+ encryptionConfig.setAllowAccessContent(!doesValueExist(encryptCfg, NO_ACCESSCONTENT));
+ encryptionConfig.setAllowAssembleDocument(!doesValueExist(encryptCfg, NO_ASSEMBLEDOC));
+ encryptionConfig.setAllowPrintHq(!doesValueExist(encryptCfg, NO_PRINTHQ));
+ String encryptionLength = parseConfig(encryptCfg, ENCRYPTION_LENGTH);
+ if (encryptionLength != null) {
+ int validatedLength = checkEncryptionLength(Integer.parseInt(encryptionLength), userAgent);
+ encryptionConfig.setEncryptionLengthInBits(validatedLength);
+ }
+ }
+ }
+
+ private void buildFilterMapFromConfiguration(Configuration cfg) throws ConfigurationException,
+ FOPException {
+ Configuration[] filterLists = cfg.getChildren(FILTER_LIST.getName());
+ Map<String, List<String>> filterMap = new HashMap<String, List<String>>();
+ for (Configuration filters : filterLists) {
+ String type = filters.getAttribute("type", PDFFilterList.DEFAULT_FILTER);
+ List<String> filterList = new ArrayList<String>();
+ for (Configuration nameCfg : filters.getChildren("value")) {
+ filterList.add(nameCfg.getValue());
+ }
+ 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));
+ }
+ LogUtil.handleError(LOG, debug.toString(), true);
+ }
+
+ if (filterMap.get(type) != null) {
+ throw new ConfigurationException("A filterList of type '"
+ + type + "' has already been defined");
+ }
+ filterMap.put(type, filterList);
+ }
+ put(FILTER_LIST, filterMap);
+ }
+
+ private String parseConfig(Configuration cfg, RendererConfigOption option) {
+ Configuration child = cfg.getChild(option.getName());
+ return child.getValue(null);
+ }
+
+ private boolean doesValueExist(Configuration cfg, RendererConfigOption option) {
+ return cfg.getChild(option.getName(), false) != null;
+ }
+
+ private int checkEncryptionLength(int encryptionLength, FOUserAgent userAgent) {
+ int correctEncryptionLength = encryptionLength;
+ if (encryptionLength < 40) {
+ correctEncryptionLength = 40;
+ } else if (encryptionLength > 128) {
+ correctEncryptionLength = 128;
+ } else if (encryptionLength % 8 != 0) {
+ correctEncryptionLength = Math.round(encryptionLength / 8.0f) * 8;
+ }
+ if (correctEncryptionLength != encryptionLength && userAgent != null) {
+ PDFEventProducer.Provider.get(userAgent.getEventBroadcaster())
+ .incorrectEncryptionLength(this, encryptionLength,
+ correctEncryptionLength);
+ }
+ return correctEncryptionLength;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
index df5224c04..96a19db6a 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
@@ -19,239 +19,30 @@
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.PDFEncryptionParams;
-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.render.DefaultRendererConfigurator;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
-import org.apache.fop.util.LogUtil;
/**
* PDF renderer configurator.
*/
-public class PDFRendererConfigurator extends PrintRendererConfigurator {
+public class PDFRendererConfigurator extends DefaultRendererConfigurator {
/**
* Default constructor
*
* @param userAgent user agent
*/
- public PDFRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
- }
-
- /**
- * Throws an UnsupportedOperationException.
- *
- * @param renderer not used
- */
- public void configure(Renderer renderer) {
- throw new UnsupportedOperationException();
+ public PDFRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
- private void configure(Configuration cfg, PDFRenderingUtil pdfUtil) throws FOPException {
- //PDF filters
- try {
- Map filterMap = buildFilterMapFromConfiguration(cfg);
- if (filterMap != null) {
- pdfUtil.setFilterMap(filterMap);
- }
- } catch (ConfigurationException e) {
- LogUtil.handleException(log, e, false);
- }
-
- String s = cfg.getChild(PDFConfigurationConstants.PDF_A_MODE, true).getValue(null);
- if (s != null) {
- pdfUtil.setAMode(PDFAMode.valueOf(s));
- }
- s = cfg.getChild(PDFConfigurationConstants.PDF_X_MODE, true).getValue(null);
- if (s != null) {
- pdfUtil.setXMode(PDFXMode.valueOf(s));
- }
- Configuration encryptionParamsConfig
- = cfg.getChild(PDFConfigurationConstants.ENCRYPTION_PARAMS, false);
- if (encryptionParamsConfig != null) {
- PDFEncryptionParams encryptionParams = pdfUtil.getEncryptionParams();
- Configuration ownerPasswordConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.OWNER_PASSWORD, false);
- if (ownerPasswordConfig != null) {
- String ownerPassword = ownerPasswordConfig.getValue(null);
- if (ownerPassword != null) {
- encryptionParams.setOwnerPassword(ownerPassword);
- }
- }
- Configuration userPasswordConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.USER_PASSWORD, false);
- if (userPasswordConfig != null) {
- String userPassword = userPasswordConfig.getValue(null);
- if (userPassword != null) {
- encryptionParams.setUserPassword(userPassword);
- }
- }
- Configuration noPrintConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_PRINT, false);
- if (noPrintConfig != null) {
- encryptionParams.setAllowPrint(false);
- }
- Configuration noCopyContentConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_COPY_CONTENT, false);
- if (noCopyContentConfig != null) {
- encryptionParams.setAllowCopyContent(false);
- }
- Configuration noEditContentConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_EDIT_CONTENT, false);
- if (noEditContentConfig != null) {
- encryptionParams.setAllowEditContent(false);
- }
- Configuration noAnnotationsConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_ANNOTATIONS, false);
- if (noAnnotationsConfig != null) {
- encryptionParams.setAllowEditAnnotations(false);
- }
- Configuration noFillInForms = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_FILLINFORMS, false);
- if (noFillInForms != null) {
- encryptionParams.setAllowFillInForms(false);
- }
- Configuration noAccessContentConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_ACCESSCONTENT, false);
- if (noAccessContentConfig != null) {
- encryptionParams.setAllowAccessContent(false);
- }
- Configuration noAssembleDocConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_ASSEMBLEDOC, false);
- if (noAssembleDocConfig != null) {
- encryptionParams.setAllowAssembleDocument(false);
- }
- Configuration noPrintHqConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.NO_PRINTHQ, false);
- if (noPrintHqConfig != null) {
- encryptionParams.setAllowPrintHq(false);
- }
- Configuration encryptionLengthConfig = encryptionParamsConfig.getChild(
- PDFConfigurationConstants.ENCRYPTION_LENGTH, false);
- if (encryptionLengthConfig != null) {
- int encryptionLength = checkEncryptionLength(
- Integer.parseInt(encryptionLengthConfig.getValue(null)));
- encryptionParams.setEncryptionLengthInBits(encryptionLength);
- }
- }
-
- s = cfg.getChild(PDFConfigurationConstants.KEY_OUTPUT_PROFILE, true).getValue(null);
- if (s != null) {
- pdfUtil.setOutputProfileURI(s);
- }
- Configuration disableColorSpaceConfig = cfg.getChild(
- PDFConfigurationConstants.KEY_DISABLE_SRGB_COLORSPACE, false);
- if (disableColorSpaceConfig != null) {
- pdfUtil.setDisableSRGBColorSpace(
- disableColorSpaceConfig.getValueAsBoolean(false));
- }
-
- setPDFDocVersion(cfg, pdfUtil);
- }
-
- private int checkEncryptionLength(int encryptionLength) {
- int correctEncryptionLength = encryptionLength;
- if (encryptionLength < 40) {
- correctEncryptionLength = 40;
- } else if (encryptionLength > 128) {
- correctEncryptionLength = 128;
- } else if (encryptionLength % 8 != 0) {
- correctEncryptionLength = ((int) Math.round(encryptionLength / 8.0f)) * 8;
- }
- if (correctEncryptionLength != encryptionLength) {
- PDFEventProducer.Provider.get(userAgent.getEventBroadcaster())
- .incorrectEncryptionLength(this, encryptionLength, correctEncryptionLength);
- }
- return correctEncryptionLength;
- }
-
- private void setPDFDocVersion(Configuration cfg, PDFRenderingUtil pdfUtil) throws FOPException {
- Configuration pdfVersion = cfg.getChild(PDFConfigurationConstants.PDF_VERSION, false);
- if (pdfVersion != null) {
- String version = pdfVersion.getValue(null);
- if (version != null && version.length() != 0) {
- try {
- pdfUtil.setPDFVersion(version);
- } catch (IllegalArgumentException e) {
- throw new FOPException(e.getMessage());
- }
- } else {
- throw new FOPException("The PDF version has not been set.");
- }
- }
- }
-
- /**
- * 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;
- }
-
- // ---=== IFDocumentHandler configuration ===---
-
/** {@inheritDoc} */
public void configure(IFDocumentHandler documentHandler) throws FOPException {
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- PDFDocumentHandler pdfDocumentHandler = (PDFDocumentHandler)documentHandler;
- PDFRenderingUtil pdfUtil = pdfDocumentHandler.getPDFUtil();
- configure(cfg, pdfUtil);
- }
+ ((PDFDocumentHandler) documentHandler).mergeRendererOptionsConfig(
+ ((PDFRendererConfig) getRendererConfig(documentHandler)).getConfigOptions());
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererOption.java b/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
new file mode 100644
index 000000000..2ebd691fe
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererOption.java
@@ -0,0 +1,112 @@
+/*
+ * 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.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFXMode;
+import org.apache.fop.pdf.Version;
+import org.apache.fop.render.RendererConfigOption;
+
+public enum PDFRendererOption implements RendererConfigOption {
+ FILTER_LIST("filterList", null) {
+ @Override
+ Object deserialize(String value) {
+ throw new UnsupportedOperationException();
+ }
+ },
+ /** Rendering Options key for the PDF/A mode, default: {@link PDFAMode#DISABLED} */
+ PDF_A_MODE("pdf-a-mode", PDFAMode.DISABLED) {
+ @Override
+ PDFAMode deserialize(String value) {
+ return PDFAMode.getValueOf(value);
+ }
+ },
+ /** Rendering Options key for the PDF/X mode, default: {@link PDFXMode#DISABLED} */
+ PDF_X_MODE("pdf-x-mode", PDFXMode.DISABLED) {
+ @Override
+ PDFXMode deserialize(String value) {
+ return PDFXMode.getValueOf(value);
+ }
+ },
+ /** PDF version entry: specify the version of the PDF document created, datatype: String */
+ VERSION("version") {
+ @Override
+ Version deserialize(String value) {
+ return Version.getValueOf(value);
+ }
+ },
+ /**
+ * Rendering Options key for disabling the sRGB color space (only possible if no PDF/A or
+ * PDF/X profile is active), default: false
+ */
+ DISABLE_SRGB_COLORSPACE("disable-srgb-colorspace", false) {
+ @Override
+ Boolean deserialize(String value) {
+ return Boolean.valueOf(value);
+ }
+ },
+ /** Rendering Options key for the ICC profile for the output intent. */
+ OUTPUT_PROFILE("output-profile") {
+ @Override
+ URI deserialize(String value) {
+ try {
+ return InternalResourceResolver.cleanURI(value);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ private final String name;
+
+ private final Object defaultValue;
+
+ private PDFRendererOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ private PDFRendererOption(String name) {
+ this(name, null);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
+ public Object parse(Object object) {
+ if (object instanceof String) {
+ return deserialize((String) object);
+ } else {
+ return object;
+ }
+ }
+
+ abstract Object deserialize(String value);
+
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java b/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
new file mode 100644
index 000000000..71102ecf0
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererOptionsConfig.java
@@ -0,0 +1,123 @@
+/*
+ * 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.net.URI;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFEncryptionParams;
+import org.apache.fop.pdf.PDFXMode;
+import org.apache.fop.pdf.Version;
+
+import static org.apache.fop.render.pdf.PDFRendererOption.DISABLE_SRGB_COLORSPACE;
+import static org.apache.fop.render.pdf.PDFRendererOption.FILTER_LIST;
+import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
+import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
+
+/**
+ * The renderer options configuration data.
+ */
+public final class PDFRendererOptionsConfig {
+
+ static final PDFRendererOptionsConfig DEFAULT;
+
+ static {
+ final EnumMap<PDFRendererOption, Object> props
+ = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
+ for (PDFRendererOption option : PDFRendererOption.values()) {
+ props.put(option, option.getDefaultValue());
+ }
+ DEFAULT = new PDFRendererOptionsConfig(props, null);
+ }
+
+ private final Map<PDFRendererOption, Object> properties
+ = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
+
+ private final PDFEncryptionParams encryptionConfig;
+
+ PDFRendererOptionsConfig(Map<PDFRendererOption, Object> props,
+ PDFEncryptionParams encryptionParams) {
+ properties.putAll(props);
+ this.encryptionConfig = copyPDFEncryptionParams(encryptionParams);
+ }
+
+ private static PDFEncryptionParams copyPDFEncryptionParams(PDFEncryptionParams source) {
+ return source == null ? null : new PDFEncryptionParams(source);
+ }
+
+ PDFRendererOptionsConfig merge(PDFRendererOptionsConfig config) {
+ if (config == null) {
+ return this;
+ } else {
+ return new PDFRendererOptionsConfig(merge(this.properties, config.properties),
+ config.getEncryptionParameters() == null
+ ? copyPDFEncryptionParams(this.encryptionConfig)
+ : copyPDFEncryptionParams(config.getEncryptionParameters()));
+ }
+ }
+
+ private static Map<PDFRendererOption, Object> merge(
+ Map<PDFRendererOption, Object> first, Map<PDFRendererOption, Object> second) {
+ final EnumMap<PDFRendererOption, Object> merged
+ = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
+ for (PDFRendererOption option : PDFRendererOption.values()) {
+ Object value = second.get(option);
+ if (value != null) {
+ merged.put(option, value);
+ } else {
+ merged.put(option, first.get(option));
+ }
+ }
+ return merged;
+ }
+
+ public Map<String, List<String>> getFilterMap() {
+ return (Map<String, List<String>>) properties.get(FILTER_LIST);
+ }
+
+ public PDFAMode getPDFAMode() {
+ return (PDFAMode) properties.get(PDF_A_MODE);
+ }
+
+ public PDFXMode getPDFXMode() {
+ return (PDFXMode) properties.get(PDF_X_MODE);
+ }
+
+ public PDFEncryptionParams getEncryptionParameters() {
+ return encryptionConfig;
+ }
+
+ public URI getOutputProfileURI() {
+ return (URI) properties.get(OUTPUT_PROFILE);
+ }
+
+ public Boolean getDisableSRGBColorSpace() {
+ return (Boolean) properties.get(DISABLE_SRGB_COLORSPACE);
+ }
+
+ public Version getPDFVersion() {
+ return (Version) properties.get(VERSION);
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
index 53d259677..fba9d922f 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderingUtil.java
@@ -24,17 +24,15 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.net.URL;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.EnumMap;
import java.util.Map;
-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.xmlgraphics.image.loader.util.ImageUtil;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
@@ -42,6 +40,7 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
import org.apache.fop.accessibility.Accessibility;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fo.extensions.xmp.XMPMetadata;
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFArray;
@@ -68,11 +67,24 @@ import org.apache.fop.pdf.Version;
import org.apache.fop.pdf.VersionController;
import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileExtensionAttachment;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ACCESSCONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ANNOTATIONS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ASSEMBLEDOC;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_COPY_CONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_EDIT_CONTENT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_FILLINFORMS;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINT;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINTHQ;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.OWNER_PASSWORD;
+import static org.apache.fop.render.pdf.PDFEncryptionOption.USER_PASSWORD;
+
+
/**
* Utility class which enables all sorts of features that are not directly connected to the
* normal rendering process.
*/
-class PDFRenderingUtil implements PDFConfigurationConstants {
+class PDFRenderingUtil {
/** logging instance */
private static Log log = LogFactory.getLog(PDFRenderingUtil.class);
@@ -80,171 +92,42 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
private FOUserAgent userAgent;
/** the PDF Document being created */
- protected PDFDocument pdfDoc;
-
- /** the PDF/A mode (Default: disabled) */
- protected PDFAMode pdfAMode = PDFAMode.DISABLED;
-
- /** the PDF/X mode (Default: disabled) */
- protected PDFXMode pdfXMode = PDFXMode.DISABLED;
-
- /** the (optional) encryption parameters */
- protected PDFEncryptionParams encryptionParams;
+ private PDFDocument pdfDoc;
- /** Registry of PDF filters */
- protected Map filterMap;
+ private PDFRendererOptionsConfig rendererConfig;
/** the ICC stream used as output profile by this document for PDF/A and PDF/X functionality. */
- protected PDFICCStream outputProfile;
- /** the default sRGB color space. */
- protected PDFICCBasedColorSpace sRGBColorSpace;
- /** controls whether the sRGB color space should be installed */
- protected boolean disableSRGBColorSpace = false;
-
- /** Optional URI to an output profile to be used. */
- protected String outputProfileURI;
-
- protected Version maxPDFVersion;
+ private PDFICCStream outputProfile;
+ /** the default sRGB color space. */
+ private PDFICCBasedColorSpace sRGBColorSpace;
PDFRenderingUtil(FOUserAgent userAgent) {
this.userAgent = userAgent;
initialize();
}
- private static boolean booleanValueOf(Object obj) {
- if (obj instanceof Boolean) {
- return ((Boolean)obj).booleanValue();
- } else if (obj instanceof String) {
- return Boolean.valueOf((String)obj).booleanValue();
- } else {
- throw new IllegalArgumentException("Boolean or \"true\" or \"false\" expected.");
- }
- }
-
private void initialize() {
- PDFEncryptionParams params
- = (PDFEncryptionParams)userAgent.getRendererOptions().get(ENCRYPTION_PARAMS);
- if (params != null) {
- this.encryptionParams = params; //overwrite if available
- }
- String userPassword = (String)userAgent.getRendererOptions().get(USER_PASSWORD);
- if (userPassword != null) {
- getEncryptionParams().setUserPassword(userPassword);
- }
- String ownerPassword = (String)userAgent.getRendererOptions().get(OWNER_PASSWORD);
- if (ownerPassword != null) {
- getEncryptionParams().setOwnerPassword(ownerPassword);
- }
- Object noPrint = userAgent.getRendererOptions().get(NO_PRINT);
- if (noPrint != null) {
- getEncryptionParams().setAllowPrint(!booleanValueOf(noPrint));
- }
- Object noCopyContent = userAgent.getRendererOptions().get(NO_COPY_CONTENT);
- if (noCopyContent != null) {
- getEncryptionParams().setAllowCopyContent(!booleanValueOf(noCopyContent));
- }
- Object noEditContent = userAgent.getRendererOptions().get(NO_EDIT_CONTENT);
- if (noEditContent != null) {
- getEncryptionParams().setAllowEditContent(!booleanValueOf(noEditContent));
- }
- Object noAnnotations = userAgent.getRendererOptions().get(NO_ANNOTATIONS);
- if (noAnnotations != null) {
- getEncryptionParams().setAllowEditAnnotations(!booleanValueOf(noAnnotations));
- }
- Object noFillInForms = userAgent.getRendererOptions().get(NO_FILLINFORMS);
- if (noFillInForms != null) {
- getEncryptionParams().setAllowFillInForms(!booleanValueOf(noFillInForms));
- }
- Object noAccessContent = userAgent.getRendererOptions().get(NO_ACCESSCONTENT);
- if (noAccessContent != null) {
- getEncryptionParams().setAllowAccessContent(!booleanValueOf(noAccessContent));
- }
- Object noAssembleDoc = userAgent.getRendererOptions().get(NO_ASSEMBLEDOC);
- if (noAssembleDoc != null) {
- getEncryptionParams().setAllowAssembleDocument(!booleanValueOf(noAssembleDoc));
- }
- Object noPrintHQ = userAgent.getRendererOptions().get(NO_PRINTHQ);
- if (noPrintHQ != null) {
- getEncryptionParams().setAllowPrintHq(!booleanValueOf(noPrintHQ));
- }
- String s = (String)userAgent.getRendererOptions().get(PDF_A_MODE);
- if (s != null) {
- this.pdfAMode = PDFAMode.valueOf(s);
- }
- if (this.pdfAMode.isPDFA1LevelA()) {
+ rendererConfig = PDFRendererOptionsConfig.DEFAULT.merge(createFromUserAgent(userAgent));
+ if (rendererConfig.getPDFAMode().isPDFA1LevelA()) {
//Enable accessibility if PDF/A-1a is enabled because it requires tagged PDF.
userAgent.getRendererOptions().put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
}
- s = (String)userAgent.getRendererOptions().get(PDF_X_MODE);
- if (s != null) {
- this.pdfXMode = PDFXMode.valueOf(s);
- }
- s = (String)userAgent.getRendererOptions().get(KEY_OUTPUT_PROFILE);
- if (s != null) {
- this.outputProfileURI = s;
- }
- Object disableSRGBColorSpace = userAgent.getRendererOptions().get(
- KEY_DISABLE_SRGB_COLORSPACE);
- if (disableSRGBColorSpace != null) {
- this.disableSRGBColorSpace = booleanValueOf(disableSRGBColorSpace);
- }
- }
-
- public FOUserAgent getUserAgent() {
- return this.userAgent;
- }
-
- /**
- * Sets the PDF/A mode for the PDF renderer.
- * @param mode the PDF/A mode
- */
- public void setAMode(PDFAMode mode) {
- this.pdfAMode = mode;
- }
-
- /**
- * Sets the PDF/X mode for the PDF renderer.
- * @param mode the PDF/X mode
- */
- public void setXMode(PDFXMode mode) {
- this.pdfXMode = mode;
- }
-
- /**
- * Sets the output color profile for the PDF renderer.
- * @param outputProfileURI the URI to the output color profile
- */
- public void setOutputProfileURI(String outputProfileURI) {
- this.outputProfileURI = outputProfileURI;
}
- /**
- * Enables or disables the default sRGB color space needed for the PDF document to preserve
- * the sRGB colors used in XSL-FO.
- * @param disable true to disable, false to enable
- */
- public void setDisableSRGBColorSpace(boolean disable) {
- this.disableSRGBColorSpace = disable;
+ private static PDFRendererOptionsConfig createFromUserAgent(FOUserAgent userAgent) {
+ Map<PDFRendererOption, Object> properties
+ = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
+ for (PDFRendererOption option : PDFRendererOption.values()) {
+ Object value = userAgent.getRendererOption(option);
+ properties.put(option, option.parse(value));
+ }
+ PDFEncryptionParams encryptionConfig = new EncryptionParamsBuilder().createParams(userAgent);
+ return new PDFRendererOptionsConfig(properties, encryptionConfig);
}
- /**
- * Sets the filter map to be used by the PDF renderer.
- * @param filterMap the filter map
- */
- public void setFilterMap(Map filterMap) {
- this.filterMap = filterMap;
- }
-
- /**
- * Gets the encryption parameters used by the PDF renderer.
- * @return encryptionParams the encryption parameters
- */
- PDFEncryptionParams getEncryptionParams() {
- if (this.encryptionParams == null) {
- this.encryptionParams = new PDFEncryptionParams();
- }
- return this.encryptionParams;
+ void mergeRendererOptionsConfig(PDFRendererOptionsConfig config) {
+ rendererConfig = rendererConfig.merge(config);
}
private void updateInfo() {
@@ -258,15 +141,15 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
}
private void updatePDFProfiles() {
- pdfDoc.getProfile().setPDFAMode(this.pdfAMode);
- pdfDoc.getProfile().setPDFXMode(this.pdfXMode);
+ pdfDoc.getProfile().setPDFAMode(rendererConfig.getPDFAMode());
+ pdfDoc.getProfile().setPDFXMode(rendererConfig.getPDFXMode());
}
private void addsRGBColorSpace() throws IOException {
- if (disableSRGBColorSpace) {
- if (this.pdfAMode != PDFAMode.DISABLED
- || this.pdfXMode != PDFXMode.DISABLED
- || this.outputProfileURI != null) {
+ if (rendererConfig.getDisableSRGBColorSpace()) {
+ if (rendererConfig.getPDFAMode() != PDFAMode.DISABLED
+ || rendererConfig.getPDFXMode() != PDFXMode.DISABLED
+ || rendererConfig.getOutputProfileURI() != null) {
throw new IllegalStateException("It is not possible to disable the sRGB color"
+ " space if PDF/A or PDF/X functionality is enabled or an"
+ " output profile is set!");
@@ -286,17 +169,10 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
}
ICC_Profile profile;
InputStream in = null;
- if (this.outputProfileURI != null) {
+ URI outputProfileUri = rendererConfig.getOutputProfileURI();
+ if (outputProfileUri != null) {
this.outputProfile = pdfDoc.getFactory().makePDFICCStream();
- Source src = getUserAgent().resolveURI(this.outputProfileURI);
- if (src == null) {
- throw new IOException("Output profile not found: " + this.outputProfileURI);
- }
- if (src instanceof StreamSource) {
- in = ((StreamSource)src).getInputStream();
- } else {
- in = new URL(src.getSystemId()).openStream();
- }
+ in = userAgent.getResourceResolver().getResource(rendererConfig.getOutputProfileURI());
try {
profile = ColorProfileUtil.getICC_Profile(in);
} finally {
@@ -381,7 +257,7 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
}
String producer = userAgent.getProducer() != null ? userAgent.getProducer() : "";
-
+ final Version maxPDFVersion = rendererConfig.getPDFVersion();
if (maxPDFVersion == null) {
this.pdfDoc = new PDFDocument(producer);
} else {
@@ -391,22 +267,24 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
}
updateInfo();
updatePDFProfiles();
- pdfDoc.setFilterMap(filterMap);
+ pdfDoc.setFilterMap(rendererConfig.getFilterMap());
pdfDoc.outputHeader(out);
//Setup encryption if necessary
- PDFEncryptionManager.setupPDFEncryption(encryptionParams, pdfDoc);
+ PDFEncryptionManager.setupPDFEncryption(rendererConfig.getEncryptionParameters(), pdfDoc);
addsRGBColorSpace();
- if (this.outputProfileURI != null) {
+ if (rendererConfig.getOutputProfileURI() != null) {
addDefaultOutputProfile();
}
+ PDFXMode pdfXMode = rendererConfig.getPDFXMode();
if (pdfXMode != PDFXMode.DISABLED) {
log.debug(pdfXMode + " is active.");
log.warn("Note: " + pdfXMode
+ " support is work-in-progress and not fully implemented, yet!");
addPDFXOutputIntent();
}
+ PDFAMode pdfAMode = rendererConfig.getPDFAMode();
if (pdfAMode.isPDFA1LevelB()) {
log.debug("PDF/A is active. Conformance Level: " + pdfAMode);
addPDFA1OutputIntent();
@@ -456,8 +334,13 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
//Create embedded file
PDFEmbeddedFile file = new PDFEmbeddedFile();
this.pdfDoc.registerObject(file);
- Source src = getUserAgent().resolveURI(embeddedFile.getSrc());
- InputStream in = ImageUtil.getInputStream(src);
+ URI srcURI;
+ try {
+ srcURI = InternalResourceResolver.cleanURI(embeddedFile.getSrc());
+ } catch (URISyntaxException use) {
+ throw new RuntimeException(use);
+ }
+ InputStream in = userAgent.getResourceResolver().getResource(srcURI);
if (in == null) {
throw new FileNotFoundException(embeddedFile.getSrc());
}
@@ -497,14 +380,72 @@ class PDFRenderingUtil implements PDFConfigurationConstants {
nameArray.add(new PDFReference(fileSpec));
}
- /**
- * Sets the PDF version of the output document. See {@link Version} for the format of
- * <code>version</code>.
- * @param version the PDF version
- * @throws IllegalArgumentException if the format of version doesn't conform to that specified
- * by {@link Version}
- */
- public void setPDFVersion(String version) {
- maxPDFVersion = Version.getValueOf(version);
+ private static final class EncryptionParamsBuilder {
+ private PDFEncryptionParams params;
+
+ private EncryptionParamsBuilder() {
+ }
+
+ private PDFEncryptionParams createParams(FOUserAgent userAgent) {
+ params = (PDFEncryptionParams) userAgent.getRendererOptions().get(ENCRYPTION_PARAMS);
+ String userPassword = (String) userAgent.getRendererOption(USER_PASSWORD);
+ if (userPassword != null) {
+ getEncryptionParams().setUserPassword(userPassword);
+ }
+ String ownerPassword = (String) userAgent.getRendererOption(OWNER_PASSWORD);
+ if (ownerPassword != null) {
+ getEncryptionParams().setOwnerPassword(ownerPassword);
+ }
+ Object noPrint = userAgent.getRendererOption(NO_PRINT);
+ if (noPrint != null) {
+ getEncryptionParams().setAllowPrint(!booleanValueOf(noPrint));
+ }
+ Object noCopyContent = userAgent.getRendererOption(NO_COPY_CONTENT);
+ if (noCopyContent != null) {
+ getEncryptionParams().setAllowCopyContent(!booleanValueOf(noCopyContent));
+ }
+ Object noEditContent = userAgent.getRendererOption(NO_EDIT_CONTENT);
+ if (noEditContent != null) {
+ getEncryptionParams().setAllowEditContent(!booleanValueOf(noEditContent));
+ }
+ Object noAnnotations = userAgent.getRendererOption(NO_ANNOTATIONS);
+ if (noAnnotations != null) {
+ getEncryptionParams().setAllowEditAnnotations(!booleanValueOf(noAnnotations));
+ }
+ Object noFillInForms = userAgent.getRendererOption(NO_FILLINFORMS);
+ if (noFillInForms != null) {
+ getEncryptionParams().setAllowFillInForms(!booleanValueOf(noFillInForms));
+ }
+ Object noAccessContent = userAgent.getRendererOption(NO_ACCESSCONTENT);
+ if (noAccessContent != null) {
+ getEncryptionParams().setAllowAccessContent(!booleanValueOf(noAccessContent));
+ }
+ Object noAssembleDoc = userAgent.getRendererOption(NO_ASSEMBLEDOC);
+ if (noAssembleDoc != null) {
+ getEncryptionParams().setAllowAssembleDocument(!booleanValueOf(noAssembleDoc));
+ }
+ Object noPrintHQ = userAgent.getRendererOption(NO_PRINTHQ);
+ if (noPrintHQ != null) {
+ getEncryptionParams().setAllowPrintHq(!booleanValueOf(noPrintHQ));
+ }
+ return params;
+ }
+
+ private PDFEncryptionParams getEncryptionParams() {
+ if (params == null) {
+ params = new PDFEncryptionParams();
+ }
+ return params;
+ }
+
+ private static boolean booleanValueOf(Object obj) {
+ if (obj instanceof Boolean) {
+ return ((Boolean)obj).booleanValue();
+ } else if (obj instanceof String) {
+ return Boolean.valueOf((String)obj).booleanValue();
+ } else {
+ throw new IllegalArgumentException("Boolean or \"true\" or \"false\" expected.");
+ }
+ }
}
}
diff --git a/src/java/org/apache/fop/render/print/PrintRendererMaker.java b/src/java/org/apache/fop/render/print/PrintRendererMaker.java
index 63444a628..e5673c1f4 100644
--- a/src/java/org/apache/fop/render/print/PrintRendererMaker.java
+++ b/src/java/org/apache/fop/render/print/PrintRendererMaker.java
@@ -19,12 +19,12 @@
package org.apache.fop.render.print;
+import org.apache.fop.apps.FOPException;
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.
@@ -33,24 +33,23 @@ public class PrintRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_PRINT};
- /**{@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent userAgent) {
return new PrintRenderer(userAgent);
}
- /** {@inheritDoc} */
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return new PrintRendererConfigurator(userAgent);
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ PrintRendererConfigurator.createDefaultInstance(userAgent).configure(renderer);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return false;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
-
}
diff --git a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
index 0fe564827..0ec5fdda6 100644
--- a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
@@ -22,10 +22,12 @@ package org.apache.fop.render.ps;
import java.awt.Dimension;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
-import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -50,13 +52,14 @@ import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBoundingBox;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentHiResBoundingBox;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.io.TempResourceURIGenerator;
import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
+import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser;
import org.apache.fop.render.ps.extensions.PSCommentAfter;
import org.apache.fop.render.ps.extensions.PSCommentBefore;
import org.apache.fop.render.ps.extensions.PSPageTrailerCodeBefore;
@@ -76,13 +79,15 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
* Utility class which enables all sorts of features that are not directly connected to the
* normal rendering process.
*/
- protected PSRenderingUtil psUtil;
+ private PSRenderingUtil psUtil;
/** The PostScript generator used to output the PostScript */
- protected PSGenerator gen;
+ PSGenerator gen;
/** the temporary file in case of two-pass processing */
- private File tempFile;
+ private URI tempURI;
+ private static final TempResourceURIGenerator TEMP_URI_GENERATOR
+ = new TempResourceURIGenerator("ps-optimize");
private int currentPageNumber = 0;
private PageDefinition currentPageDefinition;
@@ -113,7 +118,9 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
/**
* Default constructor.
*/
- public PSDocumentHandler() {
+ public PSDocumentHandler(IFContext context) {
+ super(context);
+ this.psUtil = new PSRenderingUtil(context.getUserAgent());
}
/** {@inheritDoc} */
@@ -126,17 +133,13 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
return MimeConstants.MIME_POSTSCRIPT;
}
- /** {@inheritDoc} */
- public void setContext(IFContext context) {
- super.setContext(context);
- FOUserAgent userAgent = context.getUserAgent();
- this.psUtil = new PSRenderingUtil(userAgent);
- eventProducer = PSEventProducer.Provider.get(userAgent.getEventBroadcaster());
+ PSGenerator getGenerator() {
+ return gen;
}
/** {@inheritDoc} */
public IFDocumentHandlerConfigurator getConfigurator() {
- return new PSRendererConfigurator(getUserAgent());
+ return new PSRendererConfigurator(getUserAgent(), new PSRendererConfigParser());
}
PSRenderingUtil getPSUtil() {
@@ -148,11 +151,10 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
super.startDocument();
this.fontResources = new FontResourceCache(getFontInfo());
try {
- OutputStream out;
+ final OutputStream out;
if (psUtil.isOptimizeResources()) {
- this.tempFile = File.createTempFile("fop", ".ps");
- out = new java.io.FileOutputStream(this.tempFile);
- out = new java.io.BufferedOutputStream(out);
+ tempURI = TEMP_URI_GENERATOR.generate();
+ out = new BufferedOutputStream(getUserAgent().getResourceResolver().getOutputStream(tempURI));
} else {
out = this.outputStream;
}
@@ -259,8 +261,7 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
log.debug("Processing PostScript resources...");
long startTime = System.currentTimeMillis();
ResourceTracker resTracker = gen.getResourceTracker();
- InputStream in = new java.io.FileInputStream(this.tempFile);
- in = new java.io.BufferedInputStream(in);
+ InputStream in = new BufferedInputStream(getUserAgent().getResourceResolver().getResource(tempURI));
try {
try {
ResourceHandler handler = new ResourceHandler(getUserAgent(), eventProducer,
@@ -273,10 +274,6 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
}
} finally {
IOUtils.closeQuietly(in);
- if (!this.tempFile.delete()) {
- this.tempFile.deleteOnExit();
- log.warn("Could not delete temporary file: " + this.tempFile);
- }
}
if (log.isDebugEnabled()) {
long duration = System.currentTimeMillis() - startTime;
diff --git a/src/java/org/apache/fop/render/ps/PSDocumentHandlerMaker.java b/src/java/org/apache/fop/render/ps/PSDocumentHandlerMaker.java
index c581f9e02..1c31c4906 100644
--- a/src/java/org/apache/fop/render/ps/PSDocumentHandlerMaker.java
+++ b/src/java/org/apache/fop/render/ps/PSDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.ps;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
@@ -33,19 +32,17 @@ public class PSDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
private static final String[] MIMES = new String[]
{MimeConstants.MIME_POSTSCRIPT};
- /** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- PSDocumentHandler handler = new PSDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ @Override
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new PSDocumentHandler(ifContext);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java
index d0d75744f..c99bb21e1 100644
--- a/src/java/org/apache/fop/render/ps/PSFontUtils.java
+++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java
@@ -19,19 +19,14 @@
package org.apache.fop.render.ps;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
-import javax.xml.transform.Source;
-import javax.xml.transform.stream.StreamSource;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -526,27 +521,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
private static InputStream getInputStreamOnFont(PSGenerator gen, CustomFont font)
throws IOException {
if (isEmbeddable(font)) {
- Source source = font.getEmbedFileSource();
- if (source == null && font.getEmbedResourceName() != null) {
- source = new StreamSource(PSFontUtils.class
- .getResourceAsStream(font.getEmbedResourceName()));
- }
- if (source == null) {
- return null;
- }
- InputStream in = null;
- if (source instanceof StreamSource) {
- in = ((StreamSource) source).getInputStream();
- }
- if (in == null && source.getSystemId() != null) {
- try {
- in = new java.net.URL(source.getSystemId()).openStream();
- } catch (MalformedURLException e) {
- new FileNotFoundException(
- "File not found. URL could not be resolved: "
- + e.getMessage());
- }
- }
+ InputStream in = font.getInputStream();
if (in == null) {
return null;
}
diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
index 839a0cab6..3ade34522 100644
--- a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
+++ b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
@@ -70,7 +70,7 @@ public class PSImageHandlerSVG implements ImageHandler {
BridgeContext ctx = new PSBridgeContext(ua,
(strokeText ? null : psContext.getFontInfo()),
- context.getUserAgent().getFactory().getImageManager(),
+ context.getUserAgent().getImageManager(),
context.getUserAgent().getImageSessionContext());
//Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine)
diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java
index 431071701..962f19d10 100644
--- a/src/java/org/apache/fop/render/ps/PSImageUtils.java
+++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java
@@ -53,7 +53,7 @@ public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils {
}
//Investigate choice for inline mode
ImageFlavor[] inlineFlavors = determineSupportedImageFlavors(renderingContext);
- ImageManager manager = renderingContext.getUserAgent().getFactory().getImageManager();
+ ImageManager manager = renderingContext.getUserAgent().getImageManager();
ImageProviderPipeline[] inlineCandidates
= manager.getPipelineFactory().determineCandidatePipelines(
info, inlineFlavors);
@@ -79,7 +79,7 @@ public class PSImageUtils extends org.apache.xmlgraphics.ps.PSImageUtils {
private static ImageFlavor[] determineSupportedImageFlavors(RenderingContext renderingContext) {
ImageFlavor[] inlineFlavors;
ImageHandlerRegistry imageHandlerRegistry
- = renderingContext.getUserAgent().getFactory().getImageHandlerRegistry();
+ = renderingContext.getUserAgent().getImageHandlerRegistry();
inlineFlavors = imageHandlerRegistry.getSupportedFlavors(renderingContext);
return inlineFlavors;
}
diff --git a/src/java/org/apache/fop/render/ps/PSPainter.java b/src/java/org/apache/fop/render/ps/PSPainter.java
index 9d16cb428..b8947ff60 100644
--- a/src/java/org/apache/fop/render/ps/PSPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSPainter.java
@@ -41,7 +41,6 @@ import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSResource;
import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.MultiByteFont;
@@ -49,7 +48,6 @@ import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
-import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -61,12 +59,11 @@ import org.apache.fop.util.HexEncoder;
/**
* IFPainter implementation that produces PostScript.
*/
-public class PSPainter extends AbstractIFPainter {
+public class PSPainter extends AbstractIFPainter<PSDocumentHandler> {
/** logging instance */
private static Log log = LogFactory.getLog(PSPainter.class);
- private PSDocumentHandler documentHandler;
private PSBorderPainter borderPainter;
private boolean inTextMode = false;
@@ -80,27 +77,13 @@ public class PSPainter extends AbstractIFPainter {
}
protected PSPainter(PSDocumentHandler documentHandler, IFState state) {
- super();
- this.documentHandler = documentHandler;
- this.borderPainter = new PSBorderPainter(documentHandler.gen);
+ super(documentHandler);
+ this.borderPainter = new PSBorderPainter(getGenerator());
this.state = state;
}
- /** {@inheritDoc} */
- protected IFContext getContext() {
- return this.documentHandler.getContext();
- }
-
- PSRenderingUtil getPSUtil() {
- return this.documentHandler.psUtil;
- }
-
- FontInfo getFontInfo() {
- return this.documentHandler.getFontInfo();
- }
-
private PSGenerator getGenerator() {
- return this.documentHandler.gen;
+ return getDocumentHandler().getGenerator();
}
/** {@inheritDoc} */
@@ -168,7 +151,7 @@ public class PSPainter extends AbstractIFPainter {
/** {@inheritDoc} */
protected void drawImageUsingImageHandler(ImageInfo info, Rectangle rect)
throws ImageException, IOException {
- if (!getPSUtil().isOptimizeResources()
+ if (!getDocumentHandler().getPSUtil().isOptimizeResources()
|| PSImageUtils.isImageInlined(info,
(PSRenderingContext)createRenderingContext())) {
super.drawImageUsingImageHandler(info, rect);
@@ -177,7 +160,7 @@ public class PSPainter extends AbstractIFPainter {
log.debug("Image " + info + " is embedded as a form later");
}
//Don't load image at this time, just put a form placeholder in the stream
- PSResource form = documentHandler.getFormForImage(info.getOriginalURI());
+ PSResource form = getDocumentHandler().getFormForImage(info.getOriginalURI());
PSImageUtils.drawForm(form, info, rect, getGenerator());
}
}
@@ -260,7 +243,7 @@ public class PSPainter extends AbstractIFPainter {
if (top != null || bottom != null || left != null || right != null) {
try {
endTextObject();
- if (getPSUtil().getRenderingMode() == PSRenderingMode.SIZE
+ if (getDocumentHandler().getPSUtil().getRenderingMode() == PSRenderingMode.SIZE
&& hasOnlySolidBorders(top, bottom, left, right)) {
super.drawBorderRect(rect, top, bottom, left, right, innerBackgroundColor);
} else {
@@ -287,7 +270,7 @@ public class PSPainter extends AbstractIFPainter {
if (fontName == null) {
throw new NullPointerException("fontName must not be null");
}
- Typeface tf = (Typeface)getFontInfo().getFonts().get(fontName);
+ Typeface tf = getFontInfo().getFonts().get(fontName);
if (tf instanceof LazyFont) {
tf = ((LazyFont)tf).getRealFont();
}
@@ -377,10 +360,7 @@ public class PSPainter extends AbstractIFPainter {
state.getFontFamily(), state.getFontStyle(), state.getFontWeight());
//TODO Ignored: state.getFontVariant()
//TODO Opportunity for font caching if font state is more heavily used
- String fontKey = getFontInfo().getInternalFontKey(triplet);
- if (fontKey == null) {
- throw new IFException("Font not available: " + triplet, null);
- }
+ String fontKey = getFontKey(triplet);
int sizeMillipoints = state.getFontSize();
// This assumes that *all* CIDFonts use a /ToUnicode mapping
@@ -543,10 +523,9 @@ public class PSPainter extends AbstractIFPainter {
}
private void useFont(String key, int size) throws IOException {
- PSFontResource res = this.documentHandler.getPSResourceForFontKey(key);
+ PSFontResource res = getDocumentHandler().getPSResourceForFontKey(key);
PSGenerator generator = getGenerator();
generator.useFont("/" + res.getName(), size / 1000f);
res.notifyResourceUsageOnPage(generator.getResourceTracker());
}
-
}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererConfig.java b/src/java/org/apache/fop/render/ps/PSRendererConfig.java
new file mode 100644
index 000000000..e26be11d0
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSRendererConfig.java
@@ -0,0 +1,147 @@
+/*
+ * 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 java.util.EnumMap;
+import java.util.Locale;
+
+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;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.util.LogUtil;
+
+import static org.apache.fop.render.ps.PSRendererOption.AUTO_ROTATE_LANDSCAPE;
+import static org.apache.fop.render.ps.PSRendererOption.DSC_COMPLIANT;
+import static org.apache.fop.render.ps.PSRendererOption.LANGUAGE_LEVEL;
+import static org.apache.fop.render.ps.PSRendererOption.OPTIMIZE_RESOURCES;
+import static org.apache.fop.render.ps.PSRendererOption.RENDERING_MODE;
+import static org.apache.fop.render.ps.PSRendererOption.SAFE_SET_PAGE_DEVICE;
+
+/**
+ * The PostScript renderer configuration data object.
+ */
+public final class PSRendererConfig implements RendererConfig {
+
+ private final EnumMap<PSRendererOption, Object> params
+ = new EnumMap<PSRendererOption, Object>(PSRendererOption.class);
+
+ private final DefaultFontConfig fontConfig;
+
+ private PSRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public Boolean isAutoRotateLandscape() {
+ return (Boolean) params.get(AUTO_ROTATE_LANDSCAPE);
+ }
+
+ public Integer getLanguageLevel() {
+ return (Integer) params.get(LANGUAGE_LEVEL);
+ }
+
+ public Boolean isOptimizeResources() {
+ return (Boolean) params.get(OPTIMIZE_RESOURCES);
+ }
+
+ public Boolean isSafeSetPageDevice() {
+ return (Boolean) params.get(SAFE_SET_PAGE_DEVICE);
+ }
+
+ public Boolean isDscComplianceEnabled() {
+ return (Boolean) params.get(DSC_COMPLIANT);
+ }
+
+ public PSRenderingMode getRenderingMode() {
+ return (PSRenderingMode) params.get(RENDERING_MODE);
+ }
+
+ /**
+ * The PostScript renderer configuration data parser.
+ */
+ public static final class PSRendererConfigParser implements RendererConfigParser {
+
+ private static final Log LOG = LogFactory.getLog(PSRendererConfigParser.class);
+
+ public PSRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ PSRendererConfig config = null;
+ try {
+ config = new ParserHelper(cfg, userAgent).config;
+ } catch (ConfigurationException e) {
+ LogUtil.handleException(LOG, e, false);
+ }
+ return config;
+ }
+
+ public String getMimeType() {
+ return MimeConstants.MIME_POSTSCRIPT;
+ }
+ }
+
+ private static final class ParserHelper {
+
+ private PSRendererConfig config;
+
+ private ParserHelper(Configuration cfg, FOUserAgent userAgent)
+ throws ConfigurationException, FOPException {
+ config = new PSRendererConfig(new DefaultFontConfigParser().parse(cfg,
+ userAgent.validateStrictly()));
+ if (cfg != null) {
+ setBoolConfigParam(cfg, AUTO_ROTATE_LANDSCAPE);
+ setConfigParameter(LANGUAGE_LEVEL,
+ cfg.getChild(LANGUAGE_LEVEL.getName())
+ .getValueAsInteger((Integer) LANGUAGE_LEVEL.getDefaultValue()));
+ setBoolConfigParam(cfg, OPTIMIZE_RESOURCES);
+ setBoolConfigParam(cfg, SAFE_SET_PAGE_DEVICE);
+ setBoolConfigParam(cfg, DSC_COMPLIANT);
+ Configuration child = cfg.getChild("rendering");
+ if (child != null) {
+ config.params.put(RENDERING_MODE,
+ PSRenderingMode.valueOf(child.getValue(
+ RENDERING_MODE.getDefaultValue().toString())
+ .toUpperCase(Locale.ENGLISH)));
+ }
+ }
+ }
+
+ private void setConfigParameter(PSRendererOption option,
+ Object value) {
+ config.params.put(option, value != null ? value : option.getDefaultValue());
+ }
+
+ private void setBoolConfigParam(Configuration cfg, PSRendererOption option) {
+ setConfigParameter(option, cfg.getChild(
+ option.getName()).getValueAsBoolean((Boolean) option.getDefaultValue()));
+ }
+
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java
index 00f3fc154..b453de413 100644
--- a/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/ps/PSRendererConfigurator.java
@@ -19,75 +19,56 @@
package org.apache.fop.render.ps;
-import java.util.Locale;
-
-import org.apache.avalon.framework.configuration.Configuration;
-
-import org.apache.xmlgraphics.ps.PSGenerator;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.render.PrintRendererConfigurator;
-import org.apache.fop.render.Renderer;
+import org.apache.fop.render.DefaultRendererConfigurator;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
import org.apache.fop.render.intermediate.IFDocumentHandler;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
+
/**
* Postscript renderer config
*/
-public class PSRendererConfigurator extends PrintRendererConfigurator
- implements IFDocumentHandlerConfigurator {
+public class PSRendererConfigurator extends DefaultRendererConfigurator
+ implements IFDocumentHandlerConfigurator {
/**
* Default constructor
* @param userAgent user agent
*/
- public PSRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public PSRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
- /**
- * Throws an UnsupportedOperationException.
- *
- * @param renderer not used
- */
- public void configure(Renderer renderer) {
- throw new UnsupportedOperationException();
- }
-
- private void configure(PSRenderingUtil psUtil, Configuration cfg) {
- psUtil.setAutoRotateLandscape(
- cfg.getChild("auto-rotate-landscape").getValueAsBoolean(false));
- Configuration child;
- child = cfg.getChild("language-level");
- if (child != null) {
- psUtil.setLanguageLevel(child.getValueAsInteger(
- PSGenerator.DEFAULT_LANGUAGE_LEVEL));
+ private void configure(PSRenderingUtil psUtil, PSRendererConfig psConfig) {
+ if (psConfig.isAutoRotateLandscape() != null) {
+ psUtil.setAutoRotateLandscape(psConfig.isAutoRotateLandscape());
+ }
+ if (psConfig.getLanguageLevel() != null) {
+ psUtil.setLanguageLevel(psConfig.getLanguageLevel());
+ }
+ if (psConfig.isOptimizeResources() != null) {
+ psUtil.setOptimizeResources(psConfig.isOptimizeResources());
}
- child = cfg.getChild("optimize-resources");
- if (child != null) {
- psUtil.setOptimizeResources(child.getValueAsBoolean(false));
+ if (psConfig.isSafeSetPageDevice() != null) {
+ psUtil.setSafeSetPageDevice(psConfig.isSafeSetPageDevice());
}
- child = cfg.getChild("rendering");
- if (child != null) {
- psUtil.setRenderingMode(PSRenderingMode.valueOf(
- child.getValue(psUtil.getRenderingMode().toString())
- .toUpperCase(Locale.ENGLISH)));
+ if (psConfig.isDscComplianceEnabled() != null) {
+ psUtil.setDSCComplianceEnabled(psConfig.isDscComplianceEnabled());
+ }
+ if (psConfig.getRenderingMode() != null) {
+ psUtil.setRenderingMode(psConfig.getRenderingMode());
}
- psUtil.setSafeSetPageDevice(
- cfg.getChild("safe-set-page-device").getValueAsBoolean(false));
- psUtil.setDSCComplianceEnabled(
- cfg.getChild("dsc-compliant").getValueAsBoolean(true));
}
- /** {@inheritDoc} */
+ @Override
public void configure(IFDocumentHandler documentHandler) throws FOPException {
- Configuration cfg = super.getRendererConfig(documentHandler.getMimeType());
- if (cfg != null) {
- PSDocumentHandler psDocumentHandler = (PSDocumentHandler)documentHandler;
- configure(psDocumentHandler.getPSUtil(), cfg);
+ PSRendererConfig psConfig = (PSRendererConfig) getRendererConfig(documentHandler);
+ if (psConfig != null) {
+ PSDocumentHandler psDocumentHandler = (PSDocumentHandler) documentHandler;
+ PSRenderingUtil psUtil = psDocumentHandler.getPSUtil();
+ configure(psUtil, psConfig);
}
-
}
-
}
diff --git a/src/java/org/apache/fop/render/ps/PSRendererOption.java b/src/java/org/apache/fop/render/ps/PSRendererOption.java
new file mode 100644
index 000000000..4c3396921
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSRendererOption.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.ps;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * An enumeration of the PostScript renderer configuration options along with their default values.
+ */
+public enum PSRendererOption implements RendererConfigOption {
+ /** Indicates whether landscape pages should be rotated, default: false */
+ AUTO_ROTATE_LANDSCAPE("auto-rotate-landscape", false),
+ /** Sets the PostScript language leven, default: {@see PSGenerator#DEFAULT_LANGUAGE_LEVEL}*/
+ LANGUAGE_LEVEL("language-level", PSGenerator.DEFAULT_LANGUAGE_LEVEL),
+ /** Whether resources should be optimized in a post-processing run, default: false */
+ OPTIMIZE_RESOURCES("optimize-resources", false),
+ /** Indicates whether the "safe setpagedevice" mode is active, default: false */
+ SAFE_SET_PAGE_DEVICE("safe-set-page-device", false),
+ /** Indicates whether the PostScript output should be DSC compliant, default: true*/
+ DSC_COMPLIANT("dsc-compliant", true),
+ RENDERING_MODE("rendering", PSRenderingMode.QUALITY);
+
+ private final String name;
+ private final Object defaultValue;
+
+ private PSRendererOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+}
diff --git a/src/java/org/apache/fop/render/ps/PSRenderingUtil.java b/src/java/org/apache/fop/render/ps/PSRenderingUtil.java
index b22391718..4033c304f 100644
--- a/src/java/org/apache/fop/render/ps/PSRenderingUtil.java
+++ b/src/java/org/apache/fop/render/ps/PSRenderingUtil.java
@@ -33,11 +33,15 @@ import org.apache.fop.render.ps.extensions.PSCommentBefore;
import org.apache.fop.render.ps.extensions.PSExtensionAttachment;
import org.apache.fop.render.ps.extensions.PSSetupCode;
+import static org.apache.fop.render.ps.PSRendererOption.AUTO_ROTATE_LANDSCAPE;
+import static org.apache.fop.render.ps.PSRendererOption.LANGUAGE_LEVEL;
+import static org.apache.fop.render.ps.PSRendererOption.OPTIMIZE_RESOURCES;
+
/**
* Utility class which enables all sorts of features that are not directly connected to the
* normal rendering process.
*/
-public class PSRenderingUtil implements PSConfigurationConstants {
+public class PSRenderingUtil {
private FOUserAgent userAgent;
@@ -64,20 +68,21 @@ public class PSRenderingUtil implements PSConfigurationConstants {
PSRenderingUtil(FOUserAgent userAgent) {
this.userAgent = userAgent;
+ //PSRendererConfig confi = userAgent.getRendererConfig(rendererConfiguration, configCreator)
initialize();
}
private void initialize() {
Object obj;
- obj = userAgent.getRendererOptions().get(AUTO_ROTATE_LANDSCAPE);
+ obj = userAgent.getRendererOptions().get(AUTO_ROTATE_LANDSCAPE.getName());
if (obj != null) {
setAutoRotateLandscape(booleanValueOf(obj));
}
- obj = userAgent.getRendererOptions().get(LANGUAGE_LEVEL);
+ obj = userAgent.getRendererOptions().get(LANGUAGE_LEVEL.getName());
if (obj != null) {
setLanguageLevel(intValueOf(obj));
}
- obj = userAgent.getRendererOptions().get(OPTIMIZE_RESOURCES);
+ obj = userAgent.getRendererOptions().get(OPTIMIZE_RESOURCES.getName());
if (obj != null) {
setOptimizeResources(booleanValueOf(obj));
}
diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
index c52f45332..e30f6391b 100644
--- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
@@ -257,7 +257,7 @@ public class PSSVGHandler extends AbstractGenericSVGHandler
BridgeContext ctx = new PSBridgeContext(ua,
(strokeText ? null : psInfo.fontInfo),
- context.getUserAgent().getFactory().getImageManager(),
+ context.getUserAgent().getImageManager(),
context.getUserAgent().getImageSessionContext());
//Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine)
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index 2b3afaec7..1f89dc8f0 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -52,7 +52,7 @@ import org.apache.fop.util.CharUtilities;
import org.apache.fop.util.HexEncoder;
/**
- * Renders the attributed character iterator of a text node.
+ * Renders the attributed character iterator of a {@link org.apache.batik.gvt.TextNode TextNode}.
* This class draws the text directly using PostScript text operators so
* the text is not drawn using shapes which makes the PS files larger.
* <p>
diff --git a/src/java/org/apache/fop/render/ps/ResourceHandler.java b/src/java/org/apache/fop/render/ps/ResourceHandler.java
index 5594897ba..95b544ec2 100644
--- a/src/java/org/apache/fop/render/ps/ResourceHandler.java
+++ b/src/java/org/apache/fop/render/ps/ResourceHandler.java
@@ -287,7 +287,7 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
throws IOException {
final String uri = form.getImageURI();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
ImageInfo info = null;
try {
ImageSessionContext sessionContext = userAgent.getImageSessionContext();
@@ -299,7 +299,7 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
ImageFlavor[] flavors;
ImageHandlerRegistry imageHandlerRegistry
- = userAgent.getFactory().getImageHandlerRegistry();
+ = userAgent.getImageHandlerRegistry();
flavors = imageHandlerRegistry.getSupportedFlavors(formContext);
Map hints = ImageUtil.getDefaultHints(sessionContext);
diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java
index 956ea8b57..6c2d7c03d 100644
--- a/src/java/org/apache/fop/render/rtf/RTFHandler.java
+++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java
@@ -97,7 +97,6 @@ import org.apache.fop.fo.properties.EnumLength;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.layoutmgr.inline.ImageLayout;
import org.apache.fop.layoutmgr.table.ColumnSetup;
-import org.apache.fop.render.DefaultFontResolver;
import org.apache.fop.render.RendererEventProducer;
import org.apache.fop.render.rtf.rtflib.exceptions.RtfException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
@@ -169,7 +168,7 @@ public class RTFHandler extends FOEventHandler {
bDefer = true;
boolean base14Kerning = false;
- FontSetup.setup(fontInfo, null, new DefaultFontResolver(userAgent), base14Kerning);
+ FontSetup.setup(fontInfo, null, userAgent.getResourceResolver(), base14Kerning);
}
/**
@@ -1086,7 +1085,7 @@ public class RTFHandler extends FOEventHandler {
//set image data
FOUserAgent userAgent = eg.getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
info = manager.getImageInfo(uri, userAgent.getImageSessionContext());
putGraphic(eg, info);
@@ -1140,7 +1139,7 @@ public class RTFHandler extends FOEventHandler {
ImageXMLDOM image = new ImageXMLDOM(info, doc, ns);
FOUserAgent userAgent = ifo.getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
Map hints = ImageUtil.getDefaultHints(ua.getImageSessionContext());
Image converted = manager.convertImage(image, FLAVORS, hints);
putGraphic(ifo, converted);
@@ -1170,7 +1169,7 @@ public class RTFHandler extends FOEventHandler {
throws IOException {
try {
FOUserAgent userAgent = abstractGraphic.getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageManager manager = userAgent.getImageManager();
ImageSessionContext sessionContext = userAgent.getImageSessionContext();
Map hints = ImageUtil.getDefaultHints(sessionContext);
Image image = manager.getImage(info, FLAVORS, hints, sessionContext);
@@ -1701,7 +1700,7 @@ public class RTFHandler extends FOEventHandler {
Region regionBefore = pagemaster.getRegion(Constants.FO_REGION_BEFORE);
if (regionBefore != null) {
- FONode staticBefore = (FONode) pageSequence.getFlowMap().get(
+ FONode staticBefore = pageSequence.getFlowMap().get(
regionBefore.getRegionName());
if (staticBefore != null) {
recurseFONode(staticBefore);
@@ -1709,7 +1708,7 @@ public class RTFHandler extends FOEventHandler {
}
Region regionAfter = pagemaster.getRegion(Constants.FO_REGION_AFTER);
if (regionAfter != null) {
- FONode staticAfter = (FONode) pageSequence.getFlowMap().get(
+ FONode staticAfter = pageSequence.getFlowMap().get(
regionAfter.getRegionName());
if (staticAfter != null) {
recurseFONode(staticAfter);
diff --git a/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java b/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java
index 59c3bf5e6..a600047ae 100644
--- a/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/txt/TXTRendererConfigurator.java
@@ -19,24 +19,23 @@
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.DefaultRendererConfigurator;
import org.apache.fop.render.Renderer;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
/**
* TXT Renderer configurator
*/
-public class TXTRendererConfigurator extends PrintRendererConfigurator {
+public class TXTRendererConfigurator extends DefaultRendererConfigurator {
/**
* Default constructor
* @param userAgent user agent
*/
- public TXTRendererConfigurator(FOUserAgent userAgent) {
- super(userAgent);
+ public TXTRendererConfigurator(FOUserAgent userAgent, RendererConfigParser rendererConfigParser) {
+ super(userAgent, rendererConfigParser);
}
/**
@@ -45,10 +44,11 @@ public class TXTRendererConfigurator extends PrintRendererConfigurator {
* @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));
+ TxtRendererConfig config = (TxtRendererConfig) getRendererConfig(renderer);
+ if (config != null) {
+ TXTRenderer txtRenderer = (TXTRenderer) renderer;
+ txtRenderer.setEncoding(config.getEncoding());
}
}
+
}
diff --git a/src/java/org/apache/fop/render/txt/TXTRendererMaker.java b/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
index 740866e0c..150338120 100644
--- a/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
+++ b/src/java/org/apache/fop/render/txt/TXTRendererMaker.java
@@ -19,11 +19,12 @@
package org.apache.fop.render.txt;
+import org.apache.fop.apps.FOPException;
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;
+import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererConfigParser;
/**
* RendererMaker for the Plain Text Renderer.
@@ -32,22 +33,22 @@ public class TXTRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_PLAIN_TEXT};
- /**{@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent userAgent) {
return new TXTRenderer(userAgent);
}
- /**{@inheritDoc} */
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return new TXTRendererConfigurator(userAgent);
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ new TXTRendererConfigurator(userAgent, new TxtRendererConfigParser()).configure(renderer);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
diff --git a/src/java/org/apache/fop/render/txt/TxtRendererConfig.java b/src/java/org/apache/fop/render/txt/TxtRendererConfig.java
new file mode 100644
index 000000000..f597ee518
--- /dev/null
+++ b/src/java/org/apache/fop/render/txt/TxtRendererConfig.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.EnumMap;
+
+import org.apache.avalon.framework.configuration.Configuration;
+
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
+import org.apache.fop.render.RendererConfig;
+import org.apache.fop.render.RendererConfigOption;
+
+/**
+ * The Text renderer configuration data object.
+ */
+public final class TxtRendererConfig implements RendererConfig {
+
+ public enum TxtRendererOption implements RendererConfigOption {
+ ENCODING("encoding", "UTF-8");
+
+ private final String name;
+ private final Object defaultValue;
+
+ private TxtRendererOption(String name, Object defaultValue) {
+ this.name = name;
+ this.defaultValue = defaultValue;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+ }
+
+ private final EnumMap<TxtRendererOption, Object> params
+ = new EnumMap<TxtRendererOption, Object>(TxtRendererOption.class);
+
+ private final DefaultFontConfig fontConfig;
+
+ private TxtRendererConfig(DefaultFontConfig fontConfig) {
+ this.fontConfig = fontConfig;
+ }
+
+ public DefaultFontConfig getFontInfoConfig() {
+ return fontConfig;
+ }
+
+ public String getEncoding() {
+ return (String) params.get(TxtRendererOption.ENCODING);
+ }
+
+ /**
+ * The Text renderer configuration data parser.
+ */
+ public static final class TxtRendererConfigParser implements RendererConfigParser {
+
+ /** {@inheritDoc} */
+ public TxtRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
+ TxtRendererConfig config = new TxtRendererConfig(new DefaultFontConfigParser().parse(cfg,
+ userAgent.validateStrictly()));
+ if (cfg != null) {
+ TxtRendererOption option = TxtRendererOption.ENCODING;
+ String value = cfg.getChild(option.getName(), true).getValue(null);
+ config.params.put(option, value != null ? value : option.getDefaultValue());
+ }
+ return config;
+ }
+
+ /** {@inheritDoc} */
+ public String getMimeType() {
+ return MimeConstants.MIME_PLAIN_TEXT;
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/xml/XMLRendererMaker.java b/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
index f54c74b32..3110ed0ef 100644
--- a/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
+++ b/src/java/org/apache/fop/render/xml/XMLRendererMaker.java
@@ -19,12 +19,12 @@
package org.apache.fop.render.xml;
+import org.apache.fop.apps.FOPException;
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.
@@ -33,22 +33,22 @@ public class XMLRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_FOP_AREA_TREE};
- /**{@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent userAgent) {
return new XMLRenderer(userAgent);
}
- /**{@inheritDoc} */
- public RendererConfigurator getConfigurator(FOUserAgent userAgent) {
- return new PrintRendererConfigurator(userAgent);
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ PrintRendererConfigurator.createDefaultInstance(userAgent).configure(renderer);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
diff --git a/src/java/org/apache/fop/servlet/FopServlet.java b/src/java/org/apache/fop/servlet/FopServlet.java
index cfe7f6cbf..9dcf10a2b 100644
--- a/src/java/org/apache/fop/servlet/FopServlet.java
+++ b/src/java/org/apache/fop/servlet/FopServlet.java
@@ -21,7 +21,10 @@ package org.apache.fop.servlet;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URL;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -42,7 +45,10 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.io.Resource;
+import org.apache.fop.apps.io.ResourceResolver;
/**
* Example servlet to generate a PDF from a servlet.
@@ -91,16 +97,27 @@ public class FopServlet extends HttpServlet {
this.transFactory = TransformerFactory.newInstance();
this.transFactory.setURIResolver(this.uriResolver);
//Configure FopFactory as desired
- this.fopFactory = FopFactory.newInstance();
- this.fopFactory.setURIResolver(this.uriResolver);
- configureFopFactory();
+ // TODO: Double check this behaves properly!!
+ ResourceResolver resolver = new ResourceResolver() {
+ public OutputStream getOutputStream(URI uri) throws IOException {
+ URL url = getServletContext().getResource(uri.toASCIIString());
+ return url.openConnection().getOutputStream();
+ }
+
+ public Resource getResource(URI uri) throws IOException {
+ return new Resource(getServletContext().getResourceAsStream(uri.toASCIIString()));
+ }
+ };
+ FopFactoryBuilder builder = new FopFactoryBuilder(new File(".").toURI(), resolver);
+ configureFopFactory(builder);
+ fopFactory = builder.build();
}
/**
* This method is called right after the FopFactory is instantiated and can be overridden
* by subclasses to perform additional configuration.
*/
- protected void configureFopFactory() {
+ protected void configureFopFactory(FopFactoryBuilder builder) {
//Subclass and override this method to perform additional configuration
}
diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
index 954291a57..d413e3274 100644
--- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
+++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
@@ -19,23 +19,28 @@
package org.apache.fop.svg;
+import java.io.File;
+import java.net.URI;
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.CustomFontCollection;
-import org.apache.fop.fonts.FontCollection;
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.DefaultFontConfig;
+import org.apache.fop.fonts.DefaultFontConfigurator;
+import org.apache.fop.fonts.EmbedFontInfo;
+import org.apache.fop.fonts.FontCacheManagerFactory;
+import org.apache.fop.fonts.FontDetectorFactory;
import org.apache.fop.fonts.FontEventListener;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontInfoConfigurator;
import org.apache.fop.fonts.FontManager;
-import org.apache.fop.fonts.FontManagerConfigurator;
-import org.apache.fop.fonts.FontResolver;
-import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.fonts.FontSetup;
import org.apache.fop.pdf.PDFDocument;
-import org.apache.fop.render.pdf.PDFRendererConfigurator;
+import org.apache.fop.render.pdf.PDFRendererConfig;
+import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
/**
* Configurator class for PDFDocumentGraphics2D.
@@ -53,10 +58,13 @@ public class PDFDocumentGraphics2DConfigurator {
boolean useComplexScriptFeatures )
throws ConfigurationException {
PDFDocument pdfDoc = graphics.getPDFDocument();
-
- //Filter map
- pdfDoc.setFilterMap(
- PDFRendererConfigurator.buildFilterMapFromConfiguration(cfg));
+ try {
+ //Filter map
+ PDFRendererConfig pdfConfig = new PDFRendererConfigParser().build(null, cfg);
+ pdfDoc.setFilterMap(pdfConfig.getConfigOptions().getFilterMap());
+ } catch (FOPException e) {
+ throw new RuntimeException(e);
+ }
//Fonts
try {
@@ -78,30 +86,28 @@ public class PDFDocumentGraphics2DConfigurator {
throws FOPException {
FontInfo fontInfo = new FontInfo();
final boolean strict = false;
- FontResolver fontResolver = FontManager.createMinimalFontResolver(useComplexScriptFeatures);
- //TODO The following could be optimized by retaining the FontManager somewhere
- FontManager fontManager = new FontManager();
if (cfg != null) {
- FontManagerConfigurator fmConfigurator = new FontManagerConfigurator(cfg);
- fmConfigurator.configure(fontManager, strict);
- }
+ URI thisUri = new File(".").getAbsoluteFile().toURI();
+ InternalResourceResolver resourceResolver = ResourceResolverFactory.createDefaultInternalResourceResolver(thisUri);
+ //TODO The following could be optimized by retaining the FontManager somewhere
+ FontManager fontManager = new FontManager(resourceResolver, FontDetectorFactory.createDefault(),
+ FontCacheManagerFactory.createDefault());
- List fontCollections = new java.util.ArrayList();
- fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled()));
+ //TODO Make use of fontBaseURL, font substitution and referencing configuration
+ //Requires a change to the expected configuration layout
- if (cfg != null) {
- //TODO Wire in the FontEventListener
- FontEventListener listener = null; //new FontEventAdapter(eventBroadcaster);
- FontInfoConfigurator fontInfoConfigurator
- = new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict);
- List/*<EmbedFontInfo>*/ fontInfoList = new java.util.ArrayList/*<EmbedFontInfo>*/();
- fontInfoConfigurator.configure(fontInfoList);
- fontCollections.add(new CustomFontCollection(fontResolver, fontInfoList,
- fontResolver.isComplexScriptFeaturesEnabled()));
+ final FontEventListener listener = null;
+ DefaultFontConfig.DefaultFontConfigParser parser
+ = new DefaultFontConfig.DefaultFontConfigParser();
+ DefaultFontConfig fontInfoConfig = parser.parse(cfg, strict);
+ DefaultFontConfigurator fontInfoConfigurator
+ = new DefaultFontConfigurator(fontManager, listener, strict);
+ List<EmbedFontInfo> fontInfoList = fontInfoConfigurator.configure(fontInfoConfig);
+ fontManager.saveCache();
+ FontSetup.setup(fontInfo, fontInfoList, resourceResolver, useComplexScriptFeatures);
+ } else {
+ FontSetup.setup(fontInfo, useComplexScriptFeatures);
}
- fontManager.setup(fontInfo,
- (FontCollection[])fontCollections.toArray(
- new FontCollection[fontCollections.size()]));
return fontInfo;
}
diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java
index e222a08dd..30b787a77 100644
--- a/src/java/org/apache/fop/svg/PDFTranscoder.java
+++ b/src/java/org/apache/fop/svg/PDFTranscoder.java
@@ -133,7 +133,7 @@ public class PDFTranscoder extends AbstractFOPTranscoder {
}
} catch (Exception e) {
throw new TranscoderException(
- "Error while setting up PDFDocumentGraphics2D", e);
+ "Error while setting up PDFDocumentGraphics2D", e);
}
super.transcode(document, uri, output);
diff --git a/src/java/org/apache/fop/tools/TestConverter.java b/src/java/org/apache/fop/tools/TestConverter.java
index f453fecdf..3ce3eff35 100644
--- a/src/java/org/apache/fop/tools/TestConverter.java
+++ b/src/java/org/apache/fop/tools/TestConverter.java
@@ -21,6 +21,7 @@ package org.apache.fop.tools;
import java.io.File;
import java.io.OutputStream;
+import java.net.URI;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
@@ -50,9 +51,6 @@ import org.apache.fop.tools.anttasks.FileCompare;
*/
public class TestConverter {
- // configure fopFactory as desired
- private FopFactory fopFactory = FopFactory.newInstance();
-
private boolean failOnly = false;
private String outputFormat = MimeConstants.MIME_FOP_AREA_TREE;
private File destdir;
@@ -273,24 +271,17 @@ public class TestConverter {
}
try {
File xmlFile = new File(baseDir + "/" + xml);
- String baseURL = null;
- try {
- baseURL = xmlFile.getParentFile().toURI().toURL().toExternalForm();
- } catch (Exception e) {
- logger.error("Error setting base directory");
- }
+ URI baseUri = xmlFile.getParentFile().toURI();
InputHandler inputHandler = null;
if (xsl == null) {
inputHandler = new InputHandler(xmlFile);
} else {
- inputHandler = new InputHandler(xmlFile,
- new File(baseDir + "/"
- + xsl), null);
+ inputHandler = new InputHandler(xmlFile, new File(baseDir + "/" + xsl), null);
}
+ FopFactory fopFactory = FopFactory.newInstance(baseUri);
FOUserAgent userAgent = fopFactory.newFOUserAgent();
- userAgent.setBaseURL(baseURL);
userAgent.getRendererOptions().put("fineDetail", new Boolean(false));
userAgent.getRendererOptions().put("consistentOutput", new Boolean(true));
diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java
index 3cc93bafa..5e6c5141e 100644
--- a/src/java/org/apache/fop/tools/anttasks/Fop.java
+++ b/src/java/org/apache/fop/tools/anttasks/Fop.java
@@ -24,7 +24,7 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
-import java.net.MalformedURLException;
+import java.net.URI;
import java.util.List;
import java.util.Vector;
@@ -41,7 +41,9 @@ import org.apache.tools.ant.util.GlobPatternMapper;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
+import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.cli.InputHandler;
@@ -379,10 +381,10 @@ public class Fop extends Task {
class FOPTaskStarter {
// configure fopFactory as desired
- private FopFactory fopFactory = FopFactory.newInstance();
+ private final FopFactory fopFactory;
private Fop task;
- private String baseURL = null;
+ private URI baseUri;
/**
* logging instance
@@ -408,8 +410,21 @@ class FOPTaskStarter {
FOPTaskStarter(Fop task) throws SAXException, IOException {
this.task = task;
+ //Set base directory
+ if (task.getBasedir() != null) {
+ this.baseUri = task.getBasedir().toURI();
+ } else {
+ if (task.getFofile() != null) {
+ this.baseUri = task.getFofile().getParentFile().toURI();
+ }
+ }
if (task.getUserconfig() != null) {
- fopFactory.setUserConfig(task.getUserconfig());
+ FopFactoryBuilder confBuilder = new FopConfParser(
+ task.getUserconfig()).getFopFactoryBuilder();
+ confBuilder.setBaseURI(baseUri);
+ fopFactory = confBuilder.build();
+ } else {
+ fopFactory = FopFactory.newInstance(baseUri);
}
}
@@ -488,25 +503,7 @@ class FOPTaskStarter {
}
public void run() throws FOPException {
- //Set base directory
- if (task.getBasedir() != null) {
- try {
- this.baseURL = task.getBasedir().toURI().toURL().toExternalForm();
- } catch (MalformedURLException mfue) {
- logger.error("Error creating base URL from base directory", mfue);
- }
- } else {
- try {
- if (task.getFofile() != null) {
- this.baseURL = task.getFofile().getParentFile().toURI().toURL()
- .toExternalForm();
- }
- } catch (MalformedURLException mfue) {
- logger.error("Error creating base URL from XSL-FO input file", mfue);
- }
- }
-
- task.log("Using base URL: " + baseURL, Project.MSG_DEBUG);
+ task.log("Using base URI: " + baseUri, Project.MSG_DEBUG);
String outputFormat = normalizeOutputFormat(task.getFormat());
String newExtension = determineExtension(outputFormat);
@@ -598,12 +595,10 @@ class FOPTaskStarter {
}
try {
if (task.getRelativebase()) {
- this.baseURL = f.getParentFile().toURI().toURL()
- .toExternalForm();
+ this.baseUri = f.getParentFile().toURI();
}
- if (this.baseURL == null) {
- this.baseURL = fs.getDir(task.getProject()).toURI().toURL()
- .toExternalForm();
+ if (this.baseUri == null) {
+ this.baseUri = fs.getDir(task.getProject()).toURI();
}
} catch (Exception e) {
@@ -649,7 +644,6 @@ class FOPTaskStarter {
boolean success = false;
try {
FOUserAgent userAgent = fopFactory.newFOUserAgent();
- userAgent.setBaseURL(this.baseURL);
inputHandler.renderTo(userAgent, outputFormat, out);
success = true;
} catch (Exception ex) {
diff --git a/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java b/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java
index ce44eee19..0f3f737f7 100644
--- a/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java
+++ b/src/java/org/apache/fop/tools/fontlist/FontListGenerator.java
@@ -68,7 +68,8 @@ public class FontListGenerator {
IFDocumentHandlerConfigurator configurator = documentHandler.getConfigurator();
FontInfo fontInfo = new FontInfo();
- configurator.setupFontInfo(documentHandler, fontInfo);
+ configurator.setupFontInfo(documentHandler.getMimeType(), fontInfo);
+ documentHandler.setFontInfo(fontInfo);
return fontInfo;
}
diff --git a/src/java/org/apache/fop/tools/fontlist/FontListMain.java b/src/java/org/apache/fop/tools/fontlist/FontListMain.java
index b9b01f706..659f7ccac 100644
--- a/src/java/org/apache/fop/tools/fontlist/FontListMain.java
+++ b/src/java/org/apache/fop/tools/fontlist/FontListMain.java
@@ -64,7 +64,7 @@ public final class FontListMain {
private static final int GENERATE_FO = 2;
private static final int GENERATE_RENDERED = 3;
- private FopFactory fopFactory = FopFactory.newInstance();
+ private FopFactory fopFactory;
private File configFile;
private File outputFile;
@@ -78,7 +78,9 @@ public final class FontListMain {
private void prepare() throws SAXException, IOException {
if (this.configFile != null) {
- fopFactory.setUserConfig(this.configFile);
+ fopFactory = FopFactory.newInstance(configFile);
+ } else {
+ fopFactory = FopFactory.newInstance(new File(".").toURI());
}
}
diff --git a/src/java/org/apache/fop/util/ColorSpaceCache.java b/src/java/org/apache/fop/util/ColorSpaceCache.java
index 246477f6b..a249fe47b 100644
--- a/src/java/org/apache/fop/util/ColorSpaceCache.java
+++ b/src/java/org/apache/fop/util/ColorSpaceCache.java
@@ -21,19 +21,18 @@ package org.apache.fop.util;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
+import java.io.InputStream;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
-import javax.xml.transform.Source;
-import javax.xml.transform.URIResolver;
-import javax.xml.transform.stream.StreamSource;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.java2d.color.ICCColorSpaceWithIntent;
import org.apache.xmlgraphics.java2d.color.RenderingIntent;
-import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
/**
* Map with cached ICC based ColorSpace objects.
@@ -42,16 +41,15 @@ public class ColorSpaceCache {
/** logger instance */
private static Log log = LogFactory.getLog(ColorSpaceCache.class);
- private URIResolver resolver;
- private Map<String, ColorSpace> colorSpaceMap
- = Collections.synchronizedMap(new java.util.HashMap<String, ColorSpace>());
+ private InternalResourceResolver resourceResolver;
+ private Map<String, ColorSpace> colorSpaceMap = Collections.synchronizedMap(new HashMap<String, ColorSpace>());
/**
* Default constructor
- * @param resolver uri resolver
+ * @param resourceResolver uri resolver
*/
- public ColorSpaceCache(URIResolver resolver) {
- this.resolver = resolver;
+ public ColorSpaceCache(InternalResourceResolver resourceResolver) {
+ this.resourceResolver = resourceResolver;
}
/**
@@ -69,21 +67,21 @@ public class ColorSpaceCache {
* @param renderingIntent overriding rendering intent
* @return ICC ColorSpace object or null if ColorSpace could not be created
*/
- public ColorSpace get(String profileName, String base, String iccProfileSrc,
+ public ColorSpace get(String profileName, String iccProfileSrc,
RenderingIntent renderingIntent) {
- String key = profileName + ":" + base + iccProfileSrc;
+ String key = profileName + ":" + iccProfileSrc;
+ // TODO: This stuff needs some TLC, fix it!!
ColorSpace colorSpace = null;
if (!colorSpaceMap.containsKey(key)) {
try {
ICC_Profile iccProfile = null;
// First attempt to use the FOP URI resolver to locate the ICC
// profile
- Source src = resolver.resolve(iccProfileSrc, base);
- if (src != null && src instanceof StreamSource) {
+ InputStream stream = resourceResolver.getResource(iccProfileSrc);
+ if (stream != null) {
// FOP URI resolver found ICC profile - create ICC profile
// from the Source
- iccProfile = ColorProfileUtil.getICC_Profile(((StreamSource) src)
- .getInputStream());
+ iccProfile = ICC_Profile.getInstance(stream);
} else {
// TODO - Would it make sense to fall back on VM ICC
// resolution
@@ -100,6 +98,7 @@ public class ColorSpaceCache {
} catch (Exception e) {
// Ignore exception - will be logged a bit further down
// (colorSpace == null case)
+ log.warn("Exception thrown resolving the color space: " + e.getMessage());
}
if (colorSpace != null) {
diff --git a/src/java/org/apache/fop/util/ColorUtil.java b/src/java/org/apache/fop/util/ColorUtil.java
index 09e9dd50b..b18192657 100644
--- a/src/java/org/apache/fop/util/ColorUtil.java
+++ b/src/java/org/apache/fop/util/ColorUtil.java
@@ -404,10 +404,8 @@ public final class ColorUtil {
if (foUserAgent != null && iccProfileSrc != null) {
RenderingIntent renderingIntent = RenderingIntent.AUTO;
//TODO connect to fo:color-profile/@rendering-intent
- colorSpace = foUserAgent.getFactory().getColorSpaceCache().get(
- iccProfileName,
- foUserAgent.getBaseURL(), iccProfileSrc,
- renderingIntent);
+ colorSpace = foUserAgent.getColorSpaceCache().get(
+ iccProfileName, iccProfileSrc, renderingIntent);
}
if (colorSpace != null) {
// ColorSpace is available
@@ -488,10 +486,8 @@ public final class ColorUtil {
if (foUserAgent != null && iccProfileSrc != null) {
RenderingIntent renderingIntent = RenderingIntent.AUTO;
//TODO connect to fo:color-profile/@rendering-intent
- colorSpace = (ICC_ColorSpace)foUserAgent.getFactory().getColorSpaceCache().get(
- iccProfileName,
- foUserAgent.getBaseURL(), iccProfileSrc,
- renderingIntent);
+ colorSpace = (ICC_ColorSpace)foUserAgent.getColorSpaceCache().get(
+ iccProfileName, iccProfileSrc, renderingIntent);
}
if (colorSpace != null) {
ICC_Profile profile = colorSpace.getProfile();
diff --git a/src/sandbox/org/apache/fop/render/mif/MIFHandler.java b/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
index 5ef4c0940..008c090e4 100644
--- a/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
+++ b/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
@@ -57,7 +57,6 @@ import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fonts.FontSetup;
-import org.apache.fop.render.DefaultFontResolver;
// TODO: do we really want every method throwing a SAXException
@@ -91,7 +90,7 @@ public class MIFHandler extends FOEventHandler {
super(ua);
outStream = os;
boolean base14Kerning = false; //TODO - FIXME
- FontSetup.setup(fontInfo, null, new DefaultFontResolver(ua), base14Kerning);
+ FontSetup.setup(fontInfo, null, ua.getResourceResolver(), base14Kerning);
}
/** {@inheritDoc} */
diff --git a/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java
index fbb6728ca..091d904e5 100644
--- a/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java
+++ b/src/sandbox/org/apache/fop/render/svg/AbstractSVGDocumentHandler.java
@@ -28,6 +28,7 @@ import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.intermediate.AbstractXMLWritingIFDocumentHandler;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
@@ -53,6 +54,10 @@ public abstract class AbstractSVGDocumentHandler extends AbstractXMLWritingIFDoc
private int mode = MODE_NORMAL;
+ public AbstractSVGDocumentHandler(IFContext context) {
+ super(context);
+ }
+
/** {@inheritDoc} */
protected String getMainNamespace() {
return NAMESPACE;
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
index 6fd4d3618..12dd948e5 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
@@ -38,7 +38,6 @@ import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
-
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@@ -48,6 +47,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.fop.render.bitmap.BitmapRendererEventProducer;
import org.apache.fop.render.bitmap.MultiFileRenderingUtil;
import org.apache.fop.render.intermediate.DelegatingFragmentContentHandler;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.util.GenerationHelperContentHandler;
@@ -73,8 +73,8 @@ public class SVGDocumentHandler extends AbstractSVGDocumentHandler {
/**
* Default constructor.
*/
- public SVGDocumentHandler() {
- //nop
+ public SVGDocumentHandler(IFContext context) {
+ super(context);
}
/** {@inheritDoc} */
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java
index 1f2120234..75fc8b70e 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.svg;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
@@ -32,10 +31,8 @@ public class SVGDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker {
private static final String[] MIMES = new String[] {SVGConstants.MIME_TYPE};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- SVGDocumentHandler handler = new SVGDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new SVGDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPainter.java b/src/sandbox/org/apache/fop/render/svg/SVGPainter.java
index 147536ccb..ebd143a69 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGPainter.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGPainter.java
@@ -45,7 +45,6 @@ import org.apache.fop.render.ImageHandlerUtil;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.intermediate.AbstractIFPainter;
import org.apache.fop.render.intermediate.IFConstants;
-import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFState;
import org.apache.fop.render.intermediate.IFUtil;
@@ -59,12 +58,11 @@ import org.apache.fop.util.XMLUtil;
/**
* IFPainter implementation that writes SVG.
*/
-public class SVGPainter extends AbstractIFPainter implements SVGConstants {
-
- private AbstractSVGDocumentHandler parent;
+public class SVGPainter extends AbstractIFPainter<AbstractSVGDocumentHandler>
+ implements SVGConstants {
/** The SAX content handler that receives the generated XML events. */
- protected GenerationHelperContentHandler handler;
+ private GenerationHelperContentHandler handler;
private static final int MODE_NORMAL = 0;
private static final int MODE_TEXT = 1;
@@ -78,18 +76,12 @@ public class SVGPainter extends AbstractIFPainter implements SVGConstants {
*/
public SVGPainter(AbstractSVGDocumentHandler parent,
GenerationHelperContentHandler contentHandler) {
- super();
- this.parent = parent;
+ super(parent);
this.handler = contentHandler;
this.state = IFState.create();
}
/** {@inheritDoc} */
- protected IFContext getContext() {
- return parent.getContext();
- }
-
- /** {@inheritDoc} */
public void startViewport(AffineTransform transform, Dimension size, Rectangle clipRect)
throws IFException {
startViewport(SVGUtil.formatAffineTransformMptToPt(transform), size, clipRect);
@@ -190,7 +182,7 @@ public class SVGPainter extends AbstractIFPainter implements SVGConstants {
try {
establish(MODE_NORMAL);
- ImageManager manager = getUserAgent().getFactory().getImageManager();
+ ImageManager manager = getUserAgent().getImageManager();
ImageInfo info = null;
try {
ImageSessionContext sessionContext = getUserAgent().getImageSessionContext();
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
index 8ec374731..b97d3d261 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
@@ -21,12 +21,11 @@ package org.apache.fop.render.svg;
import java.awt.Dimension;
-import javax.xml.transform.Result;
-
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.fop.render.intermediate.IFConstants;
+import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.util.XMLUtil;
@@ -40,18 +39,8 @@ public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler {
/**
* Default constructor.
*/
- public SVGPrintDocumentHandler() {
- //nop
- }
-
- /**
- * Creates a new SVGPrintPainter that sends the XML content it generates to the given
- * SAX ContentHandler.
- * @param result the JAXP Result object to receive the generated content
- * @throws IFException if an error occurs setting up the output
- */
- public SVGPrintDocumentHandler(Result result) throws IFException {
- setResult(result);
+ public SVGPrintDocumentHandler(IFContext context) {
+ super(context);
}
/** {@inheritDoc} */
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java
index 8e212dfde..0a0e599ff 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandlerMaker.java
@@ -19,7 +19,6 @@
package org.apache.fop.render.svg;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.render.intermediate.AbstractIFDocumentHandlerMaker;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.fop.render.intermediate.IFDocumentHandler;
@@ -32,10 +31,8 @@ public class SVGPrintDocumentHandlerMaker extends AbstractIFDocumentHandlerMaker
private static final String[] MIMES = new String[] {SVGConstants.MIME_SVG_PRINT};
/** {@inheritDoc} */
- public IFDocumentHandler makeIFDocumentHandler(FOUserAgent ua) {
- SVGPrintDocumentHandler handler = new SVGPrintDocumentHandler();
- handler.setContext(new IFContext(ua));
- return handler;
+ public IFDocumentHandler makeIFDocumentHandler(IFContext ifContext) {
+ return new SVGPrintDocumentHandler(ifContext);
}
/** {@inheritDoc} */
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGRendererMaker.java b/src/sandbox/org/apache/fop/render/svg/SVGRendererMaker.java
index 892d01711..95c4effbb 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGRendererMaker.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGRendererMaker.java
@@ -19,6 +19,7 @@
package org.apache.fop.render.svg;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.AbstractRendererMaker;
@@ -31,20 +32,23 @@ public class SVGRendererMaker extends AbstractRendererMaker {
private static final String[] MIMES = new String[] {MimeConstants.MIME_SVG};
-
- /** {@inheritDoc} */
+ @Override
public Renderer makeRenderer(FOUserAgent ua) {
return new SVGRenderer(ua);
}
- /** {@inheritDoc} */
+ @Override
public boolean needsOutputStream() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public String[] getSupportedMimeTypes() {
return MIMES;
}
+ @Override
+ public void configureRenderer(FOUserAgent userAgent, Renderer renderer) throws FOPException {
+ // No-Op
+ }
}