summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Adams <gadams@apache.org>2012-07-02 13:38:33 +0000
committerGlenn Adams <gadams@apache.org>2012-07-02 13:38:33 +0000
commitb51ab6099afe8002472bc6fdc5c963becf2a7169 (patch)
treefb7807cdd54a7bac57af343da9bcd463378add0e
parent2f1b588c83f03011c4455d07ebf4ed3e9427e2ea (diff)
parent12e4f1844c62cc9ddfe27f91e2d59b62f0ad7456 (diff)
downloadxmlgraphics-fop-b51ab6099afe8002472bc6fdc5c963becf2a7169.tar.gz
xmlgraphics-fop-b51ab6099afe8002472bc6fdc5c963becf2a7169.zip
Rename branch to fop-1_1 to better handle progression to a final 1.1 release.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/fop-1_1@1356214 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--README18
-rw-r--r--build.xml28
-rw-r--r--checkstyle-5.1.xml204
-rw-r--r--examples/fo/advanced/cid-fonts.fo2
-rw-r--r--examples/fo/advanced/giro.fo14
-rw-r--r--examples/fo/basic/images.fo2
-rw-r--r--examples/fo/basic/tableunits.fo40
-rw-r--r--examples/fo/build.xml5
-rw-r--r--examples/fo/svg/embedding.fo4
-rw-r--r--examples/fo/tables/background.fo22
-rw-r--r--examples/fo/tables/borders.fo39
-rw-r--r--examples/fo/tables/break.fo10
-rw-r--r--examples/fo/tables/headfoot.fo14
-rw-r--r--examples/fo/tables/keep.fo12
-rw-r--r--examples/fo/tables/omit.fo10
-rw-r--r--examples/fo/tables/space.fo18
-rw-r--r--findbugs-exclude.xml51
-rw-r--r--lib/xmlgraphics-commons-1.5rc1.jarbin0 -> 600645 bytes
-rw-r--r--lib/xmlgraphics-commons-1.5svn.jarbin585921 -> 0 bytes
-rw-r--r--src/documentation/content/.htaccess42
-rw-r--r--src/documentation/content/doap.rdf17
-rw-r--r--src/documentation/content/xdocs/1.1/known-issues.xml85
-rw-r--r--src/documentation/content/xdocs/1.1rc1/accessibility.xml (renamed from src/documentation/content/xdocs/1.1/accessibility.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/anttask.xml (renamed from src/documentation/content/xdocs/1.1/anttask.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/compiling.xml (renamed from src/documentation/content/xdocs/1.1/compiling.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/complexscripts.xml (renamed from src/documentation/content/xdocs/1.1/complexscripts.xml)182
-rw-r--r--src/documentation/content/xdocs/1.1rc1/configuration.xml (renamed from src/documentation/content/xdocs/1.1/configuration.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/embedding.xml (renamed from src/documentation/content/xdocs/1.1/embedding.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/events.xml (renamed from src/documentation/content/xdocs/1.1/events.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/extensions.xml (renamed from src/documentation/content/xdocs/1.1/extensions.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/fonts.xml (renamed from src/documentation/content/xdocs/1.1/fonts.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/fotree/disabled-testcases.xml (renamed from src/documentation/content/xdocs/1.1/fotree/disabled-testcases.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/graphics.xml (renamed from src/documentation/content/xdocs/1.1/graphics.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/hyphenation.xml (renamed from src/documentation/content/xdocs/1.1/hyphenation.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/index.xml (renamed from src/documentation/content/xdocs/1.1/index.xml)8
-rw-r--r--src/documentation/content/xdocs/1.1rc1/intermediate.xml (renamed from src/documentation/content/xdocs/1.1/intermediate.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/known-issues.xml54
-rw-r--r--src/documentation/content/xdocs/1.1rc1/knownissues_overview.xml (renamed from src/documentation/content/xdocs/1.1/knownissues_overview.xml)13
-rw-r--r--src/documentation/content/xdocs/1.1rc1/layoutengine/disabled-testcases.xml (renamed from src/documentation/content/xdocs/1.1/layoutengine/disabled-testcases.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/metadata.xml (renamed from src/documentation/content/xdocs/1.1/metadata.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/output.xml (renamed from src/documentation/content/xdocs/1.1/output.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/pdfa.xml (renamed from src/documentation/content/xdocs/1.1/pdfa.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/pdfencryption.xml (renamed from src/documentation/content/xdocs/1.1/pdfencryption.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/pdfx.xml (renamed from src/documentation/content/xdocs/1.1/pdfx.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/running.xml (renamed from src/documentation/content/xdocs/1.1/running.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/servlets.xml (renamed from src/documentation/content/xdocs/1.1/servlets.xml)0
-rw-r--r--src/documentation/content/xdocs/1.1rc1/upgrading.xml (renamed from src/documentation/content/xdocs/1.1/upgrading.xml)0
-rw-r--r--src/documentation/content/xdocs/bugs.xml2
-rw-r--r--src/documentation/content/xdocs/compliance.ihtml45
-rw-r--r--src/documentation/content/xdocs/download.xml33
-rw-r--r--src/documentation/content/xdocs/examples.xml10
-rw-r--r--src/documentation/content/xdocs/faq.xml12
-rw-r--r--src/documentation/content/xdocs/fo.xml4
-rw-r--r--src/documentation/content/xdocs/fo/align.fo25
-rw-r--r--src/documentation/content/xdocs/fo/align.fo.pdfbin4689 -> 0 bytes
-rw-r--r--src/documentation/content/xdocs/fo/align.pdfbin0 -> 9284 bytes
-rw-r--r--src/documentation/content/xdocs/fo/align2.fo27
-rw-r--r--src/documentation/content/xdocs/fo/align2.fo.pdfbin4299 -> 0 bytes
-rw-r--r--src/documentation/content/xdocs/fo/align2.pdfbin0 -> 8797 bytes
-rw-r--r--src/documentation/content/xdocs/fo/build.xml70
-rw-r--r--src/documentation/content/xdocs/fo/embed.fo25
-rw-r--r--src/documentation/content/xdocs/fo/embed.fo.pdf87
-rw-r--r--src/documentation/content/xdocs/fo/embed.pdfbin0 -> 8249 bytes
-rw-r--r--src/documentation/content/xdocs/fo/fonts.fo48
-rw-r--r--src/documentation/content/xdocs/fo/fonts.fo.pdf160
-rw-r--r--src/documentation/content/xdocs/fo/fonts.pdfbin0 -> 20432 bytes
-rw-r--r--src/documentation/content/xdocs/fo/size.fo25
-rw-r--r--src/documentation/content/xdocs/fo/size.fo.pdfbin5516 -> 0 bytes
-rw-r--r--src/documentation/content/xdocs/fo/size.pdfbin0 -> 9508 bytes
-rw-r--r--src/documentation/content/xdocs/gethelp.xml2
-rw-r--r--src/documentation/content/xdocs/index.xml21
-rw-r--r--src/documentation/content/xdocs/knownissues.xml29
-rw-r--r--src/documentation/content/xdocs/license.xml4
-rw-r--r--src/documentation/content/xdocs/maillist.xml4
-rw-r--r--src/documentation/content/xdocs/news-data.xml8
-rw-r--r--src/documentation/content/xdocs/news.xml15
-rw-r--r--src/documentation/content/xdocs/quickstartguide.xml16
-rw-r--r--src/documentation/content/xdocs/resources.xml2
-rw-r--r--src/documentation/content/xdocs/site.xml22
-rw-r--r--src/documentation/content/xdocs/status.xml10
-rw-r--r--src/documentation/content/xdocs/tabs.xml2
-rw-r--r--src/documentation/content/xdocs/team.xml4
-rw-r--r--src/documentation/content/xdocs/trunk/configuration.xml18
-rw-r--r--src/documentation/content/xdocs/trunk/fonts.xml10
-rw-r--r--src/documentation/content/xdocs/trunk/graphics.xml13
-rw-r--r--src/documentation/resources/stylesheets/known-issues2document.xsl6
-rw-r--r--src/java/META-INF/services/org.apache.fop.render.ImageHandler2
-rw-r--r--src/java/org/apache/fop/accessibility/Accessibility.java6
-rw-r--r--src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java25
-rw-r--r--src/java/org/apache/fop/afp/AFPGraphics2D.java4
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageObject.java6
-rw-r--r--src/java/org/apache/fop/afp/modca/PresentationTextData.java2
-rw-r--r--src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java3
-rw-r--r--src/java/org/apache/fop/apps/FOUserAgent.java5
-rw-r--r--src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java2
-rw-r--r--src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java41
-rw-r--r--src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java2
-rw-r--r--src/java/org/apache/fop/fo/FOEventHandler.java14
-rw-r--r--src/java/org/apache/fop/fo/flow/Wrapper.java19
-rw-r--r--src/java/org/apache/fop/fo/properties/CondLengthProperty.java5
-rw-r--r--src/java/org/apache/fop/fonts/CIDFontType.java2
-rw-r--r--src/java/org/apache/fop/fonts/CMapSegment.java (renamed from src/java/org/apache/fop/fonts/BFEntry.java)39
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java40
-rw-r--r--src/java/org/apache/fop/fonts/CustomFontCollection.java2
-rw-r--r--src/java/org/apache/fop/fonts/EmbedFontInfo.java23
-rw-r--r--src/java/org/apache/fop/fonts/EmbeddingMode.java58
-rw-r--r--src/java/org/apache/fop/fonts/EncodingMode.java2
-rw-r--r--src/java/org/apache/fop/fonts/FontInfoConfigurator.java6
-rw-r--r--src/java/org/apache/fop/fonts/FontLoader.java22
-rw-r--r--src/java/org/apache/fop/fonts/FontReader.java13
-rw-r--r--src/java/org/apache/fop/fonts/FontType.java5
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java10
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java62
-rw-r--r--src/java/org/apache/fop/fonts/MutableFont.java6
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteFont.java24
-rw-r--r--src/java/org/apache/fop/fonts/apps/TTFReader.java30
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java6
-rw-r--r--src/java/org/apache/fop/fonts/truetype/FontFileReader.java29
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java118
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java8
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java709
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java65
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java48
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java49
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java525
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFTableName.java163
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java37
-rw-r--r--src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java16
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakElement.java34
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthPenalty.java7
-rw-r--r--src/java/org/apache/fop/pdf/AbstractPDFStream.java9
-rw-r--r--src/java/org/apache/fop/pdf/AlphaRasterImage.java4
-rw-r--r--src/java/org/apache/fop/pdf/BitmapImage.java20
-rw-r--r--src/java/org/apache/fop/pdf/PDFColor.java2
-rw-r--r--src/java/org/apache/fop/pdf/PDFEmbeddedFile.java5
-rw-r--r--src/java/org/apache/fop/pdf/PDFFactory.java5
-rw-r--r--src/java/org/apache/fop/pdf/PDFImage.java8
-rw-r--r--src/java/org/apache/fop/pdf/PDFImageXObject.java5
-rw-r--r--src/java/org/apache/fop/pdf/PDFObject.java6
-rw-r--r--src/java/org/apache/fop/pdf/PDFResources.java54
-rw-r--r--src/java/org/apache/fop/render/ImageHandler.java3
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java2
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java4
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java2
-rw-r--r--src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFContext.java4
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFUtil.java8
-rw-r--r--src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java3
-rw-r--r--src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java2
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DPainter.java3
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java3
-rw-r--r--src/java/org/apache/fop/render/pcl/PCLPainter.java3
-rw-r--r--src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java83
-rw-r--r--src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java260
-rw-r--r--src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java73
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java65
-rw-r--r--src/java/org/apache/fop/render/ps/FontResourceCache.java17
-rw-r--r--src/java/org/apache/fop/render/ps/ImageEncoderPNG.java113
-rw-r--r--src/java/org/apache/fop/render/ps/NativeTextHandler.java6
-rw-r--r--src/java/org/apache/fop/render/ps/PSDocumentHandler.java22
-rw-r--r--src/java/org/apache/fop/render/ps/PSEventProducer.java7
-rw-r--r--src/java/org/apache/fop/render/ps/PSEventProducer.xml1
-rw-r--r--src/java/org/apache/fop/render/ps/PSFontResource.java77
-rw-r--r--src/java/org/apache/fop/render/ps/PSFontUtils.java440
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java111
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java26
-rw-r--r--src/java/org/apache/fop/render/ps/PSPainter.java66
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java45
-rw-r--r--src/java/org/apache/fop/render/ps/ResourceHandler.java10
-rw-r--r--src/java/org/apache/fop/render/ps/fonts/PSTTFGenerator.java101
-rw-r--r--src/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStream.java75
-rw-r--r--src/java/org/apache/fop/render/ps/fonts/PSTTFOutputStream.java62
-rw-r--r--src/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStream.java59
-rw-r--r--src/java/org/apache/fop/svg/PDFAElementBridge.java2
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java2
-rw-r--r--src/java/org/apache/fop/traits/MinOptMax.java5
-rw-r--r--src/java/org/apache/fop/traits/TraitEnum.java4
-rw-r--r--src/java/org/apache/fop/util/ColorExt.java2
-rw-r--r--src/java/org/apache/fop/util/HexEncoder.java57
-rw-r--r--src/sandbox/org/apache/fop/render/mif/MIFHandler.java60
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java3
-rw-r--r--src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java3
-rw-r--r--status.xml41
-rw-r--r--test/java/org/apache/fop/UtilityCodeTestSuite.java8
-rw-r--r--test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java15
-rw-r--r--test/java/org/apache/fop/accessibility/fo/artifact.fo97
-rw-r--r--test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl2
-rw-r--r--test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java3
-rw-r--r--test/java/org/apache/fop/fonts/EncodingModeTestCase.java18
-rw-r--r--test/java/org/apache/fop/fonts/FOPFontsTestSuite.java42
-rw-r--r--test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java304
-rw-r--r--test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java7
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java427
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java13
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java76
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.java153
-rw-r--r--test/java/org/apache/fop/render/RawPNGTestUtil.java92
-rw-r--r--test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java142
-rw-r--r--test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java133
-rw-r--r--test/java/org/apache/fop/render/ps/RenderPSTestSuite.java43
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java120
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java109
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java90
-rw-r--r--test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java87
-rw-r--r--test/java/org/apache/fop/svg/PDFGraphics2DTestCase.java48
-rw-r--r--test/java/org/apache/fop/util/HexEncoderTestCase.java61
-rw-r--r--test/pdf/accessibility/pdf/role.pdfbin19023 -> 18600 bytes
-rw-r--r--test/pdf/accessibility/role.fo4
-rw-r--r--test/resources/fonts/ttf/DroidSansMono.LICENSE18
-rw-r--r--test/resources/fonts/ttf/DroidSansMono.ttfbin0 -> 78296 bytes
214 files changed, 6053 insertions, 2077 deletions
diff --git a/README b/README
index 01b981c59..0fc91455d 100644
--- a/README
+++ b/README
@@ -93,12 +93,12 @@ http://xmlgraphics.apache.org/fop/stable/running.html
RELEASE NOTES
==============================================================================
-Version 1.1
-===========
+Version 1.1rc1
+==============
-This is a minor (dot) release of Apache FOP, which primarily addresses
-bug fixes and also adds a number of new features. See below for
-details.
+This is a candidate release of the next, minor (dot) release of Apache FOP,
+which primarily addresses bug fixes and also adds a number of new features.
+See below for details.
Compliance
----------
@@ -113,14 +113,14 @@ Known issues
A detailed list of known issues in this release is available at
http://xmlgraphics.apache.org/fop/1.1/knownissues_overview.html.
-Major Changes in Version 1.1
-----------------------------
+Major Changes in Version 1.1rc1
+-------------------------------
* Adds support for complex scripts, in particular those that require
either bidirectional processing or advanced typographic tables in
fonts (e.g., the GSUB and GPOS tables of OpenType).
* Adds support for fo:bidi-override and (relatively) full support
- for writing-mode='tb-rl' (or equivalent).
+ for writing-mode='rl-tb' (or equivalent).
* Adds support for Unicode BIDI Control characters: U+200E LEFT-TO-RIGHT
MARK (LRM), U+200F RIGHT-TO-LEFT MARK (RLM), U+202A LEFT-TO-RIGHT EMBEDDING
(LRE), U+202B RIGHT-TO-LEFT EMBEDDING (RLE), U+202D LEFT-TO-RIGHT OVERRIDE
@@ -128,7 +128,7 @@ Major Changes in Version 1.1
FORMATTING (PDF).
A more detailed list of changes in this release is available at
-http://xmlgraphics.apache.org/fop/1.1/changes_1.1.html.
+http://xmlgraphics.apache.org/fop/1.1rc1/changes_1.1rc1.html.
A more detailed list of changes in this and earlier releases is available at
http://xmlgraphics.apache.org/fop/changes.html.
diff --git a/build.xml b/build.xml
index 5ddd58e72..e0c3c97bc 100644
--- a/build.xml
+++ b/build.xml
@@ -143,7 +143,7 @@ list of possible build targets.
<property name="Name" value="Apache FOP"/>
<property name="name" value="fop"/>
<property name="NAME" value="FOP"/>
- <property name="version" value="1.1"/>
+ <property name="version" value="1.1rc1"/>
<property name="year" value="1999-2012"/>
<property name="javac.debug" value="on"/>
<property name="javac.optimize" value="off"/>
@@ -864,16 +864,28 @@ list of possible build targets.
<target name="junit-text-linebreak" depends="junit-compile" description="Runs FOP's JUnit unicode linebreak tests" if="junit.present">
<junit-run title="Unicode UAX#14 support" testsuite="org.apache.fop.text.linebreak.LineBreakStatusTestCase" outfile="TEST-linebreak"/>
</target>
+ <target name="junit-fonts" depends="junit-compile">
+ <echo message="Running tests for the fonts package"/>
+ <junit-run title="fonts" testsuite="org.apache.fop.fonts.FOPFontsTestSuite" outfile="TEST-fonts"/>
+ </target>
+ <target name="junit-render-ps" depends="junit-compile">
+ <echo message="Running tests for the render ps package"/>
+ <junit-run title="render-ps" testsuite="org.apache.fop.render.ps.RenderPSTestSuite" outfile="TEST-render-ps"/>
+ </target>
<target name="junit-render-pdf" depends="junit-compile">
<junit-run title="render-pdf" testsuite="org.apache.fop.render.pdf.RenderPDFTestSuite" outfile="TEST-render-pdf"/>
</target>
<target name="junit-complexscripts" depends="junit-compile">
<junit-run title="complexscripts" testsuite="org.apache.fop.complexscripts.ComplexScriptsTestSuite" outfile="TEST-complexscripts"/>
</target>
- <target name="junit-reduced" depends="junit-userconfig, junit-basic, junit-transcoder, junit-text-linebreak, junit-fotree, junit-render-pdf, junit-complexscripts"/>
+ <target name="junit-reduced" depends="junit-userconfig, junit-basic, junit-transcoder,
+ junit-text-linebreak, junit-fotree, junit-fonts, junit-render-pdf, junit-render-ps,
+ junit-complexscripts"/>
<target name="junit" depends="junit-all" description="Runs all of FOP's JUnit tests"
if="junit.present">
- <fail><condition><or><isset property="fop.junit.error"/><isset property="fop.junit.failure"/><not><isset property="hyphenation.present"/></not></or></condition>
+ <fail><condition><or><isset property="fop.junit.error"/><isset
+ property="fop.junit.failure"/><not><isset
+ property="hyphenation.present"/></not></or></condition>
NOTE:
**************************************************************************
* One or more of the Junit tests had Failures or Errors or were skipped! *
@@ -1438,14 +1450,20 @@ NOTE:
</delete>
</target>
<target name="validate-xdocs" description="Validate the xdocs. Point schemas.dir to Forrest's 'schemas' directory.">
- <property name="schemas.dir" value="../xml-forrest/src/resources/schema"/>
+ <property name="schemas.dir" value="../xml-forrest/main/webapp/resources/schema"/>
<xmlvalidate failonerror="no">
- <fileset dir="${xdocs.dir}" includes="**.xml"/>
+ <fileset dir="${xdocs.dir}">
+ <include name="**.xml"/>
+ <exclude name="**/site.xml"/>
+ <exclude name="**/news-data.xml"/>
+ </fileset>
<xmlcatalog>
<entity publicId="-//APACHE//DTD Compliance V1.0//EN" location="src/documentation/resources/schema/dtd/compliance-v10.dtd"/>
<entity publicId="-//APACHE//DTD Documentation V1.1//EN" location="${schemas.dir}/dtd/document-v11.dtd"/>
+ <entity publicId="-//APACHE//DTD Documentation V1.3//EN" location="${schemas.dir}/dtd/document-v13.dtd"/>
<entity publicId="-//APACHE//DTD Specification V1.1//EN" location="${schemas.dir}/dtd/specification-v11.dtd"/>
<entity publicId="-//APACHE//DTD FAQ V1.1//EN" location="${schemas.dir}/dtd/faq-v11.dtd"/>
+ <entity publicId="-//APACHE//DTD FAQ V1.3//EN" location="${schemas.dir}/dtd/faq-v13.dtd"/>
<entity publicId="-//APACHE//DTD Changes V1.1//EN" location="${schemas.dir}/dtd/changes-v11.dtd"/>
<entity publicId="-//APACHE//DTD Todo V1.1//EN" location="${schemas.dir}/dtd/todo-v11.dtd"/>
<entity publicId="-//APACHE//DTD Cocoon Documentation Book V1.0//EN" location="${schemas.dir}/dtd/book-cocoon-v10.dtd"/>
diff --git a/checkstyle-5.1.xml b/checkstyle-5.1.xml
deleted file mode 100644
index 8a393d452..000000000
--- a/checkstyle-5.1.xml
+++ /dev/null
@@ -1,204 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
-<module name="Checker">
- <module name="TreeWalker">
- <module name="ArrayTypeStyleCheck">
- <property name="javaStyle" value="true"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="ModifierOrderCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="RedundantModifierCheck">
- <property name="severity" value="warning"/>
- <property name="tokens" value="METHOD_DEF, VARIABLE_DEF"/>
- </module>
- <module name="UpperEllCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="AvoidNestedBlocksCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="EmptyBlockCheck">
- <property name="option" value="text"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_FOR, LITERAL_TRY, LITERAL_WHILE, STATIC_INIT"/>
- </module>
- <module name="LeftCurlyCheck">
- <property name="maxLineLength" value="100"/>
- <property name="option" value="eol"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="CLASS_DEF, CTOR_DEF, INTERFACE_DEF, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF"/>
- </module>
- <module name="NeedBracesCheck">
- <property name="severity" value="warning"/>
- <property name="tokens" value="LITERAL_DO, LITERAL_ELSE, LITERAL_IF, LITERAL_FOR, LITERAL_WHILE"/>
- </module>
- <module name="RightCurlyCheck">
- <property name="option" value="same"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="LITERAL_CATCH, LITERAL_ELSE, LITERAL_TRY"/>
- </module>
- <module name="DoubleCheckedLockingCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="EmptyStatementCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="EqualsHashCodeCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="InnerAssignmentCheck">
- <property name="severity" value="warning"/>
- <property name="tokens" value="ASSIGN, BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, DIV_ASSIGN, MINUS_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN"/>
- </module>
- <module name="MissingSwitchDefaultCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="SimplifyBooleanExpressionCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="SimplifyBooleanReturnCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="FinalClassCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="HideUtilityClassConstructorCheck">
- <property name="severity" value="warning"/>
- </module>
- <module name="VisibilityModifierCheck">
- <property name="packageAllowed" value="false"/>
- <property name="protectedAllowed" value="true"/>
- <property name="publicMemberPattern" value="^serialVersionUID"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="AvoidStarImportCheck">
- <property name="severity" value="error"/>
- </module>
- <module name="JavadocMethodCheck">
- <property name="allowMissingParamTags" value="false"/>
- <property name="allowMissingReturnTag" value="false"/>
- <property name="allowMissingThrowsTags" value="false"/>
- <property name="allowThrowsTagsForSubclasses" value="false"/>
- <property name="allowUndeclaredRTE" value="false"/>
- <property name="scope" value="protected"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="METHOD_DEF, CTOR_DEF"/>
- </module>
- <module name="JavadocTypeCheck">
- <property name="scope" value="protected"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="CLASS_DEF, INTERFACE_DEF"/>
- </module>
- <module name="JavadocVariableCheck">
- <property name="scope" value="protected"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="ConstantNameCheck">
- <property name="format" value="^([A-Z](_?[A-Z0-9]+)*)|(log)$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="LocalFinalVariableNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="LocalVariableNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="MemberNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="MethodNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="PackageNameCheck">
- <property name="format" value="^[a-z]+(\.[a-zA-Z_][a-zA-Z0-9_]*)*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="ParameterNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="StaticVariableNameCheck">
- <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="TypeNameCheck">
- <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="CLASS_DEF, INTERFACE_DEF"/>
- </module>
- <module name="LineLengthCheck">
- <property name="ignorePattern" value="^$"/>
- <property name="max" value="100"/>
- <property name="severity" value="warning"/>
- <property name="tabWidth" value="4"/>
- </module>
- <module name="MethodLengthCheck">
- <property name="max" value="150"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="METHOD_DEF, CTOR_DEF"/>
- </module>
- <module name="ParameterNumberCheck">
- <property name="max" value="7"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="METHOD_DEF, CTOR_DEF"/>
- </module>
- <module name="EmptyForIteratorPadCheck">
- <property name="option" value="nospace"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="NoWhitespaceAfterCheck">
- <property name="allowLineBreaks" value="true"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="ARRAY_INIT, BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/>
- </module>
- <module name="NoWhitespaceBeforeCheck">
- <property name="allowLineBreaks" value="true"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="SEMI, POST_DEC, POST_INC"/>
- </module>
- <module name="OperatorWrapCheck">
- <property name="option" value="nl"/>
- <property name="severity" value="warning"/>
- <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/>
- </module>
- <module name="WhitespaceAfterCheck">
- <property name="severity" value="warning"/>
- <property name="tokens" value="COMMA, SEMI"/>
- </module>
- <module name="WhitespaceAroundCheck">
- <property name="severity" value="warning"/>
- <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/>
- </module>
- <module name="FileContentsHolder"/>
- </module>
- <module name="RegexpHeader">
- <property name="headerFile" value="${samedir}/checkstyle.header"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="FileLengthCheck">
- <property name="max" value="2000"/>
- <property name="severity" value="warning"/>
- </module>
- <module name="FileTabCharacter">
- <property name="severity" value="error"/>
- </module>
- <module name="SuppressionFilter">
- <property name="file" value="${samedir}/checkstyle-suppressions.xml"/>
- </module>
- <module name="SuppressionCommentFilter">
- <property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/>
- <property name="onCommentFormat" value="CSON\: ([\w\|]+)"/>
- <property name="checkFormat" value="$1"/>
- </module>
- <module name="SuppressWithNearbyCommentFilter">
- <property name="commentFormat" value="CSOK\: ([\w\|]+)"/>
- <property name="checkFormat" value="$1"/>
- <property name="influenceFormat" value="0"/>
- </module>
-</module>
diff --git a/examples/fo/advanced/cid-fonts.fo b/examples/fo/advanced/cid-fonts.fo
index 526ebea06..cdcb4737c 100644
--- a/examples/fo/advanced/cid-fonts.fo
+++ b/examples/fo/advanced/cid-fonts.fo
@@ -369,7 +369,7 @@ This font contains no embedding license restrictions
</fo:block>
</fo:wrapper>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
<fo:table-column column-width="50mm"/>
diff --git a/examples/fo/advanced/giro.fo b/examples/fo/advanced/giro.fo
index 5b5422ec9..9f1a6723a 100644
--- a/examples/fo/advanced/giro.fo
+++ b/examples/fo/advanced/giro.fo
@@ -32,7 +32,7 @@
<fo:block-container absolute-position="absolute" width="100%" height="100%" border-top-color="silver" border-top-style="dotted" border-top-width="0.13mm">
<fo:block/>
</fo:block-container>
- <fo:table space-before.optimum="1in div 12" margin-left="2in div 12" margin-top="1in div 10" font-family="sans-serif" font-size="7pt" color="green">
+ <fo:table space-before.optimum="1in div 12" margin-left="2in div 12" margin-top="1in div 10" font-family="sans-serif" font-size="7pt" color="green" table-layout="fixed" width="100%">
<fo:table-column column-width="8in div 10 - 2in div 12"/>
<fo:table-column border-right-style="solid" border-right-width="0.5mm" column-width="36in div 10"/>
<fo:table-column column-width="5in div 10"/>
@@ -107,7 +107,7 @@
<fo:block>Från konto nr</fo:block>
</fo:table-cell>
<fo:table-cell border-bottom-style="solid" border-bottom-width="0.13mm" padding-top="6mm" display-align="after">
- <fo:table height="3mm">
+ <fo:table height="3mm" table-layout="fixed" width="100%">
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
@@ -182,7 +182,7 @@
<fo:block color="black">16.6.2006</fo:block>
</fo:table-cell>
<fo:table-cell border-bottom-style="solid" border-bottom-width="0.5mm" padding-left="2mm" padding-top="4mm" font-size="10pt">
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="0.5cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-body>
@@ -201,7 +201,7 @@
<fo:table-row height="13in div 12 - 5mm">
<fo:table-cell number-columns-spanned="4" padding-left="40mm" display-align="after">
<fo:block>
- <fo:table height="5in div 12" margin-left="2.5mm" margin-right="2.5mm"><!--105-->
+ <fo:table height="5in div 12" margin-left="2.5mm" margin-right="2.5mm" table-layout="fixed" width="100%"><!--105-->
<fo:table-column column-width="0.5mm"/>
<fo:table-column column-width="0.25mm"/>
<fo:table-column column-width="0.25mm"/>
@@ -950,7 +950,7 @@
</fo:page-sequence>
<fo:page-sequence master-reference="A4">
<fo:static-content flow-name="xsl-region-after">
- <fo:table space-before.optimum="1in div 12" margin-left="2in div 12" margin-top="1in div 10" font-family="sans-serif" font-size="7pt" color="green">
+ <fo:table space-before.optimum="1in div 12" margin-left="2in div 12" margin-top="1in div 10" font-family="sans-serif" font-size="7pt" color="green" table-layout="fixed" width="100%">
<fo:table-column column-width="8in div 10 - 2in div 12"/>
<fo:table-column border-right-style="solid" border-right-width="0.5mm" column-width="36in div 10"/>
<fo:table-column column-width="5in div 10"/>
@@ -1025,7 +1025,7 @@
<fo:block>Från konto nr</fo:block>
</fo:table-cell>
<fo:table-cell border-bottom-style="solid" border-bottom-width="0.13mm" padding-top="6mm" display-align="after">
- <fo:table height="3mm">
+ <fo:table height="3mm" table-layout="fixed" width="100%">
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
<fo:table-column border-right-style="solid" border-right-width="0.13mm" column-width="0.2in"/>
@@ -1100,7 +1100,7 @@
<fo:block color="black">16.6.2006</fo:block>
</fo:table-cell>
<fo:table-cell border-bottom-style="solid" border-bottom-width="0.5mm" padding-left="2mm" padding-top="4mm" font-size="10pt">
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="0.5cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-body>
diff --git a/examples/fo/basic/images.fo b/examples/fo/basic/images.fo
index 3bb864fd8..daabcd31b 100644
--- a/examples/fo/basic/images.fo
+++ b/examples/fo/basic/images.fo
@@ -31,8 +31,6 @@
odd-or-even="even" />
<fo:conditional-page-master-reference master-reference="right"
odd-or-even="odd" />
- <!-- recommended fallback procedure -->
- <fo:conditional-page-master-reference master-reference="rest" />
</fo:repeatable-page-master-alternatives>
</fo:page-sequence-master>
</fo:layout-master-set>
diff --git a/examples/fo/basic/tableunits.fo b/examples/fo/basic/tableunits.fo
index aca927c4a..1a1c8c9e1 100644
--- a/examples/fo/basic/tableunits.fo
+++ b/examples/fo/basic/tableunits.fo
@@ -67,9 +67,9 @@
<fo:block space-before="12pt" space-after="6pt">The next table has width=100% on the table no column widths specified on the table-column element.</fo:block>
<!-- table start -->
<fo:table border-collapse="separate" table-layout="fixed" width="100%">
- <fo:table-column background-color="yellow"/>
- <fo:table-column background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="yellow"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="blue"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
@@ -83,7 +83,7 @@
<fo:block space-before="12pt" space-after="6pt">The next table has fixed column widths=13cm, ipd.optimum=12cm and ipd.max = 100%.</fo:block>
<!-- table start -->
<fo:table border-collapse="separate"
- table-layout="fixed"
+ table-layout="fixed" width="100%"
inline-progression-dimension="12cm"
inline-progression-dimension.maximum="100%"
>
@@ -122,8 +122,8 @@
<!-- table start -->
<fo:table border-collapse="separate" table-layout="fixed" width="70% + 1cm">
<fo:table-column column-width="from-parent('width') div 3" background-color="yellow"/>
- <fo:table-column background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="blue"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
@@ -140,11 +140,11 @@
</fo:block>
<!-- table start -->
<fo:table border-collapse="separate"
- table-layout="fixed"
+ table-layout="fixed" width="100%"
inline-progression-dimension="15cm">
- <fo:table-column background-color="yellow"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="yellow"/>
<fo:table-column column-width="3cm" background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
@@ -159,10 +159,10 @@
The next table specifies neither width nor inline-progression-dimension.
</fo:block>
<!-- table start -->
- <fo:table table-layout="fixed" border-collapse="separate">
- <fo:table-column background-color="yellow"/>
+ <fo:table table-layout="fixed" width="100%" border-collapse="separate">
+ <fo:table-column column-width="proportional-column-width(1)" background-color="yellow"/>
<fo:table-column column-width="3cm" background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
@@ -178,11 +178,11 @@
specifies a column width of 5cm on the middle column only.
</fo:block>
<!-- table start -->
- <fo:table table-layout="fixed" border-collapse="separate"
+ <fo:table table-layout="fixed" width="100%" border-collapse="separate"
inline-progression-dimension.minimum="10cm">
- <fo:table-column background-color="yellow"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="yellow"/>
<fo:table-column column-width="5cm" background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
@@ -194,17 +194,17 @@
</fo:table>
<fo:block space-before="12pt" space-after="6pt">
- The next table specifies inline-progression-dimension.minimum="10cm",
- inline-progression-dimension.maximum="17cm and
+ The next table specifies inline-progression-dimension.minimum=&quot;10cm&quot;,
+ inline-progression-dimension.maximum=&quot;17cm and
specifies a column width of 5cm on the middle column only.
</fo:block>
<!-- table start -->
- <fo:table table-layout="fixed" border-collapse="separate"
+ <fo:table table-layout="fixed" width="100%" border-collapse="separate"
inline-progression-dimension.minimum="10cm"
inline-progression-dimension.maximum="17cm">
- <fo:table-column background-color="yellow"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="yellow"/>
<fo:table-column column-width="5cm" background-color="blue"/>
- <fo:table-column background-color="green"/>
+ <fo:table-column column-width="proportional-column-width(1)" background-color="green"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell display-align="before"><fo:block>Some text to make this cell
diff --git a/examples/fo/build.xml b/examples/fo/build.xml
index 2c7c18259..de83b945c 100644
--- a/examples/fo/build.xml
+++ b/examples/fo/build.xml
@@ -127,6 +127,7 @@
</target>
<!-- =================================================================== -->
<!-- Compares new test pdf files to reference pdf files -->
+ <!-- N.B. All comparisons fail due to differences in /CreationDate -->
<!-- =================================================================== -->
<target name="comparePDF" depends="newPDF">
<compare referenceDirectory="${referenceDir}" testDirectory="${testDir}" filenames="normal.pdf,table.pdf,list.pdf,link.pdf,border.pdf,images.pdf,extensive.pdf,readme.pdf,fonts.pdf,bordershorthand.pdf,character.pdf,corresprop.pdf,hyphen.pdf,inhprop.pdf,instream.pdf,leader.pdf,newlinktest.pdf,normalex.pdf,pdfoutline.pdf,simple.pdf,textdeko.pdf,tableunits.pdf"/>
@@ -144,6 +145,7 @@
<!-- =================================================================== -->
<!-- Starts the test -->
+ <!-- N.B. All tests fail due to differences in /CreationDate -->
<!-- =================================================================== -->
<target name="runtest" depends="comparePDF">
<echo message="Running Fop tests"/>
@@ -154,6 +156,9 @@
<target name="clean" depends="init">
<delete dir="${testDir}"/>
</target>
+ <target name="cleantest" depends="init">
+ <delete dir="${referenceDir}"/>
+ </target>
</project>
<!-- End of file -->
diff --git a/examples/fo/svg/embedding.fo b/examples/fo/svg/embedding.fo
index dbcac747b..a4af1675e 100644
--- a/examples/fo/svg/embedding.fo
+++ b/examples/fo/svg/embedding.fo
@@ -794,7 +794,7 @@ XML Syntax
<fo:block>
Here we have some examples of how the XML can be specified in the fo document.
<fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="350pt"/>
<fo:table-column column-width="150pt"/>
<fo:table-body>
@@ -932,7 +932,7 @@ Sizing
The size of the instream-foreign-object is obtained in a number of ways.
<fo:block>
- <fo:table xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:table xmlns:svg="http://www.w3.org/2000/svg" table-layout="fixed" width="100%">
<fo:table-column column-width="350pt"/>
<fo:table-column column-width="150pt"/>
<fo:table-body>
diff --git a/examples/fo/tables/background.fo b/examples/fo/tables/background.fo
index fe2cf128d..e516348da 100644
--- a/examples/fo/tables/background.fo
+++ b/examples/fo/tables/background.fo
@@ -30,7 +30,7 @@
Table 1: cell background
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -72,7 +72,7 @@
Table 1: row background
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -152,7 +152,7 @@
Table 1: column background
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm" background-color="green"/>
<fo:table-column column-width="3cm" background-color="red"/>
<fo:table-column column-width="3cm" background-color="blue"/>
@@ -219,7 +219,7 @@
Table 1: column backgrounds over page
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm" background-color="green"/>
<fo:table-column column-width="3cm" background-color="red"/>
<fo:table-column column-width="3cm" background-color="blue"/>
@@ -286,7 +286,7 @@
Table 1: body background
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -323,7 +323,7 @@
</fo:table-body>
</fo:table>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -360,7 +360,7 @@
</fo:table-body>
</fo:table>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -397,7 +397,7 @@
</fo:table-body>
</fo:table>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -438,7 +438,7 @@
Table 1: table background
</fo:block>
- <fo:table background-color="green">
+ <fo:table background-color="green" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -475,7 +475,7 @@
</fo:table-body>
</fo:table>
- <fo:table background-color="red">
+ <fo:table background-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -516,7 +516,7 @@
Table 1: combinations
</fo:block>
- <fo:table background-color="green">
+ <fo:table background-color="green" table-layout="fixed" width="100%">
<fo:table-column column-width="2.5cm"/>
<fo:table-column column-width="2.5cm" background-color="green"/>
<fo:table-column column-width="2.5cm" background-color="red"/>
diff --git a/examples/fo/tables/borders.fo b/examples/fo/tables/borders.fo
index a38a6b148..f6704ef61 100644
--- a/examples/fo/tables/borders.fo
+++ b/examples/fo/tables/borders.fo
@@ -30,7 +30,7 @@
Table 1: cell borders
</fo:block>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -186,7 +186,7 @@
Table 2: row borders
</fo:block>
- <fo:table border-collapse="collapse">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -310,7 +310,7 @@
Table 3: column borders
</fo:block>
- <fo:table border-collapse="collapse">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm" border-left-color="green" border-left-width="0.5pt" border-left-style="solid"/>
<fo:table-column column-width="3cm" border-top-color="red" border-top-width="0.5pt" border-top-style="solid"/>
<fo:table-column column-width="3cm" border-right-color="blue" border-right-width="0.5pt" border-right-style="solid"/>
@@ -377,7 +377,7 @@
Table 4: column borders over page
</fo:block>
- <fo:table border-collapse="collapse">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm" border-left-color="green" border-left-width="0.5pt" border-left-style="solid"/>
<fo:table-column column-width="3cm" border-top-color="red" border-top-width="0.5pt" border-top-style="solid"/>
<fo:table-column column-width="3cm" border-right-color="blue" border-right-width="0.5pt" border-right-style="solid"/>
@@ -444,7 +444,7 @@
Table 5: body borders
</fo:block>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -480,7 +480,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -516,7 +516,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -552,7 +552,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -588,7 +588,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-collapse="separate">
+ <fo:table border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -628,8 +628,7 @@
Table 6: table borders
</fo:block>
- <fo:table border-left-color="green" border-left-width="0.5pt" border-left-style="solid"
- border-collapse="separate">
+ <fo:table border-left-color="green" border-left-width="0.5pt" border-left-style="solid" border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -665,7 +664,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-top-color="red" border-top-width="0.5pt" border-top-style="solid" border-collapse="separate">
+ <fo:table border-top-color="red" border-top-width="0.5pt" border-top-style="solid" border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -701,7 +700,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-right-color="blue" border-right-width="0.5pt" border-right-style="solid" border-collapse="separate">
+ <fo:table border-right-color="blue" border-right-width="0.5pt" border-right-style="solid" border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -737,7 +736,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-bottom-color="yellow" border-bottom-width="0.5pt" border-bottom-style="solid" border-collapse="separate">
+ <fo:table border-bottom-color="yellow" border-bottom-width="0.5pt" border-bottom-style="solid" border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -773,7 +772,7 @@
</fo:table-body>
</fo:table>
- <fo:table border-color="orange" border-width="0.5pt" border-style="solid" border-collapse="separate">
+ <fo:table border-color="orange" border-width="0.5pt" border-style="solid" border-collapse="separate" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -813,7 +812,7 @@
Table 7: combinations
</fo:block>
- <fo:table border-left-color="green" border-left-width="0.5pt" border-left-style="solid" border-collapse="collapse">
+ <fo:table border-left-color="green" border-left-width="0.5pt" border-left-style="solid" border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="2.5cm"/>
<fo:table-column column-width="2.5cm" border-left-color="green" border-left-width="0.5pt" border-left-style="solid"/>
<fo:table-column column-width="2.5cm" border-top-color="red" border-top-width="0.5pt" border-top-style="solid"/>
@@ -1025,7 +1024,7 @@
implementation status.
</fo:block>
- <fo:table border-collapse="collapse" table-layout="fixed">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm" border-color="blue" border-width="0.5pt" border-style="solid"/>
<fo:table-column column-width="3cm" border-color="blue" border-width="0.5pt" border-style="solid"/>
<fo:table-column column-width="3cm" border-color="blue" border-width="0.5pt" border-style="solid"/>
@@ -1090,7 +1089,7 @@
fo:table-cell level.
</fo:block>
- <fo:table border-collapse="collapse" table-layout="fixed">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -1159,7 +1158,7 @@
Check the FOP compliance page for current implementation status.
</fo:block>
- <fo:table border-collapse="collapse" table-layout="fixed"
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%"
border-style="solid" border-width="5pt" border-color="yellow">
<fo:table-column column-width="3cm"
border-style="solid" border-width="3pt" border-color="black"/>
@@ -1264,7 +1263,7 @@
the border properties differ only on color.
</fo:block>
- <fo:table border-collapse="collapse" table-layout="fixed">
+ <fo:table border-collapse="collapse" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"
border-style="solid" border-width="3pt" border-color="black"/>
diff --git a/examples/fo/tables/break.fo b/examples/fo/tables/break.fo
index 81325c4ed..91559699d 100644
--- a/examples/fo/tables/break.fo
+++ b/examples/fo/tables/break.fo
@@ -34,7 +34,7 @@
Table 1: basic break after with next
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -81,7 +81,7 @@
Table 2: basic break before with next
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -128,7 +128,7 @@
Table 3: basic break before a keep with next
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -175,7 +175,7 @@
Table 4: basic break after a keep with previous
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -222,7 +222,7 @@
Table 5: basic break after a keep with previous
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
diff --git a/examples/fo/tables/headfoot.fo b/examples/fo/tables/headfoot.fo
index fd0a14590..4401a2c77 100644
--- a/examples/fo/tables/headfoot.fo
+++ b/examples/fo/tables/headfoot.fo
@@ -30,7 +30,7 @@
Table 1: with header
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -311,7 +311,7 @@
Table 2: with footer
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -592,7 +592,7 @@
Table 3: with header and footer and keeps
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -888,7 +888,7 @@
Table 4: cells spanning columns
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -940,7 +940,7 @@
Table 5: cells spanning rows
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="48pt"/>
<fo:table-column column-width="48pt"/>
<fo:table-column column-width="48pt"/>
@@ -1054,7 +1054,7 @@
Table 6: table with header and multiple body's
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -1242,7 +1242,7 @@
Table 6: table with footer and multiple body's
</fo:block>
- <fo:table>
+ <fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
diff --git a/examples/fo/tables/keep.fo b/examples/fo/tables/keep.fo
index b369d7162..929ee760d 100644
--- a/examples/fo/tables/keep.fo
+++ b/examples/fo/tables/keep.fo
@@ -34,7 +34,7 @@
Table 1: basic keep with next
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -81,7 +81,7 @@
Table 1: basic keep with previous
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -128,7 +128,7 @@
Table 1: basic keep with next and keep with previous
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -192,7 +192,7 @@
Table 1: basic multiple keep with next after normal row
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -324,7 +324,7 @@
Table 1: basic multiple keep (next and previous) after normal row
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="6cm"/>
@@ -456,7 +456,7 @@
Table 1: basic multiple keep with next after normal row with normal row in middle
</fo:block>
- <fo:table border-width="0.5pt" border-color="red">
+ <fo:table border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="6cm"/>
diff --git a/examples/fo/tables/omit.fo b/examples/fo/tables/omit.fo
index 042f557ed..875afe77e 100644
--- a/examples/fo/tables/omit.fo
+++ b/examples/fo/tables/omit.fo
@@ -30,7 +30,7 @@
Table 1: with header
</fo:block>
- <fo:table table-omit-header-at-break="true">
+ <fo:table table-omit-header-at-break="true" table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -311,7 +311,7 @@
Table 2: with footer
</fo:block>
- <fo:table table-omit-footer-at-break="true">
+ <fo:table table-omit-footer-at-break="true" table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -592,7 +592,7 @@
Table 3: with header and footer and keeps
</fo:block>
- <fo:table table-omit-header-at-break="true" table-omit-footer-at-break="true">
+ <fo:table table-omit-header-at-break="true" table-omit-footer-at-break="true" table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -888,7 +888,7 @@
Table 6: table with multiple body's
</fo:block>
- <fo:table table-omit-header-at-break="true">
+ <fo:table table-omit-header-at-break="true" table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
@@ -1076,7 +1076,7 @@
Table 6: table with multiple body's
</fo:block>
- <fo:table table-omit-footer-at-break="true">
+ <fo:table table-omit-footer-at-break="true" table-layout="fixed" width="100%">
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
<fo:table-column column-width="2cm"/>
diff --git a/examples/fo/tables/space.fo b/examples/fo/tables/space.fo
index c0562d8f9..e409720bb 100644
--- a/examples/fo/tables/space.fo
+++ b/examples/fo/tables/space.fo
@@ -30,7 +30,7 @@
Table 1: spaces around cells
</fo:block>
- <fo:table border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -109,7 +109,7 @@
Table 2: spaces around rows
</fo:block>
- <fo:table border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -190,7 +190,7 @@
Table 3: spaces around body
</fo:block>
- <fo:table border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -281,7 +281,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table space-before.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table space-before.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -309,7 +309,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table padding-left="5pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table padding-left="5pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -337,7 +337,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table padding-right="5pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table padding-right="5pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -365,7 +365,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table space-after.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table space-after.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -397,7 +397,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table space-after.optimum="20pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table space-after.optimum="20pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
@@ -462,7 +462,7 @@
</fo:block>
<fo:block border-style="solid" border-width="0.5pt">
- <fo:table space-after.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red">
+ <fo:table space-after.optimum="5pt" border-style="solid" border-width="0.5pt" border-color="red" table-layout="fixed" width="100%">
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
<fo:table-column column-width="3cm"/>
diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml
index 46879d1f6..a764eac41 100644
--- a/findbugs-exclude.xml
+++ b/findbugs-exclude.xml
@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<FindBugsFilter>
<Match>
+ <Class name="org.apache.fop.fonts.truetype.TTFFile$1"/>
+ <Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
+ </Match>
+ <Match>
+ <Class name="org.apache.fop.fonts.truetype.FontFileReader"/>
+ <Method name="getAllBytes"/>
+ <Bug pattern="EI_EXPOSE_REP"/>
+ </Match>
+ <Match>
<Class name="org.apache.fop.fo.properties.FontFamilyProperty"/>
<Bug pattern="EQ_DOESNT_OVERRIDE_EQUALS"/>
</Match>
@@ -950,11 +959,6 @@
<Bug pattern="RV_EXCEPTION_NOT_THROWN"/>
</Match>
<Match>
- <Class name="org.apache.fop.hyphenation.HyphenationTreeCache"/>
- <Method name="constructUserKey"/>
- <Bug pattern="RV_RETURN_VALUE_IGNORED"/>
- </Match>
- <Match>
<Class name="org.apache.fop.afp.AFPResourceLevel"/>
<Method name="equals"/>
<Bug pattern="SA_FIELD_SELF_COMPARISON"/>
@@ -5162,4 +5166,41 @@
<Method name="getNonEmptyLevels"/>
<Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
</Match>
+ <Match>
+ <Class name="org.apache.fop.render.pdf.AbstractImageAdapter"/>
+ <Method name="populateXObjectDictionaryForIndexColorModel"/>
+ <Bug pattern="OS_OPEN_STREAM"/>
+ </Match>
+ <Match>
+ <Class name="org.apache.fop.render.pdf.ImageRawPNGAdapter"/>
+ <Or>
+ <Method name="outputContents"/>
+ <Method name="setup"/>
+ </Or>
+ <Or>
+ <Bug pattern="OS_OPEN_STREAM"/>
+ <Bug pattern="OS_OPEN_STREAM_EXCEPTION_PATH"/>
+ </Or>
+ </Match>
+ <Match>
+ <Class name="org.apache.fop.render.ps.ImageEncoderPNG"/>
+ <Method name="writeTo"/>
+ <Bug pattern="OS_OPEN_STREAM"/>
+ </Match>
+ <Match>
+ <Or>
+ <Class name="org.apache.fop.render.pdf.PDFImageHandlerRawPNG"/>
+ <Class name="org.apache.fop.render.ps.PSImageHandlerRawPNG"/>
+ </Or>
+ <Method name="getSupportedImageFlavors"/>
+ <Bug pattern="EI_EXPOSE_REP"/>
+ </Match>
+ <Match>
+ <Class name="org.apache.fop.render.ps.PSImageHandlerRawPNG"/>
+ <Or>
+ <Method name="handleImage"/>
+ <Method name="generateForm"/>
+ </Or>
+ <Bug pattern="BC_UNCONFIRMED_CAST"/>
+ </Match>
</FindBugsFilter>
diff --git a/lib/xmlgraphics-commons-1.5rc1.jar b/lib/xmlgraphics-commons-1.5rc1.jar
new file mode 100644
index 000000000..03cf5b3d6
--- /dev/null
+++ b/lib/xmlgraphics-commons-1.5rc1.jar
Binary files differ
diff --git a/lib/xmlgraphics-commons-1.5svn.jar b/lib/xmlgraphics-commons-1.5svn.jar
deleted file mode 100644
index d8c5e0989..000000000
--- a/lib/xmlgraphics-commons-1.5svn.jar
+++ /dev/null
Binary files differ
diff --git a/src/documentation/content/.htaccess b/src/documentation/content/.htaccess
index 062708b4a..0edc84f75 100644
--- a/src/documentation/content/.htaccess
+++ b/src/documentation/content/.htaccess
@@ -1,34 +1,34 @@
# redirect moved files
-RedirectMatch Permanent ^/fop/anttask(.*) http://xmlgraphics.apache.org/fop/1.1/anttask$1
-RedirectMatch Permanent ^/fop/compiling(.*) http://xmlgraphics.apache.org/fop/1.1/compiling$1
-RedirectMatch Permanent ^/fop/configuration(.*) http://xmlgraphics.apache.org/fop/1.1/configuration$1
-RedirectMatch Permanent ^/fop/embedding(.*) http://xmlgraphics.apache.org/fop/1.1/embedding$1
-RedirectMatch Permanent ^/fop/extensions(.*) http://xmlgraphics.apache.org/fop/1.1/extensions$1
-RedirectMatch Permanent ^/fop/fonts(.*) http://xmlgraphics.apache.org/fop/1.1/fonts$1
-RedirectMatch Permanent ^/fop/graphics(.*) http://xmlgraphics.apache.org/fop/1.1/graphics$1
-RedirectMatch Permanent ^/fop/hyphenation(.*) http://xmlgraphics.apache.org/fop/1.1/hyphenation$1
-RedirectMatch Permanent ^/fop/intermediate(.*) http://xmlgraphics.apache.org/fop/1.1/intermediate$1
-RedirectMatch Permanent ^/fop/output(.*) http://xmlgraphics.apache.org/fop/1.1/output$1
-RedirectMatch Permanent ^/fop/pdfa(.*) http://xmlgraphics.apache.org/fop/1.1/pdfa$1
-RedirectMatch Permanent ^/fop/pdfencryption(.*) http://xmlgraphics.apache.org/fop/1.1/pdfencryption$1
-RedirectMatch Permanent ^/fop/pdfx(.*) http://xmlgraphics.apache.org/fop/1.1/pdfx$1
-RedirectMatch Permanent ^/fop/running(.*) http://xmlgraphics.apache.org/fop/1.1/running$1
-RedirectMatch Permanent ^/fop/servlets(.*) http://xmlgraphics.apache.org/fop/1.1/servlets$1
-RedirectMatch Permanent ^/fop/upgrading(.*) http://xmlgraphics.apache.org/fop/1.1/upgrading$1
+RedirectMatch Permanent ^/fop/anttask(.*) http://xmlgraphics.apache.org/fop/1.1rc1/anttask$1
+RedirectMatch Permanent ^/fop/compiling(.*) http://xmlgraphics.apache.org/fop/1.1rc1/compiling$1
+RedirectMatch Permanent ^/fop/configuration(.*) http://xmlgraphics.apache.org/fop/1.1rc1/configuration$1
+RedirectMatch Permanent ^/fop/embedding(.*) http://xmlgraphics.apache.org/fop/1.1rc1/embedding$1
+RedirectMatch Permanent ^/fop/extensions(.*) http://xmlgraphics.apache.org/fop/1.1rc1/extensions$1
+RedirectMatch Permanent ^/fop/fonts(.*) http://xmlgraphics.apache.org/fop/1.1rc1/fonts$1
+RedirectMatch Permanent ^/fop/graphics(.*) http://xmlgraphics.apache.org/fop/1.1rc1/graphics$1
+RedirectMatch Permanent ^/fop/hyphenation(.*) http://xmlgraphics.apache.org/fop/1.1rc1/hyphenation$1
+RedirectMatch Permanent ^/fop/intermediate(.*) http://xmlgraphics.apache.org/fop/1.1rc1/intermediate$1
+RedirectMatch Permanent ^/fop/output(.*) http://xmlgraphics.apache.org/fop/1.1rc1/output$1
+RedirectMatch Permanent ^/fop/pdfa(.*) http://xmlgraphics.apache.org/fop/1.1rc1/pdfa$1
+RedirectMatch Permanent ^/fop/pdfencryption(.*) http://xmlgraphics.apache.org/fop/1.1rc1/pdfencryption$1
+RedirectMatch Permanent ^/fop/pdfx(.*) http://xmlgraphics.apache.org/fop/1.1rc1/pdfx$1
+RedirectMatch Permanent ^/fop/running(.*) http://xmlgraphics.apache.org/fop/1.1rc1/running$1
+RedirectMatch Permanent ^/fop/servlets(.*) http://xmlgraphics.apache.org/fop/1.1rc1/servlets$1
+RedirectMatch Permanent ^/fop/upgrading(.*) http://xmlgraphics.apache.org/fop/1.1rc1/upgrading$1
# redirect to versioned documentation
# Current stable release
-Redirect Temp /fop/stable http://xmlgraphics.apache.org/fop/1.1
+Redirect Temp /fop/stable http://xmlgraphics.apache.org/fop/1.0
# Current unstable release (or trunk if no beta is the latest release)
-Redirect Temp /fop/unstable http://xmlgraphics.apache.org/fop/trunk
+Redirect Temp /fop/unstable http://xmlgraphics.apache.org/fop/1.1rc1
# Latest release
-Redirect Temp /fop/current http://xmlgraphics.apache.org/fop/1.1
-Redirect Temp /fop/latest http://xmlgraphics.apache.org/fop/1.1
+Redirect Temp /fop/current http://xmlgraphics.apache.org/fop/1.0
+Redirect Temp /fop/latest http://xmlgraphics.apache.org/fop/1.0
# Previous stable release
-Redirect Temp /fop/previous http://xmlgraphics.apache.org/fop/1.0
+Redirect Temp /fop/previous http://xmlgraphics.apache.org/fop/0.95
# Old releases
Redirect Temp /fop/maintenance http://xmlgraphics.apache.org/fop/0.95
diff --git a/src/documentation/content/doap.rdf b/src/documentation/content/doap.rdf
index 327d8dec8..98c505747 100644
--- a/src/documentation/content/doap.rdf
+++ b/src/documentation/content/doap.rdf
@@ -76,16 +76,23 @@
</asfext:implements>
<release>
<Version>
- <name>Previous stable release</name>
+ <name>Upcoming release (candidate)</name>
+ <created>2012-07-02</created>
+ <revision>1.1rc1</revision>
+ </Version>
+ </release
+ <release>
+ <Version>
+ <name>Current release (stable)</name>
<created>2010-07-21</created>
<revision>1.0</revision>
</Version>
- </release>
+ </release
<release>
<Version>
- <name>Latest stable release</name>
- <created>2012-MM-DD</created>
- <revision>1.1</revision>
+ <name>Previous release (stable)</name>
+ <created>2008-08-05</created>
+ <revision>0.95</revision>
</Version>
</release>
<repository>
diff --git a/src/documentation/content/xdocs/1.1/known-issues.xml b/src/documentation/content/xdocs/1.1/known-issues.xml
deleted file mode 100644
index 622e6a79a..000000000
--- a/src/documentation/content/xdocs/1.1/known-issues.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- 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$ -->
-<known-issues>
- <!-- NEED TO REVIEW ALL OF THE FOLLOWING
- <known-issue>
- MIF and SVG output support have not been restored, yet.
- </known-issue>
- <known-issue>
- RTF output is inferior to other output formats supported by FOP.
- For details, please see the "Output Targets" page of the release
- you're using.
- </known-issue>
- <known-issue>
- Auto table layout is not implemented, yet.
- </known-issue>
- <known-issue>
- Footnotes may overlap with text of the region-body in multi-column
- documents.
- </known-issue>
- <known-issue>
- Space resolution does not work between footnote regions.
- </known-issue>
- <known-issue>
- Block containers with no height currently don't create a fence for
- spaces as they should (they behave like a normal block).
- </known-issue>
- <known-issue>
- Preserved linefeeds in fo:character are not handled correctly.
- </known-issue>
- <known-issue>
- An empty block currently produces a fence for stacking constraints
- which it shouldn't.
- </known-issue>
- <known-issue>
- There are several small problems around white space handling.
- </known-issue>
- <known-issue>
- Images currently don't shrink so they fit on a page when they are
- too big and shrinking is allowed to happen.
- </known-issue>
- <known-issue>
- Inline container may not work as expected.
- </known-issue>
- <known-issue>
- The letter-spacing and word-spacing properties may not work as expected.
- </known-issue>
- <known-issue>
- Leaders with leader-pattern="use-content" may not work as expected.
- </known-issue>
- <known-issue>
- The keep-with-previous property doesn't work inside tables and lists, yet.
- </known-issue>
- <known-issue>
- If two consecutive pages don't have the same available width, the
- content currently isn't properly fit into the available space on
- the new page.
- </known-issue>
- <known-issue>
- Background images on page number citations are not placed correctly.
- </known-issue>
- <known-issue>
- Not all FO elements can be referenced by their "id", most notably:
- table-body, table-header, table-footer and table-row.
- </known-issue>
- <known-issue>
- Border and padding conditionality are not supported on table-cells, yet.
- </known-issue>
- -->
-</known-issues>
diff --git a/src/documentation/content/xdocs/1.1/accessibility.xml b/src/documentation/content/xdocs/1.1rc1/accessibility.xml
index 412519d8b..412519d8b 100644
--- a/src/documentation/content/xdocs/1.1/accessibility.xml
+++ b/src/documentation/content/xdocs/1.1rc1/accessibility.xml
diff --git a/src/documentation/content/xdocs/1.1/anttask.xml b/src/documentation/content/xdocs/1.1rc1/anttask.xml
index ba53fe7d1..ba53fe7d1 100644
--- a/src/documentation/content/xdocs/1.1/anttask.xml
+++ b/src/documentation/content/xdocs/1.1rc1/anttask.xml
diff --git a/src/documentation/content/xdocs/1.1/compiling.xml b/src/documentation/content/xdocs/1.1rc1/compiling.xml
index 7bfa165b5..7bfa165b5 100644
--- a/src/documentation/content/xdocs/1.1/compiling.xml
+++ b/src/documentation/content/xdocs/1.1rc1/compiling.xml
diff --git a/src/documentation/content/xdocs/1.1/complexscripts.xml b/src/documentation/content/xdocs/1.1rc1/complexscripts.xml
index c622fe192..697205531 100644
--- a/src/documentation/content/xdocs/1.1/complexscripts.xml
+++ b/src/documentation/content/xdocs/1.1rc1/complexscripts.xml
@@ -26,7 +26,7 @@
<title>Overview</title>
<p>
This page describes the
- <a href="http://en.wikipedia.org/wiki/Complex_scripts">complex scripts</a>
+ <link href="http://en.wikipedia.org/wiki/Complex_scripts">complex scripts</link>
features of Apacheâ„¢ FOP, which include:
</p>
<ul>
@@ -80,16 +80,16 @@
sufficient. In these cases, an author may make use of the following XSL-FO constructs:
</p>
<ul>
- <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></a> property.</li>
- <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></a> property.</li>
- <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#writing-mode"><code>writing-mode</code></a> property.</li>
+ <li>The <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></link> property.</li>
+ <li>The <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></link> property.</li>
+ <li>The <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#writing-mode"><code>writing-mode</code></link> property.</li>
<li>The number to string conversion properties:
- <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#format"><code>format</code></a>,
- <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-separator"><code>grouping-separator</code></a>,
- <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-size"><code>grouping-size</code></a>,
- <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#letter-value"><code>letter-value</code></a>,
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#format"><code>format</code></link>,
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-separator"><code>grouping-separator</code></link>,
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#grouping-size"><code>grouping-size</code></link>,
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#letter-value"><code>letter-value</code></link>,
and <code>fox:number-conversion-features</code>.</li>
- <li>The <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override"><code>fo:bidi-override</code></a> element.</li>
+ <li>The <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override"><code>fo:bidi-override</code></link> element.</li>
<li>Explicit bidirectional control characters: U+200E LRM, U+200F RLM, U+202A LRE,
U+202B RLE, U+202C PDF, U+202D LRO, U+202E RLO.</li>
<li>Explicit join control characters: U+200C ZWNJ and U+200D ZWJ.</li>
@@ -107,7 +107,7 @@
</p>
<ol>
<li>If the FO element that governs the text specifies a
- <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></a>
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#script"><code>script</code></link>
property and its value is not the empty string or <code>"auto"</code>, then that script is used.</li>
<li>Otherwise, the dominant script of the text is determined automatically by finding the
script whose constituent characters appear most frequently in the text.</li>
@@ -115,8 +115,8 @@
<p>In case the automatic algorithm does not produce the desired results, an author may
explicitly specify a <code>script</code> property with the desired script. If specified,
it must be one of the four-letter script code specified in
- <a href="http://unicode.org/iso15924/iso15924-codes.html">ISO 15924 Code List</a> or
- in the <a href="#extended_script_codes">Extended Script Codes</a> table. Comparison
+ <link href="http://unicode.org/iso15924/iso15924-codes.html">ISO 15924 Code List</link> or
+ in the <link href="#extended_script_codes">Extended Script Codes</link> table. Comparison
of script codes is performed in a case-insensitive manner, so it does not matter what case
is used when specifying these codes in an XSL-FO document.</p>
<section id="standard_script_codes">
@@ -335,28 +335,94 @@
language specific processing rules to be applied. For example, a font designed for the Arabic script may support
typographic variations according to whether the written language is Arabic, Farsi (Persian), Sindhi, Urdu, or
another language written with the Arabic script. In order to apply these language specific features, the author
- may explicitly mark the text with a <a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></a>
+ may explicitly mark the text with a <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#language"><code>language</code></link>
property.</p>
<p>When specifying the <code>language</code> property, the value of the property must be either an
- <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes">ISO639-2 3-letter code</a> or an
- <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO639-1 2-letter code</a>. Comparison of language
+ <link href="http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes">ISO639-2 3-letter code</link> or an
+ <link href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">ISO639-1 2-letter code</link>. Comparison of language
codes is performed in a case-insensitive manner, so it does not matter what case is used when specifying these
codes in an XSL-FO document.</p>
</section>
<section id="writing_mode_property">
<title>Writing Mode Property</title>
+ <p>The <code>writing-mode</code> property is used to determine the axes and direction of the inline
+ progression direction, the block progression direction, the column progression direction (in tables
+ and flows), the shift direction, region placement, the resolution of writing-mode relative property
+ values (such as start, end, before, after), and the default block (paragraph) bidirectionality
+ level.
+ </p>
+ <p>The <code>writing-mode</code> property is inherited, so it can appear on any XSL-FO element type; however,
+ it applies (semantically) only to the following element types:
+ </p>
+ <ul>
+ <li><code>fo:page-sequence</code></li>
+ <li><code>fo:simple-page-master</code></li>
+ <li><code>fo:region-*</code></li>
+ <li><code>fo:block-container</code></li>
+ <li><code>fo:inline-container</code></li>
+ <li><code>fo:table</code></li>
+ </ul>
+ <p>If it is not specified on one of these element types, but is specified on an ancestor element, then the value specified on that
+ ancestor element (the inherited value) is used; otherwise, the initial value <code>lr-tb</code> is used.</p>
+ <p>At present, only the following values of the <code>writing-mode</code> property are supported:</p>
+ <ul>
+ <li><code>lr-tb</code></li>
+ <li><code>rl-tb</code></li>
+ <li><code>lr</code></li>
+ <li><code>rl</code></li>
+ </ul>
+ <p>Writing modes that employ a vertical inline progression direction are not yet supported.</p>
</section>
+ <!-- [TBD] - NEED TO DOCUMENT
<section id="number_conversion_properties">
<title>Number Conversion Properties</title>
</section>
+ -->
<section id="bidi_override_element">
<title>Bidi Override Element</title>
+ <p>The <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override"><code>fo:bidi-override</code></link>
+ element may be used to override default bidirectional processing behavior,
+ including default embedding levels and default character directionality. In the absence of either this element
+ or use of explicit <link href="#bidi_controls">Bidi Control Characters</link>, the default behavior prescribed
+ by the <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override">Unicode Bidirectional Algorithm</link>
+ applies.
+ </p>
</section>
<section id="bidi_controls">
<title>Bidi Control Characters</title>
+ <p>In addition to the use of the <link href="#bidi_override_element">Bidi Override Element</link>, an author
+ may make use of the following explicit Unicode Bidi Control Characters:</p>
+ <ul>
+ <li>U+200E - LEFT-TO-RIGHT MARK (LRM)</li>
+ <li>U+200F - RIGHT-TO-LEFT MARK (RLM)</li>
+ <li>U+202A - LEFT-TO-RIGHT EMBEDDING (LRE)</li>
+ <li>U+202B - RIGHT-TO-LEFT EMBEDDING (RLE)</li>
+ <li>U+202C - POP DIRECTIONAL FORMATTING (PDF)</li>
+ <li>U+202D - LEFT-TO-RIGHT OVERRIDE (LRO)</li>
+ <li>U+202E - RIGHT-TO-LEFT OVERRIDE (RLO)</li>
+ </ul>
+ <p>If an embedding or override is not terminated (using U+202C PDF) prior to the end of a
+ <link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#d0e4879">delimited text range</link>,
+ then it is automatically terminated by FOP.
+ </p>
</section>
<section id="join_controls">
<title>Join Control Characters</title>
+ <p>In order to prevent joining behavior in contexts where joining occurs by default,
+ for example, between U+0628 ARABIC LETTER BEH and U+0646 ARABIC LETTER NOON,
+ an author may used a U+200C ZERO WIDTH NON-JOINER (ZWNJ).
+ </p>
+ <p>Conversely, in order to force joining behavior in contexts where joining does not occur by default,
+ for example, between U+0628 ARABIC LETTER BEH and U+0020 SPACE, an author may used a U+200D ZERO WIDTH JOINER (ZWJ).
+ </p>
+ <p>The behavior of ZWNJ and ZWJ is script specific. See
+ <link href="http://www.unicode.org/versions/Unicode6.1.0/ch08.pdf">The Unicode Standard, Chapter 8,
+ Middle Eastern Scripts</link> for information on the use of these control characters with the Arabic
+ script. See
+ <link href="http://www.unicode.org/versions/Unicode6.1.0/ch09.pdf">The Unicode Standard, Chapter 9,
+ South Asian Scripts - I</link> for information on the use of these control characters with common
+ Indic scripts.
+ </p>
</section>
</section>
<section id="supported_scripts">
@@ -377,103 +443,103 @@
<th style="text-align:left">Comments</th>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Arabic_alphabet">Arabic</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Arabic_alphabet">Arabic</link></td>
<td class="yes">full</td>
<td class="yes">full</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Bengali_alphabet">Bengali</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Bengali_alphabet">Bengali</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Burmese_alphabet">Burmese</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Burmese_alphabet">Burmese</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Devanagari_alphabet">Devanagari</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Devanagari_alphabet">Devanagari</link></td>
<td class="partial">partial</td>
<td class="partial">partial</td>
<td style="text-align:left">join controls (ZWJ, ZWNJ) not yet supported</td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Khmer_alphabet">Khmer</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Khmer_alphabet">Khmer</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Gujarati_alphabet">Gujarati</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Gujarati_alphabet">Gujarati</link></td>
<td class="partial">partial</td>
<td class="no">none</td>
<td style="text-align:left">pre-alpha</td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Gurmukhī_alphabet">Gurmukhi</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Gurmukhī_alphabet">Gurmukhi</link></td>
<td class="partial">partial</td>
<td class="no">none</td>
<td style="text-align:left">pre-alpha</td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Hebrew_alphabet">Hebrew</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Hebrew_alphabet">Hebrew</link></td>
<td class="yes">full</td>
<td class="partial">partial</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Kannada_alphabet">Kannada</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Kannada_alphabet">Kannada</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Lao_alphabet">Lao</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Lao_alphabet">Lao</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Malayalam_alphabet">Malayalam</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Malayalam_alphabet">Malayalam</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Mongolian_script">Mongolian</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Mongolian_script">Mongolian</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Oriya_script">Oriya</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Oriya_script">Oriya</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Tamil_alphabet">Tamil</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Tamil_alphabet">Tamil</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Telugu_alphabet">Telugu</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Telugu_alphabet">Telugu</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Tibetan_alphabet">Tibetan</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Tibetan_alphabet">Tibetan</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
</tr>
<tr>
- <td><a href="http://en.wikipedia.org/wiki/Thai_alphabet">Thai</a></td>
+ <td><link href="http://en.wikipedia.org/wiki/Thai_alphabet">Thai</link></td>
<td class="no">none</td>
<td class="no">none</td>
<td></td>
@@ -500,55 +566,55 @@
<th style="text-align:left">Comments</th>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=24">Arial Unicode MS</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1081">1.01</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=24">Arial Unicode MS</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1081">1.01</link></td>
<td style="text-align:center">50377</td>
<td>limited GPOS support</td>
</tr>
<tr>
- <td><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Lateef</a></td>
+ <td><link href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Lateef</link></td>
<td class="yes" style="text-align:left">1.0</td>
<td style="text-align:center">1147</td>
<td>language features for Kurdish (KUR), Sindhi (SND), Urdu (URD)</td>
</tr>
<tr>
- <td><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Scheherazade</a></td>
+ <td><link href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=ArabicFonts">Scheherazade</link></td>
<td class="yes" style="text-align:left">1.0</td>
<td style="text-align:center">1197</td>
<td>language features for Kurdish (KUR), Sindhi (SND), Urdu (URD)</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=261">Simplified Arabic</a></td>
- <td class="no" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=867">1.01</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=261">Simplified Arabic</link></td>
+ <td class="no" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=867">1.01</link></td>
<td/>
<td>contains invalid, out of order coverage table entries</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1645">5.00</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1645">5.00</link></td>
<td style="text-align:center">414</td>
<td>lacks GPOS support</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/font.aspx?FID=261">Simplified Arabic</link></td>
<td class="yes" style="text-align:left">5.92</td>
<td style="text-align:center">473</td>
<td>includes GPOS for advanced position adjustment</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=264">Traditional Arabic</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/family.aspx?FMID=877">1.01</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=264">Traditional Arabic</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/family.aspx?FMID=877">1.01</link></td>
<td style="text-align:center">530</td>
<td>lacks GPOS support</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1658">5.00</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1658">5.00</link></td>
<td style="text-align:center">530</td>
<td>lacks GPOS support</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/font.aspx?FID=264">Traditional Arabic</link></td>
<td class="yes" style="text-align:left">5.92</td>
<td style="text-align:center">589</td>
<td>includes GPOS for advanced position adjustment</td>
@@ -571,26 +637,26 @@
<th style="text-align:left">Comments</th>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=370">Aparajita</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1700">1.00</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=370">Aparajita</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1700">1.00</link></td>
<td style="text-align:center">706</td>
<td/>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=374">Kokila</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1749">1.00</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=374">Kokila</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1749">1.00</link></td>
<td style="text-align:center">706</td>
<td/>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=243">Mangal</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1759">5.01</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=243">Mangal</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1759">5.01</link></td>
<td style="text-align:center">885</td>
<td>designed for use in user interfaces</td>
</tr>
<tr>
- <td><a href="http://www.microsoft.com/typography/fonts/family.aspx?FID=384">Utsaah</a></td>
- <td class="yes" style="text-align:left"><a href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1811">1.00</a></td>
+ <td><link href="http://www.microsoft.com/typography/fonts/family.aspx?FID=384">Utsaah</link></td>
+ <td class="yes" style="text-align:left"><link href="http://www.microsoft.com/typography/fonts/font.aspx?FMID=1811">1.00</link></td>
<td style="text-align:center">706</td>
<td/>
</tr>
@@ -618,10 +684,10 @@
described above:
</p>
<ul>
- <li><a href="http://www.unicode.org/">The Unicode Standard</a></li>
- <li><a href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override">Unicode Bidirectional Algorithm</a></li>
- <li><a href="http://www.microsoft.com/typography/otspec/ttochap1.htm">OpenType Advanced Typographic Extensions</a></li>
- <li><a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=CmplxRndExamples">Examples of Complex Rendering</a></li>
+ <li><link href="http://www.unicode.org/">The Unicode Standard</link></li>
+ <li><link href="http://www.w3.org/TR/2006/REC-xsl11-20061205/#fo_bidi-override">Unicode Bidirectional Algorithm</link></li>
+ <li><link href="http://www.microsoft.com/typography/otspec/ttochap1.htm">OpenType Advanced Typographic Extensions</link></li>
+ <li><link href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=CmplxRndExamples">Examples of Complex Rendering</link></li>
</ul>
</section>
</body>
diff --git a/src/documentation/content/xdocs/1.1/configuration.xml b/src/documentation/content/xdocs/1.1rc1/configuration.xml
index b30a091a5..b30a091a5 100644
--- a/src/documentation/content/xdocs/1.1/configuration.xml
+++ b/src/documentation/content/xdocs/1.1rc1/configuration.xml
diff --git a/src/documentation/content/xdocs/1.1/embedding.xml b/src/documentation/content/xdocs/1.1rc1/embedding.xml
index 24c74f970..24c74f970 100644
--- a/src/documentation/content/xdocs/1.1/embedding.xml
+++ b/src/documentation/content/xdocs/1.1rc1/embedding.xml
diff --git a/src/documentation/content/xdocs/1.1/events.xml b/src/documentation/content/xdocs/1.1rc1/events.xml
index 27daad59b..27daad59b 100644
--- a/src/documentation/content/xdocs/1.1/events.xml
+++ b/src/documentation/content/xdocs/1.1rc1/events.xml
diff --git a/src/documentation/content/xdocs/1.1/extensions.xml b/src/documentation/content/xdocs/1.1rc1/extensions.xml
index 02d83db96..02d83db96 100644
--- a/src/documentation/content/xdocs/1.1/extensions.xml
+++ b/src/documentation/content/xdocs/1.1rc1/extensions.xml
diff --git a/src/documentation/content/xdocs/1.1/fonts.xml b/src/documentation/content/xdocs/1.1rc1/fonts.xml
index f3481607d..f3481607d 100644
--- a/src/documentation/content/xdocs/1.1/fonts.xml
+++ b/src/documentation/content/xdocs/1.1rc1/fonts.xml
diff --git a/src/documentation/content/xdocs/1.1/fotree/disabled-testcases.xml b/src/documentation/content/xdocs/1.1rc1/fotree/disabled-testcases.xml
index 196eafcc4..196eafcc4 100644
--- a/src/documentation/content/xdocs/1.1/fotree/disabled-testcases.xml
+++ b/src/documentation/content/xdocs/1.1rc1/fotree/disabled-testcases.xml
diff --git a/src/documentation/content/xdocs/1.1/graphics.xml b/src/documentation/content/xdocs/1.1rc1/graphics.xml
index b1653443a..b1653443a 100644
--- a/src/documentation/content/xdocs/1.1/graphics.xml
+++ b/src/documentation/content/xdocs/1.1rc1/graphics.xml
diff --git a/src/documentation/content/xdocs/1.1/hyphenation.xml b/src/documentation/content/xdocs/1.1rc1/hyphenation.xml
index e6f666826..e6f666826 100644
--- a/src/documentation/content/xdocs/1.1/hyphenation.xml
+++ b/src/documentation/content/xdocs/1.1rc1/hyphenation.xml
diff --git a/src/documentation/content/xdocs/1.1/index.xml b/src/documentation/content/xdocs/1.1rc1/index.xml
index f1d4dcb87..0b5f58215 100644
--- a/src/documentation/content/xdocs/1.1/index.xml
+++ b/src/documentation/content/xdocs/1.1rc1/index.xml
@@ -19,18 +19,18 @@
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
<header>
- <title>Apacheâ„¢ FOP Version 1.1</title>
+ <title>Apacheâ„¢ FOP Version 1.1rc1</title>
<version>$Revision$</version>
</header>
<body>
<section id="intro">
<title>Introduction</title>
<p>
- The Apacheâ„¢ FOP team is proud to present to you this production quality
- minor (dot) release of FOP. FOP 1.1 contains many bux fixes and a number of improvements, including
+ This is Release Candidate 1 (rc1) of an upcoming minor (dot) release of FOP. FOP 1.1rc1 contains many bux
+ fixes and a number of improvements, including
important features such as support for <a href="complexscripts.html">Complex Scripts</a>
(e.g., Arabic, Hebrew, Indic, and Southeast Asian scripts). To see what has changed since the last release,
- please visit <a href="releaseNotes_1.0.html">Release Notes</a>.
+ please visit <a href="releaseNotes_1.1rc1.html">Release Notes</a>.
</p>
<p>
This release implements a substantial subset of the W3C XSL-FO 1.1
diff --git a/src/documentation/content/xdocs/1.1/intermediate.xml b/src/documentation/content/xdocs/1.1rc1/intermediate.xml
index 171ae4e6a..171ae4e6a 100644
--- a/src/documentation/content/xdocs/1.1/intermediate.xml
+++ b/src/documentation/content/xdocs/1.1rc1/intermediate.xml
diff --git a/src/documentation/content/xdocs/1.1rc1/known-issues.xml b/src/documentation/content/xdocs/1.1rc1/known-issues.xml
new file mode 100644
index 000000000..c0107317d
--- /dev/null
+++ b/src/documentation/content/xdocs/1.1rc1/known-issues.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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$ -->
+<known-issues>
+ <known-issue>
+ Support for Unicode characters outside of the Base Multilingual Plane (BMP), i.e., characters
+ whose code points are greater than 65535, is not yet implemented.
+ See <link href="http://issues.apache.org/bugzilla/show_bug.cgi?id=51843">bug 51843</link>.
+ </known-issue>
+ <known-issue>
+ The writing-mode property does not produce the expected behavior when specified on
+ <code>fo:simple-page-master</code> or <code>fo:region-*</code> elements.
+ See <link href="http://issues.apache.org/bugzilla/show_bug.cgi?id=53276">bug 53276</link>.
+ </known-issue>
+ <known-issue>
+ Support for Devanagari and other Indic scripts is not yet complete.
+ </known-issue>
+ <known-issue>
+ Use of Unicode U+200C ZERO WIDTH NON-JOINER (ZWNJ) or U+200D ZERO WIDTH JOINER (ZWJ)
+ does not prevent or force contextual substitution, respectively, when used with Arabic script.
+ </known-issue>
+ <known-issue>
+ Use of Unicode U+200C ZERO WIDTH NON-JOINER (ZWNJ) or U+200D ZERO WIDTH JOINER (ZWJ)
+ does not affect conjunct formation or other special behavior prescribed when used with Indic scripts.
+ </known-issue>
+ <known-issue>
+ Support for automatic line breaking at orthographic syllable segment boundaries in Indic
+ or Southeast Asian scripts is not yet available. In the mean time, use U+200B ZERO WIDTH SPACE (ZWSP).
+ </known-issue>
+ <known-issue>
+ Complex script content is presently supported only with AT, IF, and PDF output formats.
+ </known-issue>
+ <known-issue>
+ When complex script text encounters an <code>fo:inline</code> or <code>fo:character</code> boundary,
+ contextual substitution and ligature formation will not occur across the boundary. This prevents,
+ for example, applying a different color to an Arabic Letter within an Arabic word, unless that letter
+ is a non-joining letter (on both sides).
+ </known-issue>
+</known-issues>
diff --git a/src/documentation/content/xdocs/1.1/knownissues_overview.xml b/src/documentation/content/xdocs/1.1rc1/knownissues_overview.xml
index b2ea2eff2..f27f98f32 100644
--- a/src/documentation/content/xdocs/1.1/knownissues_overview.xml
+++ b/src/documentation/content/xdocs/1.1rc1/knownissues_overview.xml
@@ -49,7 +49,7 @@
This section lists disabled test cases in the test suite for the FO tree tests, at the time
of the release.
</p>
- <xi:include href="cocoon://knownissues-raw-fotree_1.1.xml#xpointer(/document/body/*)"/>
+ <xi:include href="cocoon://knownissues-raw-fotree_1.1rc1.xml#xpointer(/document/body/*)"/>
</section>
<section>
<title>Layout Engine</title>
@@ -57,12 +57,17 @@
This section lists disabled test cases in the test suite for the layout engine tests, at the
time of the release.
</p>
- <xi:include href="cocoon://knownissues-raw-layoutengine_1.1.xml#xpointer(/document/body/*)"/>
+ <xi:include href="cocoon://knownissues-raw-layoutengine_1.1rc1.xml#xpointer(/document/body/*)"/>
</section>
<section>
<title>Other known issues</title>
- <p>This section lists other known issues.</p>
- <xi:include href="cocoon://knownissues-raw-static_1.1.xml#xpointer(/document/body/*)"/>
+ <p>This section lists some other issues that post-date the release of FOP 1.0. For known issues that pre-date FOP 1.0, see
+ <link href="http://issues.apache.org/bugzilla/buglist.cgi?chfieldto=2010-07-20&amp;chfield=%5BBug%20creation%5D&amp;query_format=advanced&amp;chfieldfrom=2001-01-01&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_status=NEEDINFO&amp;product=Fop">older bugs that remain open</link>.
+ For all open issues that post-date FOP 1.0, see
+ <link href="http://issues.apache.org/bugzilla/buglist.cgi?chfieldto=Now&amp;chfield=%5BBug%20creation%5D&amp;query_format=advanced&amp;chfieldfrom=2010-07-20&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;bug_status=NEEDINFO&amp;product=Fop">newer bugs that remain open</link>.
+ </p>
+ <!-- See <root>/known-issues.xml for the source document of this section! -->
+ <xi:include href="cocoon://knownissues-raw-static_1.1rc1.xml#xpointer(/document/body/*)"/>
</section>
</section>
</body>
diff --git a/src/documentation/content/xdocs/1.1/layoutengine/disabled-testcases.xml b/src/documentation/content/xdocs/1.1rc1/layoutengine/disabled-testcases.xml
index 5208fa91d..5208fa91d 100644
--- a/src/documentation/content/xdocs/1.1/layoutengine/disabled-testcases.xml
+++ b/src/documentation/content/xdocs/1.1rc1/layoutengine/disabled-testcases.xml
diff --git a/src/documentation/content/xdocs/1.1/metadata.xml b/src/documentation/content/xdocs/1.1rc1/metadata.xml
index 5d4185533..5d4185533 100644
--- a/src/documentation/content/xdocs/1.1/metadata.xml
+++ b/src/documentation/content/xdocs/1.1rc1/metadata.xml
diff --git a/src/documentation/content/xdocs/1.1/output.xml b/src/documentation/content/xdocs/1.1rc1/output.xml
index cabbbb0fa..cabbbb0fa 100644
--- a/src/documentation/content/xdocs/1.1/output.xml
+++ b/src/documentation/content/xdocs/1.1rc1/output.xml
diff --git a/src/documentation/content/xdocs/1.1/pdfa.xml b/src/documentation/content/xdocs/1.1rc1/pdfa.xml
index 0b8399121..0b8399121 100644
--- a/src/documentation/content/xdocs/1.1/pdfa.xml
+++ b/src/documentation/content/xdocs/1.1rc1/pdfa.xml
diff --git a/src/documentation/content/xdocs/1.1/pdfencryption.xml b/src/documentation/content/xdocs/1.1rc1/pdfencryption.xml
index 2d8fdfb10..2d8fdfb10 100644
--- a/src/documentation/content/xdocs/1.1/pdfencryption.xml
+++ b/src/documentation/content/xdocs/1.1rc1/pdfencryption.xml
diff --git a/src/documentation/content/xdocs/1.1/pdfx.xml b/src/documentation/content/xdocs/1.1rc1/pdfx.xml
index bef2fce2a..bef2fce2a 100644
--- a/src/documentation/content/xdocs/1.1/pdfx.xml
+++ b/src/documentation/content/xdocs/1.1rc1/pdfx.xml
diff --git a/src/documentation/content/xdocs/1.1/running.xml b/src/documentation/content/xdocs/1.1rc1/running.xml
index 5e30bb25e..5e30bb25e 100644
--- a/src/documentation/content/xdocs/1.1/running.xml
+++ b/src/documentation/content/xdocs/1.1rc1/running.xml
diff --git a/src/documentation/content/xdocs/1.1/servlets.xml b/src/documentation/content/xdocs/1.1rc1/servlets.xml
index dd2df4351..dd2df4351 100644
--- a/src/documentation/content/xdocs/1.1/servlets.xml
+++ b/src/documentation/content/xdocs/1.1rc1/servlets.xml
diff --git a/src/documentation/content/xdocs/1.1/upgrading.xml b/src/documentation/content/xdocs/1.1rc1/upgrading.xml
index 1e2136a06..1e2136a06 100644
--- a/src/documentation/content/xdocs/1.1/upgrading.xml
+++ b/src/documentation/content/xdocs/1.1rc1/upgrading.xml
diff --git a/src/documentation/content/xdocs/bugs.xml b/src/documentation/content/xdocs/bugs.xml
index 77b6ce379..100789c54 100644
--- a/src/documentation/content/xdocs/bugs.xml
+++ b/src/documentation/content/xdocs/bugs.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Bugs and Other Trackable Issues</title>
diff --git a/src/documentation/content/xdocs/compliance.ihtml b/src/documentation/content/xdocs/compliance.ihtml
index 55362db8c..11e3332b3 100644
--- a/src/documentation/content/xdocs/compliance.ihtml
+++ b/src/documentation/content/xdocs/compliance.ihtml
@@ -561,7 +561,7 @@
</tr>
<tr>
<th align="center">1.0 (stable)</th>
- <th align="center">1.1 (stable)</th>
+ <th align="center">1.1 (rc1)</th>
<th align="center">development</th>
</tr>
@@ -883,8 +883,8 @@
<td><a name="fo-object-bidi-override" id="fo-object-bidi-override">bidi-override</a></td>
<td class="extended">Extended</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
<td>&nbsp;</td>
</tr>
<tr>
@@ -1492,7 +1492,7 @@
</tr>
<tr>
<th align="center">1.0 (stable)</th>
- <th align="center">1.1 (stable)</th>
+ <th align="center">1.1 (rc1)</th>
<th align="center">develop- ment</th>
</tr>
@@ -2303,7 +2303,7 @@
<td class="yes">yes</td>
<td class="yes">yes</td>
<td>For PDF output: Only 2-letter codes from ISO 639 are supported properly to
- identify the natural language!</td>
+ identify the natural language! Also used with complex scripts features.</td>
</tr>
<tr>
<td align="center"><a href=
@@ -2311,9 +2311,9 @@
<td><a name="fo-property-script" id="fo-property-script">script</a></td>
<td class="extended">Extended</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
- <td>&nbsp;</td>
+ <td class="no">yes</td>
+ <td class="no">yes</td>
+ <td>Used with complex scripts features to override default script heuristics.</td>
</tr>
<tr>
<td align="center"><a href=
@@ -3647,9 +3647,9 @@
<td><a name="fo-property-format" id="fo-property-format">format</a></td>
<td class="basic">Basic</td>
<td class="partial">partial</td>
- <td class="partial">partial</td>
- <td class="partial">partial</td>
- <td>only values '0*1', 'a', 'A', 'i', 'I' supported</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
+ <td>[1.0 and earlier] only values '0*1', 'a', 'A', 'i', 'I' supported</td>
</tr>
<tr>
<td align="center"><a href=
@@ -3658,8 +3658,8 @@
"fo-property-grouping-separator">grouping-separator</a></td>
<td class="extended">Extended</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
<td>&nbsp;</td>
</tr>
<tr>
@@ -3668,8 +3668,8 @@
<td><a name="fo-property-grouping-size" id="fo-property-grouping-size">grouping-size</a></td>
<td class="extended">Extended</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
<td>&nbsp;</td>
</tr>
<tr>
@@ -3678,8 +3678,8 @@
<td><a name="fo-property-letter-value" id="fo-property-letter-value">letter-value</a></td>
<td class="basic">Basic</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
<td>&nbsp;</td>
</tr>
@@ -4177,9 +4177,9 @@
<td><a name="fo-property-writing-mode" id="fo-property-writing-mode">writing-mode</a></td>
<td class="basic">Basic</td>
<td class="no">no</td>
- <td class="no">no</td>
- <td class="no">no</td>
- <td>&nbsp;</td>
+ <td class="yes">yes</td>
+ <td class="yes">yes</td>
+ <td>[1.1 and later] only horizontal left-to-right and right-to-left modes</td>
</tr>
<tr>
@@ -4643,10 +4643,9 @@
</tr>
<tr>
<th align="center">1.0 (stable)</th>
- <th align="center">1.1 (stable)</th>
- <th align="center">develop- ment</th>
+ <th align="center">1.1 (rc1)</th>
+ <th align="center">development</th>
</tr>
-
<tr>
<td class="category" align="center"><a href=
"http://www.w3.org/TR/xsl/#d0e5860">&sect;5.10.1</a></td>
diff --git a/src/documentation/content/xdocs/download.xml b/src/documentation/content/xdocs/download.xml
index e153a97b8..905e4a131 100644
--- a/src/documentation/content/xdocs/download.xml
+++ b/src/documentation/content/xdocs/download.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Downloading A Distribution</title>
@@ -85,26 +85,26 @@
<p/>
<table>
<tr>
- <th colspan="2">Latest Stable Release</th>
+ <th colspan="2">This Candidate Release</th>
</tr>
<tr>
<td>Repository URL</td>
<td>
- <link href="http://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_1/">
- <code>http://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_1/</code>
+ <link href="http://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_1rc1/">
+ <code>http://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-1_1rc1/</code>
</link>
</td>
</tr>
<tr>
<td>Web view</td>
<td>
- <link href="http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-1_1/">
- <code>http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-1_1/</code>
+ <link href="http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-1_1rc1/">
+ <code>http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-1_1rc1/</code>
</link>
</td>
</tr>
<tr>
- <th colspan="2">Previous Stable Release</th>
+ <th colspan="2">Latest Stable Release</th>
</tr>
<tr>
<td>Repository URL</td>
@@ -123,6 +123,25 @@
</td>
</tr>
<tr>
+ <th colspan="2">Previous Stable Release</th>
+ </tr>
+ <tr>
+ <td>Repository URL</td>
+ <td>
+ <link href="http://svn.apache.org/repos/asf/xmlgraphics/fop/tages/fop-0_95/">
+ <code>http://svn.apache.org/repos/asf/xmlgraphics/fop/tags/fop-0_95/</code>
+ </link>
+ </td>
+ </tr>
+ <tr>
+ <td>Web view</td>
+ <td>
+ <link href="http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-0_95/">
+ <code>http://svn.apache.org/viewvc/xmlgraphics/fop/tags/fop-0_95/</code>
+ </link>
+ </td>
+ </tr>
+ <tr>
<th colspan="2">Trunk</th>
</tr>
<tr>
diff --git a/src/documentation/content/xdocs/examples.xml b/src/documentation/content/xdocs/examples.xml
index f64a0d702..6565c1b4e 100644
--- a/src/documentation/content/xdocs/examples.xml
+++ b/src/documentation/content/xdocs/examples.xml
@@ -39,7 +39,7 @@
<tr>
<td>default font characters</td>
<td><link href="fo/fonts.fo">fonts.fo</link></td>
- <td><link href="fo/fonts.fo.pdf">fonts.fo.pdf</link></td>
+ <td><link href="fo/fonts.pdf">fonts.pdf</link></td>
</tr>
</table>
<p>Other basic examples on the use of XSL-FO can be found in the FOP distribution in
@@ -100,17 +100,17 @@ Embedding images in FO:
<tr>
<td>align in larger viewport</td>
<td><link href="fo/align.fo">align.fo</link></td>
- <td><link href="fo/align.fo.pdf">align.fo.pdf</link></td>
+ <td><link href="fo/align.pdf">align.pdf</link></td>
</tr>
<tr>
<td>align in smaller viewport</td>
<td><link href="fo/align2.fo">align2.fo</link></td>
- <td><link href="fo/align2.fo.pdf">align2.fo.pdf</link></td>
+ <td><link href="fo/align2.pdf">align2.pdf</link></td>
</tr>
<tr>
<td>scaling image</td>
<td><link href="fo/size.fo">size.fo</link></td>
- <td><link href="fo/size.fo.pdf">size.fo.pdf</link></td>
+ <td><link href="fo/size.pdf">size.pdf</link></td>
</tr>
</table>
<p>Look also into the directory examples/fo/svg. There you find some very extensive SVG examples.
@@ -132,7 +132,7 @@ Instream Foreign Object images in FO, there are more on the
<tr>
<td>embedding svg in viewport</td>
<td><link href="fo/embed.fo">embed.fo</link></td>
- <td><link href="fo/embed.fo.pdf">embed.fo.pdf</link></td>
+ <td><link href="fo/embed.pdf">embed.pdf</link></td>
</tr>
</table>
</section>
diff --git a/src/documentation/content/xdocs/faq.xml b/src/documentation/content/xdocs/faq.xml
index 463583666..47fa65e6e 100644
--- a/src/documentation/content/xdocs/faq.xml
+++ b/src/documentation/content/xdocs/faq.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V2.0//EN" "http://forrest.apache.org/dtd/faq-v20.dtd">
+<!DOCTYPE faqs PUBLIC "-//APACHE//DTD FAQ V1.3//EN" "http://forrest.apache.org/dtd/faq-v12.dtd">
<faqs title="FOP FAQ">
<part id="part-general">
<title>Apacheâ„¢ FOP: General questions</title>
@@ -146,11 +146,11 @@
<p>
When it's ready and the committers have enough time to go
through the time-consuming process of creating a release. Version
- 1.1 was released on [TBD - ADD DAY MONTH] 2012, and will release a
- subsequent version when we accumulate enough enhancements and bug fixes. If
- you want to speed up the process, consider <link
- href="dev/index.html#involved">contributing</link> to
- FOP.</p>
+ 1.1rc1 was released on 02 July 2012. A subsequent final
+ Version 1.1 is expected to be released within 1 to 3 months following
+ this release candidate. If you want to speed up the process, consider <link
+ href="dev/index.html#involved">contributing</link> to FOP.
+ </p>
</answer>
</faq>
<faq id="redesign">
diff --git a/src/documentation/content/xdocs/fo.xml b/src/documentation/content/xdocs/fo.xml
index 8818a030c..f0781ec50 100644
--- a/src/documentation/content/xdocs/fo.xml
+++ b/src/documentation/content/xdocs/fo.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: XSL-FO Input</title>
@@ -518,7 +518,7 @@ This applies similarly to the extent of the after region and the bottom margin o
<section id="external-resources">
<title>External Resources</title>
<p>Resources needed by an XSL-FO file that are external to it (graphics, for example), are defined in the XSL-FO standard as being of type "uri-specification". This is defined in the standard at <jump href="http://www.w3.org/TR/xsl11/#datatype">Section 5.11 Property Datatypes</jump>, which includes a link to the URI standard itself. Refer to the XSL-FO and URI standards themselves for more detailed instructions.</p>
- <p>URIs may be either absolute or relative to a base URI. (See <link href="1.1/configuration.html">FOP: Configuration</link> for information on setting the base URI for a FOP session). Here is an example referencing an external-graphic that is relative to the base URI:</p>
+ <p>URIs may be either absolute or relative to a base URI. (See <link href="1.1rc1/configuration.html">FOP: Configuration</link> for information on setting the base URI for a FOP session). Here is an example referencing an external-graphic that is relative to the base URI:</p>
<source><![CDATA[<fo:external-graphic src="url('images/logo.jpg')"/>]]></source>
<p>Here is an example referencing an external-graphic that is an absolute URI on a local filesystem:</p>
<source><![CDATA[fo:external-graphic src="url('file:///d:/images/logo.jpg')"/>]]></source>
diff --git a/src/documentation/content/xdocs/fo/align.fo b/src/documentation/content/xdocs/fo/align.fo
index ee0cc8827..06e6a2929 100644
--- a/src/documentation/content/xdocs/fo/align.fo
+++ b/src/documentation/content/xdocs/fo/align.fo
@@ -19,19 +19,18 @@
<fo:root font-family="Times Roman" font-size="12pt" text-align="center" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
- <fo:simple-page-master
- margin-right="1.5cm"
- margin-left="1.5cm"
- margin-bottom="2cm"
- margin-top="1cm"
- page-width="21cm"
- page-height="29.7cm"
- master-name="left">
- <fo:region-before extent="1cm"/>
- <fo:region-body margin-top="1cm"/>
- <fo:region-after extent="1.5cm"/>
- </fo:simple-page-master>
-
+ <fo:simple-page-master
+ margin-right="1.5cm"
+ margin-left="1.5cm"
+ margin-bottom="2cm"
+ margin-top="1cm"
+ page-width="21cm"
+ page-height="29.7cm"
+ master-name="left">
+ <fo:region-body margin-top="1cm"/>
+ <fo:region-before extent="1cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence id="N2528" master-reference="left">
diff --git a/src/documentation/content/xdocs/fo/align.fo.pdf b/src/documentation/content/xdocs/fo/align.fo.pdf
deleted file mode 100644
index 9e5393e1e..000000000
--- a/src/documentation/content/xdocs/fo/align.fo.pdf
+++ /dev/null
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/align.pdf b/src/documentation/content/xdocs/fo/align.pdf
new file mode 100644
index 000000000..4b9413b1c
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/align.pdf
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/align2.fo b/src/documentation/content/xdocs/fo/align2.fo
index d16553139..64449dbb3 100644
--- a/src/documentation/content/xdocs/fo/align2.fo
+++ b/src/documentation/content/xdocs/fo/align2.fo
@@ -19,19 +19,18 @@
<fo:root font-family="Times Roman" font-size="12pt" text-align="center" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
- <fo:simple-page-master
- margin-right="1.5cm"
- margin-left="1.5cm"
- margin-bottom="2cm"
- margin-top="1cm"
- page-width="21cm"
- page-height="29.7cm"
- master-name="left">
- <fo:region-before extent="1cm"/>
- <fo:region-body margin-top="1cm"/>
- <fo:region-after extent="1.5cm"/>
- </fo:simple-page-master>
-
+ <fo:simple-page-master
+ margin-right="1.5cm"
+ margin-left="1.5cm"
+ margin-bottom="2cm"
+ margin-top="1cm"
+ page-width="21cm"
+ page-height="29.7cm"
+ master-name="left">
+ <fo:region-body margin-top="1cm"/>
+ <fo:region-before extent="1cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence id="N2528" master-reference="left">
@@ -59,7 +58,7 @@ Default align:
<fo:block>
Default align:
(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" src="images/fop.jpg"/>), start-before
-(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" text-align="start" display-align="start" src="images/fop.jpg"/>), start-center
+(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" text-align="start" display-align="before" src="images/fop.jpg"/>), start-center
(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" text-align="start" display-align="center" src="images/fop.jpg"/>), start-after
(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" text-align="start" display-align="after" src="images/fop.jpg"/>), center-before
(<fo:external-graphic width="50pt" height="50pt" overflow="hidden" text-align="center" display-align="before" src="images/fop.jpg"/>), center-after
diff --git a/src/documentation/content/xdocs/fo/align2.fo.pdf b/src/documentation/content/xdocs/fo/align2.fo.pdf
deleted file mode 100644
index f5a02666b..000000000
--- a/src/documentation/content/xdocs/fo/align2.fo.pdf
+++ /dev/null
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/align2.pdf b/src/documentation/content/xdocs/fo/align2.pdf
new file mode 100644
index 000000000..01b8d1bfb
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/align2.pdf
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/build.xml b/src/documentation/content/xdocs/fo/build.xml
new file mode 100644
index 000000000..4b4a099b4
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/build.xml
@@ -0,0 +1,70 @@
+<?xml version="1.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.
+-->
+<!-- =========================================================================== -->
+<project default="newPDF" basedir=".">
+ <!-- =================================================================== -->
+ <!-- Initialization target -->
+ <!-- =================================================================== -->
+ <target name="init">
+ <tstamp/>
+ <mkdir dir="tests"/>
+ <property name="testDir" value="tests"/>
+ <property name="foDir" value="."/>
+ <path id="run-classpath">
+ <fileset dir="../../../../../lib">
+ <include name="*.jar"/>
+ </fileset>
+ <pathelement location="../../../../../build/fop.jar"/>
+ </path>
+ <taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop" classpathref="run-classpath"/>
+ </target>
+ <!-- =================================================================== -->
+ <!-- Help on usage -->
+ <!-- =================================================================== -->
+ <target name="usage">
+ <echo message="Use '-projecthelp' instead"/>
+ </target>
+ <!-- =================================================================== -->
+ <!-- Produces new test files (function) -->
+ <!-- =================================================================== -->
+ <target name="newTestFiles">
+ <fop format="${mimetype}" outdir="${outDir}" messagelevel="${msglevel}" relativebase="true" throwexceptions="false">
+ <fileset dir=".">
+ <include name="**/*.fo"/>
+ </fileset>
+ </fop>
+ </target>
+ <!-- =================================================================== -->
+ <!-- Produces new test PDF files -->
+ <!-- =================================================================== -->
+ <target name="newPDF" depends="init" description="Creates a new set of PDF test files">
+ <antcall target="newTestFiles">
+ <param name="mimetype" value="application/pdf"/>
+ <param name="msglevel" value="warn"/>
+ <param name="outDir" value="${testDir}"/>
+ </antcall>
+ </target>
+ <!-- =================================================================== -->
+ <!-- Clean targets -->
+ <!-- =================================================================== -->
+ <target name="clean" depends="init">
+ <delete dir="${testDir}"/>
+ </target>
+
+</project>
+<!-- End of file -->
diff --git a/src/documentation/content/xdocs/fo/embed.fo b/src/documentation/content/xdocs/fo/embed.fo
index 558e9d397..6b052e0bf 100644
--- a/src/documentation/content/xdocs/fo/embed.fo
+++ b/src/documentation/content/xdocs/fo/embed.fo
@@ -23,19 +23,18 @@
<fo:root font-family="Times Roman" font-size="12pt" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
- <fo:simple-page-master
- margin-right="1.5cm"
- margin-left="1.5cm"
- margin-bottom="2cm"
- margin-top="1cm"
- page-width="21cm"
- page-height="29.7cm"
- master-name="left">
- <fo:region-before extent="1cm"/>
- <fo:region-body margin-top="1cm"/>
- <fo:region-after extent="1.5cm"/>
- </fo:simple-page-master>
-
+ <fo:simple-page-master
+ margin-right="1.5cm"
+ margin-left="1.5cm"
+ margin-bottom="2cm"
+ margin-top="1cm"
+ page-width="21cm"
+ page-height="29.7cm"
+ master-name="left">
+ <fo:region-body margin-top="1cm"/>
+ <fo:region-before extent="1cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence id="N2528" master-reference="left">
diff --git a/src/documentation/content/xdocs/fo/embed.fo.pdf b/src/documentation/content/xdocs/fo/embed.fo.pdf
deleted file mode 100644
index 6da06b559..000000000
--- a/src/documentation/content/xdocs/fo/embed.fo.pdf
+++ /dev/null
@@ -1,87 +0,0 @@
-%PDF-1.3
-%ª«¬­
-4 0 obj
-<< /Type /Info
-/Producer (FOP 0.20.5) >>
-endobj
-5 0 obj
-<< /Length 1556 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gb"0W9p=9h(^KQB5D>011Kd^2(:&!s-8.0G?92NC6am<+$Zp"a8L^3ZrE?Z%8B:u_OFn)DOGr-/INIQ=q\oZh2p:3YpSJW^j5k;[E4:*BGe#CoakN"mYH!sFZ8>$).@Y@g/-!,+\,3geIX]sgn&ks8h-P:I5CJ>(?M<peVjI(+?b[S@pZ8%/ns@)HU2Lio<0CtCPX[Q)8_(<FftM:sit[&L*Ob:OKat[.EkI%ON)unFn92KJrG.J!cH<PB*A9Y6q24X,`S^&S[!UEIh+u"#V93'eZc#bITL93O^P^p,I3BHrmbEFVPF$aP[Jemg]0^JG[GBF4ZUN[?=KSW(*k#W!J+1'Bh;+g]["$p!rMJIh;uH?[:#+dG<U]5@$Jf'eIGN8iGJ0k>3srEp%+j`GFC2lVAW?-k]'A%*A+X0,Y&n>gXrgJRd8etuLIh.uop[SIXoW1(Me8(mZ+eI84[tkfD8Y2>AOP5_.60qf-b].hK50R#%EJ8&ck"-ed6),XDAZ4I/+.NABKpXVTecSBnJhE/-BIl,-QFP0P>7hC<B]QN&C.,Y8Gd*8%[k^9Hi4&$B)L$>kMsi)STHZs%$'J5nT--!YC%F5o`L74Wr:Be]r#sCZ+lgS/E:AD3,3jV\ej=Ch)Mm&T3L9Qof&akqNaE.ePBeD$+%h=PJ*s!3>n&C]igN#KOB]'j8H"aks*5=iHX3ZW>2HPS[b]*`)73_Q%NVce\!_DKr]/-Y/42K3d4X3_6^:.XnTm.M/Ws*C)U,oQ,$R7M5;IQWWpQNXEeNq$<R<Z?j3W^FmcIHJnJLtn"7q,lIV18P-__e<Fgr_6rPiH7SM(LJ5hU;;F)d'"fZPjPmA)PrUM!Qp%*M$jflJgibHB!cmc"N9.VAd;)(V]?<k_^!EQuC=90p["fud#Pn6%clf97o>-MaM&m21cZ'7XGeK>`6"O7>T<ko&E!@qO]XE0/^&3L?dC3.eQYbEX_<h1cDLEnJS=-O,Fo?4qC$r@,-5S^4!<M2Bs<$Qsaan'ESI[F:IQD.j]$*GaN/1&\A3Cq0H&Y'R;YM^/.JlhFK?K]UL7.;t8P=rd#Au7HmY>plj8g:-IOGkatB8+,OGQk;/'tf.M\ap^O]Zf]N/IY_K;_Cf\L-lRiL(u"ei;CH2-j*X=.qf*gTG=iZSQ6qr)cg<j)q4H%YZ.\Z,10D%M5;J,.L4)Jb&CAe^;<tH$=DaBI%@mQK]&)u;bP"C=,]);Y<#<---<LF5r/0+2(Jf:i@B;0YOE:@cJ;PgE8YMeBD+'tMJH7H>BtH@(6&KA0C:ed<NAL]hd<_.;BdP%K4MpV]JSDt]5SSS_HjZ5GBXA0<7Li@R\gm\NFJc%&ogoS@O[.ub!@ekBUfe=Y.td^!a":e>j%+t+a=UNaVEi.YkDdNJud0091bqd)C/fC``XJC$=&-4E!<D[FmcaPJcf8u<fEkZ?OjPcl:rlH2j2]h[<`2[_>YWO/1#n25qkWC<X.PM>_ic-+YL^(]=:7:C?abAqh?bqD4b-,1\n_j+*T5NVnRDAT6?<U@WcP17PIi#^4hB/rspg7gYM~>
-endstream
-endobj
-6 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 5 0 R
->>
-endobj
-7 0 obj
-<< /Length 1817 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gb"0W:N+uG(^BKA5)#"'Yd"$U8imem#OF-PR"6:/*k]utN6sEG3%4Xj7nFsp;3J?+4m;Cb/S%)3?CFKB?VSYnqb?ePK?>&Z1uIXURQk@7VtS,NabaJ,Y-fH"AbkJUs)n(bDSLTWQi$]3.r%#RgR?#YrF>m&j5#._.Gt&lrOg7dfGe=DCLO9.JlJ#\Nu:_+'9XObCm7%pIqEiC#]3r(6ZXV,rHP^:2:!="7[p5gQd%aYoh4"?CMW%pVqf;,\4sMKf<>Y[[oqT?]$9s%n,K_VArek#gUbF!FjDL<f/M_nI7j[N(Sm.]Wjj^^X.[)1g9opE<O[0BX3jCRC#>/(H\Zt^D8g"tMc@0c>I<YL)PBJq<Yb-Gl^BiRqaf,5=oU6pl&g!lMKY/W;-W=o:>%?@\t`PT_@NNSUM//U^7dnFB>]k,gsGT'8p>p-/_"t]4N`X)^SA/n>4O8[WK$DZi:"X[8@`0iGF;K/oBJDZ9tRQ^T20MuX/In(9BX/odV^W3rKV8qhu&C&.Ui@aH`nog^">K.8!\<CbO;jA8pD*MA_f>SZl<4uYB;@Nk0tuRbZQ^4Zl`RW%CQc6l9V>:g\X^LPnhTI(tXiC5P1&O>dih=]W7P0+tFD=.[%`'UfWeAOpP4=dVor(_H")Q=5iGu?005^2='PfY.j8J=(&-[];:<l9bJ,&#hDj."`%!AYQ@k@$<R<Z?sPjq69;_j@GTJ+k>`7n,`KdDas8\bkm\B&A4"hR1fT1/:_fus<N*KP<MaYXc)UX7DLX_9k$aN$,J&\><CpXd;FK$3aTS\ZBtt'X!@qO]XFPH\YU\Vu)St.eR@`EV"d+89V$UU:P#AMhgD3`r/kZfjOs20H@)CZo%(HJMi"k+">B%2tDAdYA`K1Sda):WQ;.YHi:?tGNSg5X.4ecbW9V!N#'S<B)'s>DR\-c<hmODkpY$"i\dtAg/Ar1e%#oi@`P/N$La-;XJaci0JKto3`"g?i!]RnbCo.$QBCOt*6.:L?"KM>*j=-Y$X,X&#FPY<*N9aZGQn-WL<.sM6$CZe\5cE7=W(ZpJ.6/"Y,KQRN)PJi,BKk(lkffCYd>!XZP"g+F4['#tNb0soB]CI].`JJ$#/^9_Q\FLn"+mCRiUL`Z"CJkGNJlhFK?GS.:>s#6[Hb1&@?()XK^4M2BZ*,oS9LsJ(`@./D2(]8Ei@B;0YOE:@Y2*0Q]NkoZ/kuj+,'5q+XHLMT,b>rMPKCr*@3P+I?GS.:"g?j,mCZ'Ym@*'X=+=PH)to%WGsV)l\>r8sj/sOC"]p_r\of,GA;.+H's^0W[EIir]<[S6Z`l&V$F><sVH>)o:D+>(*`=mgV@L0aKjZEIKrqQo[_gV'gWGqjlRK%F1W!Bq+pYQ6,V^J,-0:n4_Uc(NCk]!q't1t[fXc61"a>,!D']\<G9=2?le#JE2Yh5Y,q?c(\&BGM>B?a8_H-VhA(.Qi,aB[Mh<MIJrU<u4p8@NPg4a!]HUU%C"C_!=2A_5k-70un,]&]=]dZ\`!H,[^\,ePH#2F!L4!5Am3d=S.rtet1DeYBZ)9"mCOX)8!]qp+@9YE#Q$:.bW$=0>UFG6l5f<tDUW7J+S>o.&e<C*#%OfU<09Lr])D44.H_C$c8=Wo;+Krg@NZE@KaJDf0nF]6C[:nh/r=d&F?+,c5>K),#!I2T6r<l$7f"fl$RmAr(?41i![XCmel?e:;s#lD"fc\IkNRhp:0Qc#fjKD<PeD8,\(cFYa5L\!.0])1S''m`&lNLkFP?K+K&a,A18gZeADJ+r!>R/Z're+oUP&g(8R_^!@;&u7($?83Z%nS$eZO5XGIU386~>
-endstream
-endobj
-8 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 7 0 R
->>
-endobj
-9 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F5
-/BaseFont /Times-Roman
-/Encoding /WinAnsiEncoding >>
-endobj
-10 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F7
-/BaseFont /Times-Bold
-/Encoding /WinAnsiEncoding >>
-endobj
-1 0 obj
-<< /Type /Pages
-/Count 2
-/Kids [6 0 R 8 0 R ] >>
-endobj
-2 0 obj
-<< /Type /Catalog
-/Pages 1 0 R
- >>
-endobj
-3 0 obj
-<<
-/Font << /F5 9 0 R /F7 10 0 R >>
-/ProcSet [ /PDF /ImageC /Text ] >>
-endobj
-xref
-0 11
-0000000000 65535 f
-0000004058 00000 n
-0000004122 00000 n
-0000004172 00000 n
-0000000015 00000 n
-0000000071 00000 n
-0000001719 00000 n
-0000001825 00000 n
-0000003734 00000 n
-0000003840 00000 n
-0000003949 00000 n
-trailer
-<<
-/Size 11
-/Root 2 0 R
-/Info 4 0 R
->>
-startxref
-4261
-%%EOF
diff --git a/src/documentation/content/xdocs/fo/embed.pdf b/src/documentation/content/xdocs/fo/embed.pdf
new file mode 100644
index 000000000..59dec7763
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/embed.pdf
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/fonts.fo b/src/documentation/content/xdocs/fo/fonts.fo
index 12e176eba..0c2646d05 100644
--- a/src/documentation/content/xdocs/fo/fonts.fo
+++ b/src/documentation/content/xdocs/fo/fonts.fo
@@ -18,32 +18,32 @@
<!-- $Id$ -->
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
- <!-- defines the layout master -->
- <fo:layout-master-set>
- <fo:simple-page-master master-name="first"
- page-height="29.7cm"
- page-width="21cm"
- margin-top="1cm"
- margin-bottom="2cm"
- margin-left="2.5cm"
- margin-right="2.5cm">
- <fo:region-body margin-top="1cm"/>
- <fo:region-before extent="1cm"/>
- <fo:region-after extent="1.5cm"/>
- </fo:simple-page-master>
- </fo:layout-master-set>
-
- <!-- starts actual layout -->
- <fo:page-sequence master-reference="first">
+<!-- defines the layout master -->
+<fo:layout-master-set>
+ <fo:simple-page-master
+ master-name="first"
+ page-height="29.7cm"
+ page-width="21cm"
+ margin-top="1cm"
+ margin-bottom="2cm"
+ margin-left="2.5cm"
+ margin-right="2.5cm">
+ <fo:region-body margin-top="1cm"/>
+ <fo:region-before extent="1cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
+</fo:layout-master-set>
+<!-- starts actual layout -->
+<fo:page-sequence master-reference="first">
<fo:flow flow-name="xsl-region-body">
- <fo:block font-family="Helvetica" font-size="14pt">
+<fo:block font-family="Helvetica" font-size="14pt">
Helvetica
</fo:block>
- <fo:block space-after.optimum="10pt" font-family="Helvetica" font-size="10pt">
-<fo:table>
+<fo:block space-after.optimum="10pt" font-family="Helvetica" font-size="10pt">
+<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="65pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="65pt"/>
@@ -303,7 +303,7 @@ Helvetica
Times Roman
</fo:block>
<fo:block space-after.optimum="10pt" font-family="Times Roman" font-size="10pt">
-<fo:table>
+<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="65pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="65pt"/>
@@ -563,7 +563,7 @@ Times Roman
Courier
</fo:block>
<fo:block space-after.optimum="10pt" font-family="Courier" font-size="10pt">
-<fo:table>
+<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="65pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="65pt"/>
@@ -823,7 +823,7 @@ Courier
ZapfDingbats:
</fo:block>
<fo:block space-after.optimum="10pt" font-family="ZapfDingbats" font-size="10pt">
-<fo:table>
+<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="65pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="65pt"/>
@@ -1071,7 +1071,7 @@ Courier
Symbol:
</fo:block>
<fo:block space-after.optimum="10pt" font-family="Symbol" font-size="10pt">
-<fo:table>
+<fo:table table-layout="fixed" width="100%">
<fo:table-column column-width="65pt"/>
<fo:table-column column-width="30pt"/>
<fo:table-column column-width="65pt"/>
diff --git a/src/documentation/content/xdocs/fo/fonts.fo.pdf b/src/documentation/content/xdocs/fo/fonts.fo.pdf
deleted file mode 100644
index 85a37fd0e..000000000
--- a/src/documentation/content/xdocs/fo/fonts.fo.pdf
+++ /dev/null
@@ -1,160 +0,0 @@
-%PDF-1.4
-%ª«¬­
-4 0 obj
-<< /Type /Info
-/Producer (FOP 0.20.5) >>
-endobj
-5 0 obj
-<< /Length 2756 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gas2O=aO+:'LgpN.p>dQQ0),tXf?8Xl8sh^A"4[?L]L?S.Yp(`G)J$07;CF[q0Xk,m[_:;p.hg?\%DUPMj%;2G1eG?n*DpXrcNRk=kqghM^JC4(9q#F6<M1iQEg+@rM.>kF&rk?5<4+=n+NmTMjoY'X2c"#Z%_Ip=kXFJF_B#_[H@&U`<@2^l+]E+l1pZ!Cop\)PH?hg\+B/,61.dsGk/JYH2/>>gUQl'^O&$qIgP0_PeXi&QbNt"`g=GeR$XG9Q\Vt!J+koUIg+m`>Q4&kH259:cpnuO)YE2Y+(Xr3H2XcdDe8Lq]_jXK4.1I\07P#'<[L&Tb:eD$aQ1Beq%DbJ9R`Fs?_!J[FZFa!bf^reYKF[C8A"tK/EcFDnJ:3"S@aEl4-6r5g`7ZS"h?/HmND$@jL1SjK>\"VRr[p,&g'EraP7s/X*K!&QFTB@f-"GBg`c-Q5TXJ(OS?p@pG-s6q\pYrAaYZS2aQkBmZ@1P5]10$OS?4MDT]N!OS<rahNW)"+n(nG\QbDAD^"QiaC@7)(@p=74Hso*+n#NSI6%$;nihZ</a(tWhC"DsEpbO?rEYLhR60L.$HS4N*V01Na;^O/jSeAVgob2UOSAK8*bFc$pCBM1AF>QR%mfVpmZ@1(5i0Z=+n$M*gm)sTOS;O9DTfS;aSVkX2s&gXjSdfFgoS]0HcZ(s+CCCTpQ5,tON2D0*qK<@aA)011uohL?]\T5a@"t%,e`]/LWFs6H3#3#RK&`J6:;k]J"?4`6lo6U"8'`(*b'V<5R'PD*eJm*oKktfP5c!UKo.u\s'*nZ('VeYGGH$-$5!2@U_b]lOT+]?04Yb>rjPHPBG;Th5Cd(n-pReQP$[&p5QTX`^!KW,!k:mL_4pu6n0@1ONrg$24jj]\"Xnnn82#W1TE'Ef]c^4'!k;$P@AEo!56AMb;Ln[0+MCTLJG_VW]jO`kr;T*0iM6bTs-<3X8eLXo)sN'@,38b9klm=rjSpt!Kp<kCs*)m!/4IY['@86]7EGKNU_d9nOT25S(LDu\s$'(.^_@slJ!"&n.74%6-G:O#K`(j;H=<ZVq>ZfR!_j9tru^KZRPp8B"5E*hD.fR'["/K0$b`fV$_aI-UbGs8SLn%O6#@a#a[0o_fg7*%"'J;5H>gtB6;ebYA$XIN>IG*3g-?jGL#1XkKb2dh:@6Wubr&]2<GgsRDE[B@P19c2R4N#)Pccp+c=B4fTnKhI=6S6$?J$t3QI?$nQ7R-Vfg7Z6"+OpHKaotE#\nMOQhDO.a?jR@_ls@dC:4]3l7hQjLRKfJ\N1.Gd%TkY'Y?C7H_@&^G]aksTOH.^_Hn7;4j[L`IWZM$5^T1-em[2Um=dl/LLH7N(Wp/,L-<sk.#N-ap5"&=1tH*f,OL0d=U0G<P6L?-10KB\&SWm4b<#!J8:.%@el,qOQN1P>E7Rrp\;']Dq5gL.E"22g,$Icji>UDXV6lij_DSh>!bsmkKkk?TPgt*F$eNa3.'E6m(TsIF:h&ai0:\`L:h]0o0@Hn"Z4Lp>W@sd8]hih:W@sd8]hj%@W@sd8]hj7FW@sdX]b#qaW@sd8]hj[RW@sd8]hjk2YV.QpKu2VqI:6hCPii8;$VPi?82jp`=P=.Z\cM]FdU"?S%G2J_p-RGM^qR%_(P6i5p4]?V:qRaO0-'A5in]-5iFjkYmfr+d7sgqS2dfuPg'bm3!W0a]?7=Y>fGBSA6Les/^2UFqMK]0rKql=X]Gn+/>1sA']+Oq73^.'^_7L<VU,kIt5Q;eYLj`,@+0pUYh2$JV*?VS@i8'3;;&paaL#CdCI8M",ZA%5mLj`,@+0pUYh2$JV*?TG?MK^<=7<O"!(4p`Tp-j+Oa;0AO,PFQKI)m(TG9cfMFaV7GJp/I5Kr;U\]Gn+/Wr#5n&A/se0<4n<[Lg*@YV3$R7CEc?S$4QGqo-iInSZ4XW9tJT6L\m0^8UH9fg>1G_S2u:(YM.EDSj,dmMFPCn8?+WW9tJT6L\m0^8UH9fg>1G_S2u:(YM.EDSj,dmMFPCn8?+WW9tH`$cT^aqkCZ/A.-5c$2^I.?XsP\]*\A/\mJtU_7L$NU:O]B$c0F]qkCZ/A.-5c`mBo4#I^A5Ca+Cr9^pb<]k#;5Jp<9KV]=,\K%hH1QV?oF>.oUFR4.3oYOU=J]l;.A!d_rkDd4#rAeRJDA:dmcl;_LU&_LmC)Fn&gG-Zt_?=WM*\ZH,`RgAN:`o*FfYa%ocq2u'@V(:?D-3AV;"@l]oF>a`t9."o3XZ1W>U>VA3n>KP3n$7eC?S]I^<&gID"TFPjDJTL;fgP<_RGc(c=28Y#lCM+ZK'J/Y9q:VXI>B>?d%2Wg-54TuF^`?<7e_R"'9mqY1/STV;<<,"NE$Zd-Fg>23A6jih%P+u5?.`Q"PFI+s'tZ2ioFb/G)!V!4POK$Y.#KpgV7rSpuo9+[>.8]*b5XST6W59[<2(ShO[$rp'3YX&jGo!9J#:K?4NTQ1JK:ZDI*gFH!C/Dh9N([,B'Wk<;UquIH&M:l7fE=&%pRn*TtuLH+3^sZV8W]GGf(pF_i,55<YL:F5&mJ>NtD*>T)>jdG.>hO64UG[SQ$do'7Ebd;9uLXlME+0!j:rQWqS4kAp0"8VX^&cbDBrp\]/_g\:X//F^Y+,M^#r5@]95q9'I6W/ag5ns;XcclT*uj'U*;K*"(#%KCI=*L+Xhqu+(VAY::H&:ETgJWBA$n<HcS3^TI0EoiL9NmK8R*;O-<,P9,m2nj=*,;dSX-baVo,F$B.$fAJ/pHP_$<5J~>
-endstream
-endobj
-6 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 5 0 R
->>
-endobj
-7 0 obj
-<< /Length 2935 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gas2O=-jma'SPBB.u%SN_RLo"U`"2C^gpR<OtetcAE%Mt#"GslqY'^#I]5BohPsK0gZn=qd^@Wo9XjJ6B:iGoG+W(r].X%:]@cK]+m`ZsHPb]0m-EK^="`BQb8q_=\pMg#gP@?jrVt48.p$r`m*;b8p^g'q&b&j&msU$7gA(OFhY/=DCr>]H\8rsDC;V+n\@!W1DSmP!\1o:WBuBZFn%'.G[c,iln8L?&E7_MV*Pg^/KUXmT!'HLWF1)Oe!;E>VS86"__#%#PY&D4)J@e^%cF;aRi3lUU$Z1+g\1(G@@N-?hhNb*^i:oYYmZ440*#SY\n0k:=^HVkj+K>OY57DKaWWU"#!q9Mq#C_.:i(d5VIX_da<`B<QIiRCD<*^#`IfeP6WOa/K5.';IYuG!>INJT>-rnlOh^<r0;KY.tI0R27<S)l\(P)7Vl?_ss$?0(HXp;^+$#j+KXp;^+"`RD?Xp;^+%Id+l#CaGEL:a4Z%fH;7^^m/#nGBNlO.n])qf;c3U,qf@o)S5JFl<!1!:EJ0H1:]h!4Sfi4S\k$J=BGZ*rQ!m^q3Ke*rQ"0)fC_5l9+k?%,cn=FWUJ[Wk_?ubu3pp2t%;a9!no_]M!JueK0tH*oWqq#E[7.KU5j_5W^&!?@$_onU*lP.FnOLo+BrX=U1&7a+2cV*C)hJ#VY!p^k)"^iMBca3&*TC]X6u)8&f1pQ[0\1bkR^td]W`m)IF%^$?gquj%I6^_[^X%Hpr:ZfE(pM2;klP#OqaPKU7iB_#N:)?<VLTs*mO`WS%m]s#o>;B1MIk9u9QNNo9pZ#VSn6K)^<G]N"8(rr7iEd^:=ps(B,_foG"j?O/<%4+dKN&ROaG"TSKoGj3rpr;R_pV/Sros6kW-`Z;nqIh5p9G6IsG8U0LT&cDYFiMCW,i4j?fl[%\]TuD?Y$RQ3dd:<S5hZLAB;<XGq;b-p2^kdh6=#HC49)&Bm9GG(@aV7Xk#I%^4d$7>&O>9"M,85d6D)-eZnpr^,l#3;X;EiI5ep>i"'_;@,R4(TB>0[@lB;-MSBL*`UTSZ!X@7,D34eaQ\l69.t9cm4K6$8;=UoBERMkIZ&'N3LPe4!>BA.%Se,O-JQ/i&,[p(;EZ<>V&i>5O,eLoQA,+iSjt>t!+pG4uTS4&M(l[(_S4hhcr,TacI(#+$`/(L#fG-unFQ,@+uDTBI87*U,nkr']_(lUViGjsN2[>XuBP69ijXP2_HLUsi,((TnugBW[mT03h#Yct5L>?FZ#;U#g`t]PrUIU&BG7]PrUITbW'O]PrUITe1bg]PrUITgaI*]PrUITj</B]L[f2;+TN8-nh)6?"i8j-nh)6?"iJp0eY*B6@8`kH!s8\>5`*X$VS(Xp-3%n=OMm5!&Nbk-!f^C0OnEkdY3\^1ZjB[?-"9F@pW9cKh_\*k(P$ckThil?9$Ae:'*66Kd0me,VW_737<LU!]/tm,@0LY0OnEKdY1Et1ZjB9?0EOf@pV.EKhMOUk!`(Wcq.W]]VsuB9HfV8JpC5<WQqu^oa=Bm)JLs\9EGSoWu>\-KhMOU8uikE15/C'$VJUCZnd>/!XhWDX0aX99EGSobH&!*KhMOu8h6jI15/C'.nV=jZq_;r$*5PW5e><6@)\lhO=kVf=RddHU^N^r<]l8>;)_Fp,d?9*</nJW67.6uO.pC=bnMo>XEYFZUMcrj8RTN4W#Be7KhMOuk!_/mSg\[n=>;J/;)_Fp,d:`a<24?.O@`j!]Vn<U9HfV8MKr'Y\sYl3JJIdN)Kdii9ELcYf?NKe.e8uqAq<@%$d7gWcQk7TFGAYCVOn"A+nIrC_$+`,G"s;D&Tic9pkaYFXNgs*"P4gICm%A#.S(hp&?-"0-BYj31Iq?X=)3=[,*P<*Z,#%mb[qKU%;]ZR-WMhG,VgAc&mT9Tbrh32I#png='Q2>R7&BT7"X1.C?.F<k_tToE;s#,Gqt4M$&Je744WDX8RtRe,cK@1G0;-d.3oO*Cpbt>,VgmGs#<J6[I;3_1+aaaN.Pg)P=_i*etRAg@5O/b<NO/^GI7Ip,b6ENDB5W;+iW`rO@W3Qe`J6C*)s1b'/`2ZP!i0Ki<Pi"gM<kC-0+uG+oarT\p'C!_V"a8q5/([](u/]Ri-@mfD$)G:-[dJ5K3#^+a!Nmq!Xi!aT(6&:JkY`)n9b&mf[m`7IN-Rf7r/dnBUKNgq`eFr9cJu*;r'i%G\GOpAk,QIZ`AT(Y\B%!0;SYgci=%L>NC.1c:`hUH>jAo^.?(^#!Y!h%B/Gm=e,PlaICCB]J(+$^2&e^O:?:)\1b3R$:3Oqs^I@*59*?-L;8tLGu^$nEkqo_Z%&nG"Wbahd.;_hJAh>g.&uX(PfN0Rg8\+#1dJ_o&BAS@e8@pfUY4=LjQm^C_#6\05i.Q4?2I\_FrU-YfuEdQalSDR5YC)H/l^sDZX5Ia+J$],.o1]#Lg=[G_mCNXuS]o!XTkX^7i0<)EJpu6[)HdF?EZ\m\Xaa">CAB:"@l&?lutLWjreY5]eqbK."H[8U")ZGljM&F>['m-bt"!2cD#L!k9=*VO$0S_#/L32(s;&Hj7sS\ZN<(R6pIW!;RoJ>'t)gNM+(.>AY`DKr!'$,"r]XpspQ+6&1;K?AN81N?H2.5qbV_N^f+?U7`;H)Fu)Dnq)cZRRnaFnq)cZ)G;;Go7Dl[RS4sV3PL<EiA=H-j,5mc:EpiU(L4o+L`562]&4cmUsqr5']6fjTGldV]&4KeACZKE_7+C+\/I(PE&4JM[?/@4FU'[#87F/]0j!1^bS64B$X(\RG9A\q,h>9tF4D;P'87da65FXm*QUntM7&Ga>]g9,;b1@LA2.0AJ]ngk=:88j?PmNe/S$Sb@Ao$jON7-MTdJ>W-K>nsRTKs.N*dE:@P)+HIUT13[F12]0+9/3<]ZB=IA%q;8d@,d/sO:X0eE*:@@:4JAjnnDQa9>7"16kd=o~>
-endstream
-endobj
-8 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 7 0 R
->>
-endobj
-9 0 obj
-<< /Length 3803 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gat=/BpTgY&cAe=0fD3@gQ_!gWbr-%H[Bq?nSK$`Y[E-$#ltYUY`6udmM]f;-7cEtQ,Vbc]Vh).W&c.ZU3c[qlIOe/ZuagNh:9DIG5(3dgY).YgLY0?P]f'"1YKFQHEqn\p30j>.YR\CFtY4iXLN]Ir1DrnmbQ^L)koHS`^WiIf?5Be+%G9[;Eh1K&"l%F-?rF[f#n^T&#4u<Piq`1%*JN^&j<gG]mKtEDD[b&h6^KPJT<i@OWN>k?@Hh+4AD$Eo]RpYbO:)SEAEOqh6LAd$7O5a$2!HTlfG=%nhcb*O7%&%r.gqmR*7gVm]^$s)CUZ1alMZ[>qc3i-kB8P2^rt:jYJA>InG_RqXsCe;!tH*jQIf7qZ=p`..QB^,1-3.Pa=Uoo]Uh^0A"C&adRc%*ROZaP`OC+H?;F@YClE+^Zj,H^&Jq6-Yk&TF?o:Z!TeqiNZK4fq\u1j3ofJP!PSLIPQthF4Z]81T7M%ObWq4!kl'\;gc:S^d/gr\!gHo%7XB/An%W*\O-;@53P#7TrE#Y>oZ!#g)h?dp%Ec"9SfHPdo_oe+T"GBjkQ[^S2aR8tbs7;,!.)B]jjBPcNt1CP/QV;fYj+srOPGViT%T;12"qj;1OkR<kWV?+bb-5S\rT]OF!q@9mLrRG/4ouTH\1ON7nGsj:Jj82.1%Ek;c(eG8d<`@%+R/'P(E?+MX$U*aZt6GUO$NO1/QjEW1H#7%-7./Wb5?Y"9&0-eMFCl_8?.4XDc?U"rm:YW1LPb%.sQ7Wb6K$"9&65eMFt'Jc>ZQlFC?F5l^jRous[OT`>%bH=g;8d/SSm4nC3Bkl6.2Ssbl^kjR4qLEMt(R=PJKKLZTt]Z`Wp"bOeM$Gd.p%"q_*Ggri,bf%^jMZn^Qh$UuWbREQ7+F)s16#\V9"%<t2*d]C?1Ggm!jg?0]JmbHf#.c>sW%YZcR=R1&"R6A4DJ#Qe!eL3")k7cOZp=,pn7hh*AcY!]3`pj$'nY,/"j&;tI[h.)3Lp>q/6I@k'nVjE"j&;tI[h.)q4.]2/6I.ebjm;UB#/MU<=%`5(*p4o\]cN+1Hl20=`G5XJpX*naXfF$(Yo!@87o]3^>KK75r&fXo`[9?$^+Y3W%YXk>*-s[6[ceQciR6VJO"Y"h9Z53@=^[l_%"cn$upiKIDJ%n*mP-(qh!Lq4e*<0p'#M,HT3Z@l3hKip2F>_e/-m^mGY_IW%YYLg;A3p;.":/["n7iUV>YUBb0B\7t&45dN6\lJGOj:V*1=b!VHUT8p`NN!pg;,PkK'&"P=O7..-!+#cKDd;;/p5&PuhRUU5gJ,+u[.7VNCr76l:;NRB,C(D6<D2bKEU?3hKW+dc-<K_%O_pb8dV"s'@7'7V2@Jf1Be<,1DgUd?c1FFZtXr/"AYAs<d%WL5u5$Gh\L!@ftu-W2+T;*$t=B)"c];*$t=B!0Vj_2QeC.Q):DSfkO?3^BNRe/-mg*M?:dl3hKo%T',Bo`[9HetL:DCG1'1"^tH2JAAZFL0k*mB$%W;VM5o$YC\I?<'Xjh(X(_FdMaIuclGp`JHs@L;ZT0Iie;NU+NuYW&C`"4bju1YCm/uTI)I3TSNs])Z6&Em06VaI@FiP)#Q$pAQ3tLQ;ZVFc,Jpri&8%OA#^jS-O&cg(TF(t;;\4trJhRR45iAbrLqsgZRA^/gT8kV6'nk8=!WkGa=PF2"N)Th/*@p]&"^tH3r5IVC&97IJ_Tc$\JYPI5iX3Qh;uqR(&RN/&0LJi*i$Fi%+K-F,;AH1jnVB5lS#QMk4&uLE$GpUZ!J)7Agi<Q)hMh)7*Br+jr9k]^c:.?kG=DG3?eO[h*1l3(rSY#;qo;JSIIQ1<0CI4k]36/NTp`2MgLm):o6Bm,E^GQ`_A1J:JRNpn_)V^`L5+0$F&Is8.QC'C;U\N'6T6C3GY,_S#&T_GcIgB50tsLB/7(9a##4ehcWLt!0tsdJ%,&/;r&n!Qhm:-qE;IBZ[c,HdS.t"q$;MD]QlF>US!.;dhc>hB2F+U>\k+?jopln_qVla_UKuq5HFp,lpn!)D?oPM>\aIa[0YXaK9\G)B&hSFT@%:^D5>Z<b/We^Y[.!.Q(b[C!A(_jh,jITuMI@3hA]rKB>W<6WSCTHS]*cgr4N:tG3SQ'M#/_oMm::T#M-TcZD(sb'3SfqEcqGY8]g3SGYM^B*1Gsg+F`5V2,:GNm1r2&>h&E`;L^MF:2B*I)h9aD<0a7eo8Q3'c6`tcg2Af$%)5\`!(XDFXg0eFpVp?\KF3&KBcj!uZE4XQS2&4F)"km?X$;MPbd*A>qGMY4p$7A(6k-h]pG->]hEW=":@nH.V&F*Sn']PAo1T&9iFp)rk:($OV#34qa#;RD*p"8l4D+$X8;aW#I;Gb]Q8kLh@1o)<>"ngfSU_Mi@%B7E>5s>#n.E2(aL6RIh*7UaeP#@7rBh1Zb$L6;G8L_[J25DEC"nhAcU_Mi")H)]]JpR9=Q_.neMXe-0<90jJSq!#i@_AHY'fd]Joa(2-I.$)F`q?`oPp`CJe75_g;N,fWU`q8lFbD`FDhISOL/_][T["*=dUsGL@f0(j.`,(_LPV.+)N=DJU`qBZFc*,n']Xb!<5bW3NY.P@@XOgl'mV6O0@U3d:C9u;Qt#eVD(tsj+Vfh_Ft_>Lj"D<K&Xd,&6>\CtC.Ld*MVSZJ_0Db!'qm("0@U3d6Og"c9sK&=2AhK4U`q_9mY0A&I&%o#\LD\Te-=rC%4Mf__pU:/8!>pP-ONb6S7;4RV%?E:PWUu9F2s/`I^TsMWIe#YVqA[T.E&,'Pc#THam>8A@j/@IQV6C@nsd9S5,G&]0pS)7OIt*Bo'uo`g9I-6@Z]L-Dt<H1Q'-I@<*kGJI`0"C.pb+[FW4CgMEu^e^WFZo<;[ZI'SCccYfY);<(q%j<d?,`iSD'cXLpYl`ME3AQ+)&/jG0iV_TL%X<W!arC>M,L6).d!X("u=[1dHtWsZ.eQNsSDYG2;sn7qSGZ;p7`)\#9qe`^)QX4TY/)iVY7dB?)C0r^^JjeWfJ=/0+7Z=6_$\&q>u$Elq612#_Jk=[N:Y=?8^C?>HX9/-dW7_^]qjmM<d?sNT1dB<s`\bl1\(kl%d?^\I1g7JUoF59VH$Elq613R6:7Ba?<U[W$j/!F%8?[Egfd*XR,(kl%d?Q$S`g8S.[MG\UUqN^k,X7*df3E(mRX3n,0?s2mMO1\!/hI%%(Q%$^<X0LDd2&PCYat6p3`5Z\A73Tb8QWpQN2:gDsXsaGK@WRH-`3HT%>#>RrOlmYKl)0:lO\P*I)=>T$/FmN'-EhZf25qs6Zo>Jc9d2ZKca:eEhJ#^L$!DPC7!AP8C6M`3esb)%o([:Oj.pE'g%igj9j[@%CJmsLb1e2IoB0/D]]/&(Un3\@S=;oir^L[e=1mFZe._DoH^p17,!1;,[E0q*ETo,qlJK'BAEU/42L38GY$!n3.rUWmcC^28n]DYRZ[,06GhYW0rpFTd=1mgeeRPoU2MitQNIL!DY$%;\.rUWm6Ib4#^@7TA$+07]M(D&SIcWYp=e/A=Dj/7/eEBuJp6sM<V=HO$/8X/S<aLp0Ap$G>]M0RXRl?"c=!Y)^A,kET2Miu$h@Q9'AKmU*p?uZmk(tX*h@N^oOiZ[FrHlH:,dOY"6WeV&,+C[fD`M1N'3Wu#+fr=#Oj+pDpP-.KA7>(aYk!Z>2L"NFRr`H[=kLA1XLoa>boQ\*>Y/I7o7jL?MF;X8]a*:[(,g*r.^)BR(YsGB9k7](VQTKI7!?tk#?`8*]W"!_MF;X8]a!4Z[WtYm@MOadU3d3TM/;dLmeg?H94Sjp/$M`YooAJ2lIPt9%SlFX~>
-endstream
-endobj
-10 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 9 0 R
->>
-endobj
-11 0 obj
-<< /Length 3625 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gat=pl'!AO&]MNR?dW8Ah#PVEWCj1r\[H]o!-@0DJ8h!q!>kkWF(9:im::-ZV))$pbtDN\D8a(oQWhOZ:F5](rlJr"nIVTP*U\FKA3.Bt,T\</(CtWqCFP$BQ`t?"E<!c5mAHS'jeGf8m2O@]YGSnZh`Q>cg#8L>rL7GbR:UPuQr7%f``GA"MrkOnAsl"=ML"An:6X*#._o:eW*(n)KJR,*(SgLXJ2tX]-cM$^VUTi#0[gg"WgLoQPT!&B)/E>e`QW4se9D!JV\2m,bh:7*)E3^5b;P,e<QrG*<#W4GF%p(I'XP<;;WA6peeiF*bj&e4NNWH.AICrXTecGa<bd!a@*YRMl;63i9W@PVJ=0&tFWGerXg^p_9n8YoYj+8kF>Kc5[fC$a+mM,\!b]s=7\fKjJ2tTQkW3hGAkJ'O4O.3_/Sr!.\bi;Qpb'?-mA0'0]72;imfCX16;_kR]DJMSpccJuQ8#:!Phl::C&@s=c8fFsLU+OA.ZGM[R'A1_'=P]/Rprob1TBn7"PUAi"Wgs(8rZ%Yd)LelnF/24CA\s#=s(0m*RK-&\5M??#h0ctjTl[<'Xs0edJ,3n[8(O`!P=%"f9[4KC&AEk2HFX65YGn3rXM140=KZO*bBh!V=>'!g6f-VoffA'p]uF/DJXl0$:CZ0`sC2KZ+@_/AR@2bj.?UanRDsn;]$uAre3TV6aeu*l#e1ANIN2"`fVjW;dlWSp^[FC/D1)/'cp\\nQuFQGd?>s1.pSkjp5p1?WPsA7VNDm+l(),'fZRW=)&:*,M^;2'fZ^[=)&:j7_"FJ.r]B9Y1+T^JoD[$<npD>Bb7`^\<KKF<c*Q23QKcU[8WYdj36;uXf_(P1KS<&G;RUhD%,/+O#(jR#'$>VDYD@V\A'h$C(Riugh-S&Kj-Z\V8at)$/mdhBIhm"R4C.N40"LgD9U`A2u4MtqnH$]\>)*qF5+C8(%1`V=(r4i<%"*g=L])`pGlRS#c%ZEOnIJ?\/"H,b`s*b7FlBmjAreTo/KAPiZd]tol;Rq7rd[_pF)71EKTqKg:7ZQdec(')Q0*ep"MO=%JDg+Po@S0eo,?h2V@1H=)&9_>/-'#gL-Yk>ik9l6Ip)@lS`tee\3X`AGnF#0)EUkqmr;Zp"T8QpjYE0noZr9laQD,EHD!dmH^]k+l()hD=7D(I9k-nop_<)(>KMq)tR%`pRimS=pVV-F[u4PRB(aAKq>dDF[t)&0N\._3iZ9*D1(.Op)EV1L/Jst=%Dq@\W*dS_L@-Jg=OkP]jbm>lgSc,H+IkqC0t%4onp;>Y<0UMK=T^fePX$6\ZN%s_L>u:BB/=CW*V41pq"*1(@M'4DX6W:cp'><pq"*1`pp]GW7CaU1s@Dm285*B([f'9]ZSj&ToWcfnTFK:pq3@$T^H<;>oMikjr.Ss>Xs4>H"AjhMpt>alY)es?cV3.HsIZQ,N]nO8'gM"=4__oHsIZY1GIGU3oW3sd<1uPIbf[Y,O=ZO$g351odVlsFi3"Z>iY.+lf^j*EAm]:'@I\uY9U3Fs'E^um+4tQ]X#83\9L6LY$\MB2r$o4Y46YANaNs@Y9UA\2pB%\bqW0tYARe+c<R>7>kS'@qJZ)ZaCLFaFh.Fl>9A@amYC8G55;M:^RDVGAed'Bri!B`(-V]<@MD!0&8NT8/;TiD1*B2C<rc^':FLia-WUY3;W4q^ENV?#F>bfX7&9kpF4-r";aL^WWGm.j+NYj?l/t.YA:TmOVe6!MU<b6iI&B7nKHpY<'u'/s0s<G[C#V4NlX=7^7cB7*Z)3VYIIEQ8r\H$X!"bKsNI.Q455[j8aXFe+&Eab%W&hVE4oM@T'LlAP-`.fVW&hV%4ThEX)#9)\)!M]kWma&Z1E];D;5_)?doO@3W_R_=<i%M@'K_H:MmVWWdpNDKWA&@N40d-['LaC]CUm=[p%+`aS@=4Vd9Xq\_C0]r6jaBmW&_C%3sJ*P0ZnQ#0u^ARRZlR`6Rf):Ob1;(hq?gJPf!,R0lE-OOW\g@GJC:1"i+?]>/Db)Nk8LEKf9!@Thd(PNk8LEKeEJF\V)GJ:+)J@Lf33T!7BHbm-]p,!Ot6YL0SS#Ap8`($Gb2S89)(qRaX?_1jDKhnFkn\Q#`ED3PDabrNB'*]^n+d`_](>=kl@o"b&YnmADmZd$aG/Q^m[3%9eWm@s%:5TdK(:'WsL[o1s'X)P^g3$oN$[T^_S^W72ZTK4h,S49U@RcPa<+UG4e8cVP:$#R\m^L.[HQ8U,uYfL&KF!qGbPNLq=i'7:&mYF+qJXiY78cJS(eRsh13*;8XoP:DR>!ITWjpd7m1W\[Uh+K+18![9&ZSJ`n7hEmk^";)?VcO?'WpB]:0+G.H?R\<X>7gRU4+bIQXR\<VhFJEZ-g,)2ofLPC,V(oP*aA<P+#RXdML.[Gt,#FJ[VL3J=)5Zjr"DVBX6/d@;:oWt;!]A)UT^Hs&1u:Tm-6*WI]hXj4Y7RYS7g*t<;l0#"!,<_k6/Cj+Bcoq8D+Z"NH^uXGh]bl1PR-P\Vb.'%M.Eq*5oga5$C)OE6_GbY&_(5T=#+;Uj7`i/,US+(/Edfu2;Uir-8Z=ai<E@eT17iO!7^'V@QM`kj[#^GE]_<0-UKkqi5P=\M%9j4rJ4GEQ=u`G&pQSaeV'hjNqtQ`^+5qbl/kTt;]`XkB!-Pl'I-j(Qn(%MM]=TjhAaE>Vl6pfC/PacOe\2dgS9S>Z/Xr3)F$]apAIk,2ffk:hB:q=q$Q9<QUnB*??a2M)Q0qbPIYt('RT"cqcos`>i\"[o0TF'Nc`(%)T5(iF#L4e@dgttJ1EL5Mk&t;\Z1..Fhj7\`'kHFNE.LfQL2>0RqQr=D]7T'FHtjF@m47WL=/'CN6GoRY__V4cPNb4+>,FAD8md&@m481;M2L#I'tbf\;pB4j[p!A,2]Ru>/YR-k:9VK&/Ub\2Jf3H\a-'>pbW%0@>gfH@\knVWBagna]l]+(Fu?P)$"FC(.$as:hbG=h/)-rY.NL?NR9Bs1"8TDK#0O/Ti)!*Y$t<GESXqrBn4ftD"&W$SG&>NNe(WjO_j_8/tBWK2P`/nO$HG5+t+F'c4>9YT2llg>nn$fB]ZiXQ'=8iiD&6+DGI277T=SkOqOr.OSb`g-@o#!6^dQ<_!A$k/eKkj-EskoFcj3qJO,(HRfo%'Q_"FeS\TuH2484n=R'0U*cQ6'K+<l!#qYa%*tPmH"Q/uP/9>Y69>*u""0Mr=d.>s&7S_=T<?Z1+WI<qf+Y;U@5L,UWRWhq"6_H>gV&(cJ98BY_f_B%tF);!%]jIH!&$er<\KHg/8RNE#<m4g6^iD^f<Kk3RIO:>j.Y6^?07P\--Eu;&KtY<udKuutga7S(0-&cjNi,HV1NJ,A8RSC)kESeMPYVjn9jjgl9.'hE8mo$#&?\`8V>#lm"0P7(Bn=!*S%qYb(In[7WBjeQq_]P`Y4QUh4?TgQIH1"A9l&m[&4TpFI,;`Q)3%.(QLA(J_h\\)k+-:.f^OVSF%m.V>Ar>G6#$5uJXRQJ:rfBC6<+Lgco"Oe_hdXBpfFW@@0sNBBlb,2iV^`$S\p1HbJ[YL_hdV\6s$P@+>0sUC_S+s].'*q2LJT4F%m>nXCD]FYU55Nhl_fF7"o!8lml.0&9Vms\+`\t#E)-F\G~>
-endstream
-endobj
-12 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 11 0 R
->>
-endobj
-13 0 obj
-<< /Length 1495 /Filter [ /ASCII85Decode /FlateDecode ]
- >>
-stream
-Gat%e6#YO:&4Z-f'`nFNG*'!T7j=r);VSgQ,.A\Q*a85ECc>(H)@>c+9oufu4l[f^3$X(O#[b5&oKA>r%%k$GqigJlY&i1HDZA_7G/'ZZcLR%^U,=BQ0#lc#0m<H[m[)C@*kVlMn'AR`I8#%-l/T,<f5CW\/q\2c*8m>CdA_d(b8%&cB&YK_)\unqBH]F-n,X[*I"tZ40:U!a-N"5_4l;qbM!_NP-N")[*LSW7`:J^<HBZ!6R#(+\Tj^W,lkel>D1.Wm@IaGM-GE8W5[?1Q9OOe$THT_f$L#hF/JG8fi]nh"$ZQhaQ]Obr@J0\cpa5q@h).I"$!&?G4sCNePDM^9Z>T:gf(85tPqi(u!*G^a/GbI)&RS*c[`g`23cc/62G#TlLFP&3!%)>K/""i1/2NjtbWmLC_8H^nAsO<=JCu:`HGL$7bVJ3kJ4Y-L:,)3qR@.X+Nr[WT1F0e1c-.s'=bZ+WE3CTj\qGFDGL7[6)6XXN1'NEL'q1h-`XMuLZG9;H6o23op^)L$?XP9eUD[6Ig`fRk$k2NmTk24_!32<8Tl=Y3Td&MK!`dCY:q/AnBUSAlJLY5=.,5as[*1KP:h:(EKptGaQ5T-'W3QV^Nm5p+iu\E(XarCTbs>l&7A)/DfJGMlOhn%qZd5&Op4c:_eVK/K&a2h,2U,5H1B'b9arJ(e%5T!Tk.osq&[&DEju*W+XR1Sp[jKmuWsljLC*.A^_(3YQ>\+MkD:ijFg*1d5CKu=r]2p7?Y8!3om^'T_N/%[<M$-2lEMtf[WJl[]m0t:]PtNeI4p\[YY$?Q+GsJl3-^_M_*cII_M[JGnU[[-XQC&bs4GN@5(W`#FV1Q8&Mb9R/&CoKTjsmQB0"fqNXuM@_6Ae=7"`rW32fm0$M/9:cB!/EIju1hR4I%#o4^TKPb_6Q:1KPPi&Cdeg@sCeR+m4+d-PI.[<Kb0tpb6XS)C"3k!3-LGF2bTu<Fl#X5a>b3[(1WR#&h)+E4'6G5FT,\1*Y."<g)DDm&ZVU,Qh2i/'7:SGo^\BJEC!-#&dkn>U:7F/e.QI<p\6MhKO<.RXS3R'+M?5Q+>$nQj`Ap]tN0M<h;%qelCi^cX?1DKhG!a"q@t_Q+>$nG%h35;/`6";0rKVd.:8/_-FL1108eA:m:R?X$)*GYcQ/UjV^G1X"mb%#'43UcWo]P6d8so=*Y!kiP(GbdPHWHB4S19%-GET,BK\o<58CQ>lF=cg;,FnRB&FPRV1_"b_?!QF+n7'oqaTgQ"_oghL@=_*+r+@$_NifAV7Ot^Wp)H_-Ed3C>WDOm&tK&PeKH6rASe_D_N"$f?=uD5ul7Q>icpKKh_-eIRMmKW-YD)\]QjugT^^,i<nJ8M"F:+)pE0QIm;2an-t8LI_EDVb;V3TfULC&c^-bDFa[MV\$(jJ5Hauhrc!+-F`V\MF1f&Smm`'YB4qe0^:eg">W\K/^]/I>/0EO>qa\iMQcF<n#B.pAVmFE4MRRYdDYGM#!>>4h*r~>
-endstream
-endobj
-14 0 obj
-<< /Type /Page
-/Parent 1 0 R
-/MediaBox [ 0 0 595 842 ]
-/Resources 3 0 R
-/Contents 13 0 R
->>
-endobj
-15 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F14
-/BaseFont /ZapfDingbats >>
-endobj
-16 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F5
-/BaseFont /Times-Roman
-/Encoding /WinAnsiEncoding >>
-endobj
-17 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F13
-/BaseFont /Symbol >>
-endobj
-18 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F1
-/BaseFont /Helvetica
-/Encoding /WinAnsiEncoding >>
-endobj
-19 0 obj
-<< /Type /Font
-/Subtype /Type1
-/Name /F9
-/BaseFont /Courier
-/Encoding /WinAnsiEncoding >>
-endobj
-1 0 obj
-<< /Type /Pages
-/Count 5
-/Kids [6 0 R 8 0 R 10 0 R 12 0 R 14 0 R ] >>
-endobj
-2 0 obj
-<< /Type /Catalog
-/Pages 1 0 R
- >>
-endobj
-3 0 obj
-<<
-/Font << /F5 16 0 R /F14 15 0 R /F13 17 0 R /F1 18 0 R /F9 19 0 R >>
-/ProcSet [ /PDF /ImageB /ImageC /Text ] >>
-endobj
-xref
-0 20
-0000000000 65535 f
-0000016170 00000 n
-0000016255 00000 n
-0000016305 00000 n
-0000000015 00000 n
-0000000071 00000 n
-0000002919 00000 n
-0000003025 00000 n
-0000006052 00000 n
-0000006158 00000 n
-0000010053 00000 n
-0000010160 00000 n
-0000013878 00000 n
-0000013986 00000 n
-0000015574 00000 n
-0000015682 00000 n
-0000015767 00000 n
-0000015877 00000 n
-0000015956 00000 n
-0000016064 00000 n
-trailer
-<<
-/Size 20
-/Root 2 0 R
-/Info 4 0 R
->>
-startxref
-16438
-%%EOF
diff --git a/src/documentation/content/xdocs/fo/fonts.pdf b/src/documentation/content/xdocs/fo/fonts.pdf
new file mode 100644
index 000000000..5c84a41b2
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/fonts.pdf
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/size.fo b/src/documentation/content/xdocs/fo/size.fo
index 225adb491..1de6b0245 100644
--- a/src/documentation/content/xdocs/fo/size.fo
+++ b/src/documentation/content/xdocs/fo/size.fo
@@ -19,19 +19,18 @@
<fo:root font-family="Times Roman" font-size="12pt" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
- <fo:simple-page-master
- margin-right="1.5cm"
- margin-left="1.5cm"
- margin-bottom="2cm"
- margin-top="1cm"
- page-width="21cm"
- page-height="29.7cm"
- master-name="left">
- <fo:region-before extent="0.5cm"/>
- <fo:region-body margin-top="0.5cm" margin-bottom="1.7cm"/>
- <fo:region-after extent="1.5cm"/>
- </fo:simple-page-master>
-
+ <fo:simple-page-master
+ margin-right="1.5cm"
+ margin-left="1.5cm"
+ margin-bottom="2cm"
+ margin-top="1cm"
+ page-width="21cm"
+ page-height="29.7cm"
+ master-name="left">
+ <fo:region-body margin-top="0.5cm" margin-bottom="1.7cm"/>
+ <fo:region-before extent="0.5cm"/>
+ <fo:region-after extent="1.5cm"/>
+ </fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence id="N2528" master-reference="left">
diff --git a/src/documentation/content/xdocs/fo/size.fo.pdf b/src/documentation/content/xdocs/fo/size.fo.pdf
deleted file mode 100644
index 177160580..000000000
--- a/src/documentation/content/xdocs/fo/size.fo.pdf
+++ /dev/null
Binary files differ
diff --git a/src/documentation/content/xdocs/fo/size.pdf b/src/documentation/content/xdocs/fo/size.pdf
new file mode 100644
index 000000000..add8fe871
--- /dev/null
+++ b/src/documentation/content/xdocs/fo/size.pdf
Binary files differ
diff --git a/src/documentation/content/xdocs/gethelp.xml b/src/documentation/content/xdocs/gethelp.xml
index 4369362be..f94bf0544 100644
--- a/src/documentation/content/xdocs/gethelp.xml
+++ b/src/documentation/content/xdocs/gethelp.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Getting Help</title>
diff --git a/src/documentation/content/xdocs/index.xml b/src/documentation/content/xdocs/index.xml
index ec9084a50..8a95934e3 100644
--- a/src/documentation/content/xdocs/index.xml
+++ b/src/documentation/content/xdocs/index.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP</title>
@@ -25,21 +25,22 @@
<body>
<section id="intro">
<title>Introduction</title>
- <p>Apacheâ„¢ FOP (Formatting Objects Processor) is a print formatter driven by XSL
+ <p>
+ Apacheâ„¢ FOP (Formatting Objects Processor) is a print formatter driven by XSL
formatting objects (XSL-FO) and an output independent formatter. It is a Java
application that reads a formatting object (FO) tree and renders the resulting
- pages to a specified output. <link href="1.1/output.html">Output formats</link>
+ pages to a specified output. <link href="1.1rc1/output.html">Output formats</link>
currently supported include PDF, PS, PCL, AFP, XML (area tree representation),
Print, AWT and PNG, and to a lesser extent, RTF and TXT. The primary output target is PDF.
</p>
- <p>The Apacheâ„¢ FOP project is part of the <a href="http://www.apache.org">Apacheâ„¢</a>
- Software Foundation, which is a wider community of users and developers of open
- source projects.
+ <p>
+ The Apacheâ„¢ FOP project is part of the <link href="http://www.apache.org">Apacheâ„¢</link>
+ Software Foundation, which is a wider community of users and developers of open source projects.
+ </p>
+ <figure width="480" height="260" src="images/document.jpg" alt="Render Diagram" />
+ <p>
+ A release candidate (rc1) of the latest version of FOP is available at <link href="1.1rc1/">FOP 1.1rc1</link>.
</p>
- <figure width="480" height="260" src="images/document.jpg" alt="Render Diagram" />
- <p>
- A stable release of the latest version of FOP is available at <link href="1.1/">FOP 1.1</link>.
- </p>
<p>
Support for each of the standard's objects and properties is detailed in <link href="compliance.html">FOP Compliance</link>.
<link href="download.html">Download</link> options include a precompiled version, source code, and many example files to get you started. <link href="resources.html">Resources</link> include links to XSL-FO introductions and many other useful references. A checklist for <link href="gethelp.html">Getting Help</link> will guide you toward maximizing the usefulness of FOP.
diff --git a/src/documentation/content/xdocs/knownissues.xml b/src/documentation/content/xdocs/knownissues.xml
index 7c63fb69d..d916f0171 100644
--- a/src/documentation/content/xdocs/knownissues.xml
+++ b/src/documentation/content/xdocs/knownissues.xml
@@ -16,7 +16,14 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd" [
+<!ATTLIST document
+ xmlns:xi CDATA #IMPLIED>
+<!ELEMENT xi:include EMPTY>
+<!ATTLIST xi:include
+ href CDATA #IMPLIED>
+<!ENTITY % local.sections "|xi:include">
+]>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<title>Apacheâ„¢ FOP: Known Issues</title>
@@ -30,27 +37,25 @@
from data in FOP's code repository (Trunk) and may not exactly represent the list of issues in
the latest release.
</p>
- <note>
- <p>
- For additional information on known issues in Apache FOP, please have a look at the following pages, too:
- </p>
- <ul>
- <li><a href="bugs.html">the bug list in Bugzilla</a></li>
- <li><a href="http://wiki.apache.org/xmlgraphics-fop/FOPProjectTasks">the task list in the Wiki</a></li>
- </ul>
- </note>
<p>
Apacheâ„¢ FOP has an extensive automated testing infrastructure. Parts of this infrastructure are several
sets of test cases. When a test case is listed in disabled-testcases.xml it is disabled in the JUnit
tests during the normal build process. This indicates a problem in the current codebase. When a bug is
fixed or a missing feature is added the entry for the relevant test case(s) are removed.
</p>
+ <p>
+ For additional information on known issues in Apache FOP, please have a look at the following pages, too:
+ </p>
+ <ul>
+ <li><link href="bugs.html">the bug list in Bugzilla</link></li>
+ <li><link href="http://wiki.apache.org/xmlgraphics-fop/FOPProjectTasks">the task list in the Wiki</link></li>
+ </ul>
<section>
<title>FO Tree</title>
<p>
This section lists currently disabled test cases in the test suite for the FO tree tests.
The data for this section comes from
- <a href="http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/test/fotree/disabled-testcases.xml">test/fotree/disabled-testcases.xml</a>.
+ <link href="http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/test/fotree/disabled-testcases.xml">test/fotree/disabled-testcases.xml</link>.
</p>
<xi:include href="cocoon://knownissues-raw-fotree.xml#xpointer(/document/body/*)"/>
</section>
@@ -59,7 +64,7 @@
<p>
This section lists currently disabled test cases in the test suite for the layout engine tests.
The data for this section comes from
- <a href="http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml">test/layoutengine/disabled-testcases.xml</a>.
+ <link href="http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk/test/layoutengine/disabled-testcases.xml">test/layoutengine/disabled-testcases.xml</link>.
</p>
<xi:include href="cocoon://knownissues-raw-layoutengine.xml#xpointer(/document/body/*)"/>
</section>
diff --git a/src/documentation/content/xdocs/license.xml b/src/documentation/content/xdocs/license.xml
index b0cf05c5d..95e8b455a 100644
--- a/src/documentation/content/xdocs/license.xml
+++ b/src/documentation/content/xdocs/license.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP License</title>
@@ -27,7 +27,7 @@
<title>License</title>
<p>
All new Apacheâ„¢ FOP releases will be licensed under the <strong>Apacheâ„¢ License, version 2.0</strong>.
- Releases until version 0.20.5 are released unter the Apacheâ„¢ License, version 1.1.
+ Releases up through version 0.20.5 were released under the Apacheâ„¢ License, version 1.1.
</p>
<p>
To inspect the license terms please consult the LICENSE and NOTICE files in the root
diff --git a/src/documentation/content/xdocs/maillist.xml b/src/documentation/content/xdocs/maillist.xml
index e58778c32..b24166462 100644
--- a/src/documentation/content/xdocs/maillist.xml
+++ b/src/documentation/content/xdocs/maillist.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Mailing List Resources</title>
@@ -83,7 +83,7 @@ If you are using Microsoft Outlook, this setting can be found at the "Mail Forma
source, or other semantic XML? If so, the question is <em>almost certainly not
appropriate to this list</em>. In general, the only input documents that are
appropriate on this list are XSL-FO snippets. See <link
- href="1.1/running.html#check-input">Running Xalan</link> for instructions about capturing the XSL-FO document that is actually submitted to FOP. If you haven't examined the XSL-FO document yourself, then you are not yet prepared to formulate a FOP-specific question.</li>
+ href="1.1rc1/running.html#check-input">Running Xalan</link> for instructions about capturing the XSL-FO document that is actually submitted to FOP. If you haven't examined the XSL-FO document yourself, then you are not yet prepared to formulate a FOP-specific question.</li>
<li>If you are providing one or more XSL-FO snippets:
<ul>
<li>Have you reduced them to the shortest possible complete, <strong>self-contained</strong> document that demonstrates the problem? Please do so.</li>
diff --git a/src/documentation/content/xdocs/news-data.xml b/src/documentation/content/xdocs/news-data.xml
index b76c7e2da..4b8956cd1 100644
--- a/src/documentation/content/xdocs/news-data.xml
+++ b/src/documentation/content/xdocs/news-data.xml
@@ -17,12 +17,12 @@
-->
<!-- $Id$ -->
<news>
- <item date="2012-DD-MM" title="Apacheâ„¢ FOP 1.1 Released">
+ <item date="2012-07-02" title="Apacheâ„¢ FOP 1.1rc1 Available">
<p>
- The Apacheâ„¢ FOP team is delighted to present you a production grade
+ This is a candidate release for an upcoming FOP Version 1.1 (stable) release.
release of the new FOP codebase. This release
- contains bug fixes and new features. See the <a
- href="1.1/releaseNotes_1.1.html">Release Notes</a> for a list of
+ contains bug fixes and new features. See
+ <a href="1.1rc1/releaseNotes_1.1rc1.html">Release Notes</a> for a list of
the most important changes.
</p>
</item>
diff --git a/src/documentation/content/xdocs/news.xml b/src/documentation/content/xdocs/news.xml
index 978314977..688558226 100644
--- a/src/documentation/content/xdocs/news.xml
+++ b/src/documentation/content/xdocs/news.xml
@@ -16,17 +16,24 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
-<document>
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd" [
+<!ATTLIST document
+ xmlns:xi CDATA #IMPLIED>
+<!ELEMENT xi:include EMPTY>
+<!ATTLIST xi:include
+ href CDATA #IMPLIED>
+<!ENTITY % local.sections "|xi:include">
+]>
+<document xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<title>Apacheâ„¢ FOP News</title>
<version>$Revision$</version>
</header>
<body>
<p>
- RSS Feed: <a href="subproject-news-feed.rss"><img src="feed-icon-14x14.png" alt="Subproject News Feed"/></a>
+ RSS Feed: <link href="subproject-news-feed.rss"><img src="feed-icon-14x14.png" alt="Subproject News Feed"/></link>
</p>
- <xi:include href="cocoon://subproject-news-document.xml#xpointer(/document/body/*)" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="cocoon://subproject-news-document.xml#xpointer(/document/body/*)"/>
</body>
</document>
diff --git a/src/documentation/content/xdocs/quickstartguide.xml b/src/documentation/content/xdocs/quickstartguide.xml
index ceb931248..3d369c08c 100644
--- a/src/documentation/content/xdocs/quickstartguide.xml
+++ b/src/documentation/content/xdocs/quickstartguide.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Quick Start Guide</title>
@@ -29,15 +29,15 @@
<p>The goal of this <strong>Quick Start Guide</strong> is to help novice users get Apache FOP up and running quickly. Typically, you'll need to:</p>
<ol>
<li><link href="download.html">Download FOP</link></li>
- <li><link href="1.1/compiling.html">Build FOP</link> (you can skip this step if you download the binary distribution!)</li>
- <li><link href="1.1/configuration.html">Configure FOP</link></li>
- <li><link href="1.1/running.html">Run FOP</link></li>
+ <li><link href="1.1rc1/compiling.html">Build FOP</link> (you can skip this step if you download the binary distribution!)</li>
+ <li><link href="1.1rc1/configuration.html">Configure FOP</link></li>
+ <li><link href="1.1rc1/running.html">Run FOP</link></li>
</ol>
<p>Here are some links to help you find out what FOP can do, as well as how and where to get help:</p>
<ul>
- <li><link href="1.1/embedding.html">Calling FOP from a Java Application</link></li>
- <li><link href="1.1/servlets.html">Using FOP in Servlets</link></li>
- <li><link href="1.1/anttask.html">Using FOP in an 'Ant' Build Script</link></li>
+ <li><link href="1.1rc1/embedding.html">Calling FOP from a Java Application</link></li>
+ <li><link href="1.1rc1/servlets.html">Using FOP in Servlets</link></li>
+ <li><link href="1.1rc1/anttask.html">Using FOP in an 'Ant' Build Script</link></li>
<li><link href="compliance.html" title="FOP Compliance">XSL-FO Compliance</link> (what FOP supports and what it doesn't)</li>
<li><link href="faq.html">FAQs</link></li>
<li><link href="gethelp.html">Getting Help</link></li>
@@ -45,7 +45,7 @@
</ul>
<p>
Once you've familiarized yourself with the basics, you can get more detailed information,
- in the detailed FOP <link href="1.1/index.html">product documentation</link>.
+ in the detailed FOP <link href="1.1rc1/index.html">product documentation</link>.
</p>
</section>
diff --git a/src/documentation/content/xdocs/resources.xml b/src/documentation/content/xdocs/resources.xml
index 020936c96..d976f9859 100644
--- a/src/documentation/content/xdocs/resources.xml
+++ b/src/documentation/content/xdocs/resources.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<!-- FOP Relevant Specifications and links -->
<document>
<header>
diff --git a/src/documentation/content/xdocs/site.xml b/src/documentation/content/xdocs/site.xml
index 4c55beb2b..c750f9556 100644
--- a/src/documentation/content/xdocs/site.xml
+++ b/src/documentation/content/xdocs/site.xml
@@ -65,12 +65,12 @@
<upgrading label="Upgrading" href="upgrading.html"/>
<using label="Using Apacheâ„¢ FOP">
+ <ant label="Ant Task" href="anttask.html"/>
<build label="Build" href="compiling.html"/>
<config label="Configure" href="configuration.html"/>
- <run label="Run" href="running.html"/>
<embed label="Embed" href="embedding.html"/>
+ <run label="Run" href="running.html"/>
<servlet label="Servlets" href="servlets.html"/>
- <ant label="Ant Task" href="anttask.html"/>
</using>
<features label="Features">
@@ -94,22 +94,22 @@
-->
<!--
- BEGIN Version 1.1 documentation tab
+ BEGIN Version 1.1rc1 documentation tab
-->
- <trunk label="Apacheâ„¢ FOP 1.1" href="1.1/" tab="stableversion">
+ <trunk label="Apacheâ„¢ FOP 1.1rc1" href="1.1rc1/" tab="stableversion">
<about label="About" href="index.html"/>
- <release label="Release Notes" href="releaseNotes_1.1.html"/>
- <changes label="Changes (1.1)" href="changes_1.1.html"/>
+ <release label="Release Notes" href="releaseNotes_1.1rc1.html"/>
+ <changes label="Changes (1.1rc1)" href="changes_1.1rc1.html"/>
<knownissues label="Known Issues" href="knownissues_overview.html"/>
<upgrading label="Upgrading" href="upgrading.html"/>
<using label="Using Apacheâ„¢ FOP">
+ <ant label="Ant Task" href="anttask.html"/>
<build label="Build" href="compiling.html"/>
<config label="Configure" href="configuration.html"/>
- <run label="Run" href="running.html"/>
<embed label="Embed" href="embedding.html"/>
+ <run label="Run" href="running.html"/>
<servlet label="Servlets" href="servlets.html"/>
- <ant label="Ant Task" href="anttask.html"/>
</using>
<features label="Features">
@@ -130,7 +130,7 @@
</trunk>
<!--
- END Version 1.1 documentation tab
+ END Version 1.1rc1 documentation tab
-->
<!--
@@ -141,12 +141,12 @@
<upgrading label="Upgrading" href="upgrading.html"/>
<using label="Using Apacheâ„¢ FOP">
+ <ant label="Ant Task" href="anttask.html"/>
<build label="Build" href="compiling.html"/>
<config label="Configure" href="configuration.html"/>
- <run label="Run" href="running.html"/>
<embed label="Embed" href="embedding.html"/>
+ <run label="Run" href="running.html"/>
<servlet label="Servlets" href="servlets.html"/>
- <ant label="Ant Task" href="anttask.html"/>
</using>
<features label="Features">
diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml
index 8b1f16099..1b6f1dc2b 100644
--- a/src/documentation/content/xdocs/status.xml
+++ b/src/documentation/content/xdocs/status.xml
@@ -27,17 +27,17 @@
<body>
<section>
<title>Status</title>
- <p>Last updated DD Month 2012.</p>
+ <p>Last updated 02 July 2012.</p>
<p>
- Apacheâ„¢ FOP version 1.1 was released on DD Month 2012.
+ Apacheâ„¢ FOP version 1.1rc1 (candidate) was released on 02 July 2012.
</p>
</section>
<section>
<title>Development Status</title>
<p>
- The FOP code base is gradually evolving, from version 0.90
- released on 22 November 2005, to version 1.1 released on DD Month 2012.
- Further releases in the 1.x series are expected.
+ The FOP code base is gradually evolving, from Version 0.90,
+ released on 22 November 2005, to Version 1.1, expected to be released during
+ the Summer of 2012. Further releases in the 1.x series and beyond are expected.
</p>
<p>
FOP releases prior to version 0.90 were based on a different
diff --git a/src/documentation/content/xdocs/tabs.xml b/src/documentation/content/xdocs/tabs.xml
index e14d9409e..27e99b67c 100644
--- a/src/documentation/content/xdocs/tabs.xml
+++ b/src/documentation/content/xdocs/tabs.xml
@@ -22,7 +22,7 @@
<tabs software="FOP" title="FOP" copyright="@year@ The Apache Software Foundation" xmlns:xlink="http://www.w3.org/1999/xlink">
<tab label="Home" dir=""/>
<tab label="Version 1.0" dir="1.0/"/>
- <tab label="Version 1.1" dir="1.1/"/>
+ <tab label="Version 1.1rc1" dir="1.1rc1/"/>
<tab label="FOP Trunk" dir="trunk/"/>
<tab label="Development" dir="dev/"/>
</tabs>
diff --git a/src/documentation/content/xdocs/team.xml b/src/documentation/content/xdocs/team.xml
index c5d83443c..4eb2da7b3 100644
--- a/src/documentation/content/xdocs/team.xml
+++ b/src/documentation/content/xdocs/team.xml
@@ -16,7 +16,7 @@
limitations under the License.
-->
<!-- $Id$ -->
-<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
<document>
<header>
<title>Apacheâ„¢ FOP: Development Team</title>
@@ -44,7 +44,7 @@
is an XP/Agile practitioner with interests in open source content management and electronic
document generation. He is a UK expat now residing in Singapore.</li>
<li id="ad"><link href="mailto:adelmelle@apache.org">Andreas Delmelle</link> (AD)</li>
- <li id="pjfh"> <a href="mailto:phancock.at.apache.org">Peter Hancock</a>
+ <li id="pjfh"> <link href="mailto:phancock.at.apache.org">Peter Hancock</link>
(PH) is a Java developer from England.</li>
<li id="vh"><link href="mailto:vhennebert@apache.org">Vincent Hennebert</link>
(VH), a Java developer from France; with an interest in typography, and in using
diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml
index b30a091a5..563ae9647 100644
--- a/src/documentation/content/xdocs/trunk/configuration.xml
+++ b/src/documentation/content/xdocs/trunk/configuration.xml
@@ -281,6 +281,24 @@
treated as zero penalty in most cases. For more details on the image loading framework,
please consult the documentation there.
</p>
+ <p>
+ The ImageLoaderPNG and ImageLoaderRawPNG have a hard-coded penalty of 1000 and as such the
+ ImageLoaderImageIO image loader will be selected by default when loading PNGs unless
+ the latter is disabled by awarding a INFINITE penalty to it, or one of the former two is
+ promoted by awarding a strong negative penalty (say, -10000) to it.
+ </p>
+ <source><![CDATA[<fop version="1.0">
+ [..]
+ <image-loading>
+ <penalty value="-10000"
+ class="org.apache.xmlgraphics.image.loader.impl.ImageLoaderRawPNG"/>
+ <penalty value="INFINITE"
+ class="org.apache.xmlgraphics.image.loader.impl.ImageLoaderPNG"/>
+ <penalty value="INFINITE"
+ class="org.apache.xmlgraphics.image.loader.impl.imageio.ImageLoaderImageIO"/>
+ </image-loading>
+ <renderers....
+</fop>]]></source>
</section>
<section id="renderers">
<title>Renderer configuration</title>
diff --git a/src/documentation/content/xdocs/trunk/fonts.xml b/src/documentation/content/xdocs/trunk/fonts.xml
index f3481607d..ba607e40b 100644
--- a/src/documentation/content/xdocs/trunk/fonts.xml
+++ b/src/documentation/content/xdocs/trunk/fonts.xml
@@ -493,10 +493,10 @@
Various notes related to embedded fonts:
</p>
<ul>
- <li>The PostScript renderer does not yet support TrueType fonts, but can embed Type 1 fonts.</li>
- <li>The font is simply embedded into the PDF file, it is not converted.</li>
- <li>When FOP embeds a font, it adds a prefix to the fontname to ensure that the name will not match the fontname of an installed font.
- This is helpful with older versions of Acrobat Reader that preferred installed fonts over embedded fonts.</li>
+ <li>The font is simply embedded into the output file, it is not converted.</li>
+ <li>When FOP embeds a font in a PDF file, it adds a prefix to the fontname to ensure that
+ the name will not match the fontname of an installed font. This is helpful with older
+ versions of Acrobat Reader that preferred installed fonts over embedded fonts.</li>
<li>When embedding PostScript fonts, the entire font is always embedded.</li>
<li>When embedding TrueType fonts (ttf) or TrueType Collections (ttc), a subset of the
original font, containing only the glyphs used, is embedded in the output document.
@@ -576,4 +576,4 @@
</p>
</section>
</body>
-</document> \ No newline at end of file
+</document>
diff --git a/src/documentation/content/xdocs/trunk/graphics.xml b/src/documentation/content/xdocs/trunk/graphics.xml
index b1653443a..eb05013b7 100644
--- a/src/documentation/content/xdocs/trunk/graphics.xml
+++ b/src/documentation/content/xdocs/trunk/graphics.xml
@@ -108,7 +108,7 @@
<tr>
<td><a href="#png">PNG</a> (Portable Network Graphic)</td>
<td>bitmap</td>
- <td/>
+ <td>(X)</td>
<td/>
<td>X</td>
</tr>
@@ -217,8 +217,8 @@
</tr>
<tr>
<td><a href="#png">PNG</a> (Portable Network Graphic)</td>
- <td>X</td>
- <td>X</td>
+ <td>X [2]</td>
+ <td>X [2]</td>
<td>X</td>
<td>X</td>
<td>X</td>
@@ -383,8 +383,11 @@
<section id="png">
<title>PNG</title>
<p>
- PNG images are supported through an Image&amp;nbsp;I/O codec. Transparency is supported but
- not guaranteed to work with every output format.
+ FOP native support of PNG only includes the variants with 8 bits per channel and without
+ interlacing. Native support requires using the ImageLoaderRawPNG image loader.
+ Support through a Image I/O codec can use either the internal XGC PNG codec or the JRE PNG
+ codec. The associated image loaders are, respectively, ImageLoaderPNG and ImageLoaderImageIO.
+ Transparency is supported but not guaranteed to work with every output format.
</p>
</section>
<section id="svg">
diff --git a/src/documentation/resources/stylesheets/known-issues2document.xsl b/src/documentation/resources/stylesheets/known-issues2document.xsl
index 8e10c35a2..ad0c4d70a 100644
--- a/src/documentation/resources/stylesheets/known-issues2document.xsl
+++ b/src/documentation/resources/stylesheets/known-issues2document.xsl
@@ -46,4 +46,10 @@
</li>
</xsl:template>
+ <xsl:template match="@*|*|text()|processing-instruction()|comment()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|*|text()|processing-instruction()|comment()"/>
+ </xsl:copy>
+ </xsl:template>
+
</xsl:stylesheet>
diff --git a/src/java/META-INF/services/org.apache.fop.render.ImageHandler b/src/java/META-INF/services/org.apache.fop.render.ImageHandler
index f9b890c8e..9066913ad 100644
--- a/src/java/META-INF/services/org.apache.fop.render.ImageHandler
+++ b/src/java/META-INF/services/org.apache.fop.render.ImageHandler
@@ -1,6 +1,7 @@
org.apache.fop.render.pdf.PDFImageHandlerGraphics2D
org.apache.fop.render.pdf.PDFImageHandlerRenderedImage
org.apache.fop.render.pdf.PDFImageHandlerRawJPEG
+org.apache.fop.render.pdf.PDFImageHandlerRawPNG
org.apache.fop.render.pdf.PDFImageHandlerRawCCITTFax
org.apache.fop.render.pdf.PDFImageHandlerSVG
org.apache.fop.render.java2d.Java2DImageHandlerRenderedImage
@@ -11,6 +12,7 @@ org.apache.fop.render.ps.PSImageHandlerRenderedImage
org.apache.fop.render.ps.PSImageHandlerEPS
org.apache.fop.render.ps.PSImageHandlerRawCCITTFax
org.apache.fop.render.ps.PSImageHandlerRawJPEG
+org.apache.fop.render.ps.PSImageHandlerRawPNG
org.apache.fop.render.ps.PSImageHandlerGraphics2D
org.apache.fop.render.ps.PSImageHandlerSVG
org.apache.fop.render.afp.AFPImageHandlerRenderedImage
diff --git a/src/java/org/apache/fop/accessibility/Accessibility.java b/src/java/org/apache/fop/accessibility/Accessibility.java
index c842cf43f..88ec6dbdd 100644
--- a/src/java/org/apache/fop/accessibility/Accessibility.java
+++ b/src/java/org/apache/fop/accessibility/Accessibility.java
@@ -28,6 +28,12 @@ public final class Accessibility {
/** Constant string for the rendering options key to enable accessibility features. */
public static final String ACCESSIBILITY = "accessibility";
+ /**
+ * The value to be set on the 'role' property for the element and its descendants to
+ * be considered as artifacts.
+ */
+ public static final String ROLE_ARTIFACT = "artifact";
+
private Accessibility() { }
}
diff --git a/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
index 47c227e9a..27469d6e0 100644
--- a/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
+++ b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
@@ -23,6 +23,7 @@ import java.util.Stack;
import org.xml.sax.SAXException;
+import org.apache.fop.accessibility.Accessibility;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.fo.DelegatingFOEventHandler;
import org.apache.fop.fo.FOEventHandler;
@@ -57,6 +58,8 @@ import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.Root;
import org.apache.fop.fo.pagination.StaticContent;
+import org.apache.fop.fo.properties.CommonAccessibility;
+import org.apache.fop.fo.properties.CommonAccessibilityHolder;
/**
* Allows to create the structure tree of an FO document, by converting FO
@@ -355,6 +358,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
@Override
public void startStatic(StaticContent staticContent) {
+ handleStartArtifact(staticContent);
converter.startStatic(staticContent);
super.startStatic(staticContent);
}
@@ -362,6 +366,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
@Override
public void endStatic(StaticContent statisContent) {
converter.endStatic(statisContent);
+ handleEndArtifact(statisContent);
super.endStatic(statisContent);
}
@@ -454,6 +459,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
@Override
public void startWrapper(Wrapper wrapper) {
+ handleStartArtifact(wrapper);
converter.startWrapper(wrapper);
super.startWrapper(wrapper);
}
@@ -461,6 +467,7 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
@Override
public void endWrapper(Wrapper wrapper) {
converter.endWrapper(wrapper);
+ handleEndArtifact(wrapper);
super.endWrapper(wrapper);
}
@@ -488,4 +495,22 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
super.endExternalDocument(document);
}
+ private void handleStartArtifact(CommonAccessibilityHolder fobj) {
+ if (isArtifact(fobj)) {
+ converters.push(converter);
+ converter = eventSwallower;
+ }
+ }
+
+ private void handleEndArtifact(CommonAccessibilityHolder fobj) {
+ if (isArtifact(fobj)) {
+ converter = converters.pop();
+ }
+ }
+
+ private boolean isArtifact(CommonAccessibilityHolder fobj) {
+ CommonAccessibility accessibility = fobj.getCommonAccessibility();
+ return Accessibility.ROLE_ARTIFACT.equalsIgnoreCase(accessibility.getRole());
+ }
+
}
diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java
index e9a269ac4..7172b0ee3 100644
--- a/src/java/org/apache/fop/afp/AFPGraphics2D.java
+++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java
@@ -67,7 +67,7 @@ import org.apache.fop.svg.NativeImageHandler;
/**
* This is a concrete implementation of {@link AbstractGraphics2D} (and
- * therefore of {@link Graphics2D}) which is able to generate GOCA byte
+ * therefore of {@link java.awt.Graphics2D}) which is able to generate GOCA byte
* codes.
*
* @see org.apache.xmlgraphics.java2d.AbstractGraphics2D
@@ -165,7 +165,7 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
}
/**
- * Returns the AFP resource manager associated with this {@link Graphics2D} instance.
+ * Returns the AFP resource manager associated with this {@link java.awt.Graphics2D} instance.
* @return the resource manager
*/
public AFPResourceManager getResourceManager() {
diff --git a/src/java/org/apache/fop/afp/modca/ImageObject.java b/src/java/org/apache/fop/afp/modca/ImageObject.java
index adb56e626..e42639248 100644
--- a/src/java/org/apache/fop/afp/modca/ImageObject.java
+++ b/src/java/org/apache/fop/afp/modca/ImageObject.java
@@ -119,7 +119,8 @@ public class ImageObject extends AbstractDataObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
- * @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
+ * @deprecated Use {@link org.apache.fop.afp.ioca.IDEStructureParameter#setColorModel(byte)}
+ * instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageSegment().setIDEColorModel(colorModel);
@@ -128,7 +129,8 @@ public class ImageObject extends AbstractDataObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
- * @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
+ * @deprecated Use {@link org.apache.fop.afp.ioca.IDEStructureParameter#setSubtractive(boolean)}
+ * instead.
*/
public void setSubtractive(boolean subtractive) {
getImageSegment().setSubtractive(subtractive);
diff --git a/src/java/org/apache/fop/afp/modca/PresentationTextData.java b/src/java/org/apache/fop/afp/modca/PresentationTextData.java
index b68131413..c0934b1e5 100644
--- a/src/java/org/apache/fop/afp/modca/PresentationTextData.java
+++ b/src/java/org/apache/fop/afp/modca/PresentationTextData.java
@@ -46,7 +46,7 @@ import org.apache.fop.afp.util.BinaryUtils;
* which signal an alternate mode of processing for the content of the current
* Presentation Text data.
* <p>
- * The content for this object can be created using {@link PtocaBuilder}.
+ * The content for this object can be created using {@link org.apache.fop.afp.ptoca.PtocaBuilder}.
*/
public class PresentationTextData extends AbstractAFPObject implements PtocaConstants {
diff --git a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java b/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
index f379546e2..2872976b6 100644
--- a/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
+++ b/src/java/org/apache/fop/afp/util/DefaultFOPResourceAccessor.java
@@ -44,7 +44,8 @@ public class DefaultFOPResourceAccessor extends SimpleResourceAccessor {
* 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 FontManager}'s base URI instead of the one on the {@link FopFactory}.
+ * 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)
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
index 665c1abf8..035b6f1a1 100644
--- a/src/java/org/apache/fop/apps/FOUserAgent.java
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -355,7 +355,7 @@ public class FOUserAgent {
/**
* Sets font base URL.
* @param fontBaseUrl font base URL
- * @deprecated Use {@link FontManager#setFontBaseURL(String)} instead.
+ * @deprecated Use {@link org.apache.fop.fonts.FontManager#setFontBaseURL(String)} instead.
*/
public void setFontBaseURL(String fontBaseUrl) {
try {
@@ -500,7 +500,8 @@ public class FOUserAgent {
/**
* Returns the font base URL.
* @return the font base URL
- * @deprecated Use {@link FontManager#getFontBaseURL()} instead. This method is not used by FOP.
+ * @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();
diff --git a/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java b/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
index 3b7c14b0e..6db6be726 100644
--- a/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
+++ b/src/java/org/apache/fop/complexscripts/fonts/GlyphPositioningTable.java
@@ -1783,9 +1783,9 @@ public class GlyphPositioningTable extends GlyphTable {
* Find device adjustment.
* @param fontSize the font size to search for
* @return an adjustment if font size matches an entry
- * @asf.todo at present, assumes that 1 device unit equals one point
*/
public int findAdjustment ( int fontSize ) {
+ // [TODO] at present, assumes that 1 device unit equals one point
int fs = fontSize / 1000;
if ( fs < startSize ) {
return 0;
diff --git a/src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java b/src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java
index a9110d378..9afb893b5 100644
--- a/src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java
+++ b/src/java/org/apache/fop/complexscripts/fonts/OTFAdvancedTypographicTableReader.java
@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.truetype.FontFileReader;
import org.apache.fop.fonts.truetype.TTFDirTabEntry;
import org.apache.fop.fonts.truetype.TTFFile;
+import org.apache.fop.fonts.truetype.TTFTableName;
// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
@@ -126,7 +127,7 @@ public final class OTFAdvancedTypographicTableReader {
return gpos;
}
- private void readLangSysTable(String tableTag, long langSysTable, String langSysTag) throws IOException {
+ private void readLangSysTable(TTFTableName tableTag, long langSysTable, String langSysTag) throws IOException {
in.seekSet(langSysTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " lang sys table: " + langSysTag );
@@ -168,7 +169,7 @@ public final class OTFAdvancedTypographicTableReader {
private static String defaultTag = "dflt";
- private void readScriptTable(String tableTag, long scriptTable, String scriptTag) throws IOException {
+ private void readScriptTable(TTFTableName tableTag, long scriptTable, String scriptTag) throws IOException {
in.seekSet(scriptTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " script table: " + scriptTag );
@@ -221,7 +222,7 @@ public final class OTFAdvancedTypographicTableReader {
seLanguages = null;
}
- private void readScriptList(String tableTag, long scriptList) throws IOException {
+ private void readScriptList(TTFTableName tableTag, long scriptList) throws IOException {
in.seekSet(scriptList);
// read script record count
int ns = in.readTTFUShort();
@@ -250,7 +251,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}
- private void readFeatureTable(String tableTag, long featureTable, String featureTag, int featureIndex) throws IOException {
+ private void readFeatureTable(TTFTableName tableTag, long featureTable, String featureTag, int featureIndex) throws IOException {
in.seekSet(featureTable);
if (log.isDebugEnabled()) {
log.debug(tableTag + " feature table: " + featureTag );
@@ -278,7 +279,7 @@ public final class OTFAdvancedTypographicTableReader {
seFeatures.put ( "f" + featureIndex, new Object[] { featureTag, lul } );
}
- private void readFeatureList(String tableTag, long featureList) throws IOException {
+ private void readFeatureList(TTFTableName tableTag, long featureList) throws IOException {
in.seekSet(featureList);
// read feature record count
int nf = in.readTTFUShort();
@@ -3144,9 +3145,9 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readLookupTable(String tableTag, int lookupSequence, long lookupTable) throws IOException {
- boolean isGSUB = tableTag.equals ( "GSUB" );
- boolean isGPOS = tableTag.equals ( "GPOS" );
+ private void readLookupTable(TTFTableName tableTag, int lookupSequence, long lookupTable) throws IOException {
+ boolean isGSUB = tableTag.equals ( TTFTableName.GSUB );
+ boolean isGPOS = tableTag.equals ( TTFTableName.GPOS );
in.seekSet(lookupTable);
// read lookup type
int lt = in.readTTFUShort();
@@ -3197,7 +3198,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}
- private void readLookupList(String tableTag, long lookupList) throws IOException {
+ private void readLookupList(TTFTableName tableTag, long lookupList) throws IOException {
in.seekSet(lookupList);
// read lookup record count
int nl = in.readTTFUShort();
@@ -3232,7 +3233,7 @@ public final class OTFAdvancedTypographicTableReader {
* @param lookupList offset to lookup list from beginning of font file
* @throws IOException In case of a I/O problem
*/
- private void readCommonLayoutTables(String tableTag, long scriptList, long featureList, long lookupList) throws IOException {
+ private void readCommonLayoutTables(TTFTableName tableTag, long scriptList, long featureList, long lookupList) throws IOException {
if ( scriptList > 0 ) {
readScriptList ( tableTag, scriptList );
}
@@ -3244,7 +3245,7 @@ public final class OTFAdvancedTypographicTableReader {
}
}
- private void readGDEFClassDefTable(String tableTag, int lookupSequence, long subtableOffset) throws IOException {
+ private void readGDEFClassDefTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// subtable is a bare class definition table
@@ -3256,7 +3257,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readGDEFAttachmentTable(String tableTag, int lookupSequence, long subtableOffset) throws IOException {
+ private void readGDEFAttachmentTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// read coverage offset
@@ -3274,7 +3275,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readGDEFLigatureCaretTable(String tableTag, int lookupSequence, long subtableOffset) throws IOException {
+ private void readGDEFLigatureCaretTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// read coverage offset
@@ -3304,7 +3305,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readGDEFMarkAttachmentTable(String tableTag, int lookupSequence, long subtableOffset) throws IOException {
+ private void readGDEFMarkAttachmentTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// subtable is a bare class definition table
@@ -3316,7 +3317,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readGDEFMarkGlyphsTableFormat1(String tableTag, int lookupSequence, long subtableOffset, int subtableFormat) throws IOException {
+ private void readGDEFMarkGlyphsTableFormat1(TTFTableName tableTag, int lookupSequence, long subtableOffset, int subtableFormat) throws IOException {
initATSubState();
in.seekSet(subtableOffset);
// skip over format (already known)
@@ -3350,7 +3351,7 @@ public final class OTFAdvancedTypographicTableReader {
resetATSubState();
}
- private void readGDEFMarkGlyphsTable(String tableTag, int lookupSequence, long subtableOffset) throws IOException {
+ private void readGDEFMarkGlyphsTable(TTFTableName tableTag, int lookupSequence, long subtableOffset) throws IOException {
in.seekSet(subtableOffset);
// read mark set subtable format
int sf = in.readTTFUShort();
@@ -3366,11 +3367,11 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGDEF() throws IOException {
- String tableTag = "GDEF";
+ TTFTableName tableTag = TTFTableName.GDEF;
// Initialize temporary state
initATState();
// Read glyph definition (GDEF) table
- TTFDirTabEntry dirTab = ttf.getDirectoryEntry ( tableTag );
+ TTFDirTabEntry dirTab = ttf.getDirectoryEntry( tableTag );
if ( gdef != null ) {
if (log.isDebugEnabled()) {
log.debug(tableTag + ": ignoring duplicate table");
@@ -3439,7 +3440,7 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGSUB() throws IOException {
- String tableTag = "GSUB";
+ TTFTableName tableTag = TTFTableName.GSUB;
// Initialize temporary state
initATState();
// Read glyph substitution (GSUB) table
@@ -3476,7 +3477,7 @@ public final class OTFAdvancedTypographicTableReader {
* @throws IOException In case of a I/O problem
*/
private void readGPOS() throws IOException {
- String tableTag = "GPOS";
+ TTFTableName tableTag = TTFTableName.GPOS;
// Initialize temporary state
initATState();
// Read glyph positioning (GPOS) table
diff --git a/src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java b/src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java
index ce4585828..26249bc22 100644
--- a/src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java
+++ b/src/java/org/apache/fop/complexscripts/scripts/IndicScriptProcessor.java
@@ -360,7 +360,7 @@ public class IndicScriptProcessor extends DefaultScriptProcessor {
}
/** Abstract syllabizer. */
- protected abstract static class Syllabizer {
+ protected abstract static class Syllabizer implements Comparable {
private String script;
private String language;
Syllabizer ( String script, String language ) {
diff --git a/src/java/org/apache/fop/fo/FOEventHandler.java b/src/java/org/apache/fop/fo/FOEventHandler.java
index 743708b72..11b6d4a2f 100644
--- a/src/java/org/apache/fop/fo/FOEventHandler.java
+++ b/src/java/org/apache/fop/fo/FOEventHandler.java
@@ -123,11 +123,17 @@ public abstract class FOEventHandler {
public void endDocument() throws SAXException {
}
- /** {@inheritDoc} */
+ /**
+ * Called upon start of root element.
+ * @param root element
+ */
public void startRoot(Root root) {
}
- /** {@inheritDoc} */
+ /**
+ * Called upon end of root element.
+ * @param root element
+ */
public void endRoot(Root root) {
}
@@ -413,9 +419,9 @@ public abstract class FOEventHandler {
/**
* Process end of a Static.
- * @param statisContent StaticContent that is ending
+ * @param staticContent StaticContent that is ending
*/
- public void endStatic(StaticContent statisContent) {
+ public void endStatic(StaticContent staticContent) {
}
diff --git a/src/java/org/apache/fop/fo/flow/Wrapper.java b/src/java/org/apache/fop/fo/flow/Wrapper.java
index 1302e3134..0aec7ce16 100644
--- a/src/java/org/apache/fop/fo/flow/Wrapper.java
+++ b/src/java/org/apache/fop/fo/flow/Wrapper.java
@@ -26,7 +26,10 @@ import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.FObjMixed;
+import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.CommonAccessibility;
+import org.apache.fop.fo.properties.CommonAccessibilityHolder;
/**
* Class modelling the <a href=http://www.w3.org/TR/xsl/#fo_wrapper">
@@ -34,13 +37,13 @@ import org.apache.fop.fo.ValidationException;
* The <code>fo:wrapper</code> object serves as a property holder for
* its child node objects.
*/
-public class Wrapper extends FObjMixed {
- // The value of properties relevant for fo:wrapper.
- // End of property values
+public class Wrapper extends FObjMixed implements CommonAccessibilityHolder {
// used for FO validation
private boolean blockOrInlineItemFound = false;
+ private CommonAccessibility commonAccessibility;
+
/**
* Create a Wrapper instance that is a child of the
* given {@link FONode}
@@ -52,6 +55,12 @@ public class Wrapper extends FObjMixed {
}
@Override
+ public void bind(PropertyList pList) throws FOPException {
+ super.bind(pList);
+ commonAccessibility = CommonAccessibility.getInstance(pList);
+ }
+
+ @Override
protected void startOfNode() throws FOPException {
super.startOfNode();
getFOEventHandler().startWrapper(this);
@@ -136,6 +145,10 @@ public class Wrapper extends FObjMixed {
return FO_WRAPPER;
}
+ public CommonAccessibility getCommonAccessibility() {
+ return commonAccessibility;
+ }
+
@Override
public boolean isDelimitedTextRangeBoundary ( int boundary ) {
return false;
diff --git a/src/java/org/apache/fop/fo/properties/CondLengthProperty.java b/src/java/org/apache/fop/fo/properties/CondLengthProperty.java
index 07eec7361..19c8af1bb 100644
--- a/src/java/org/apache/fop/fo/properties/CondLengthProperty.java
+++ b/src/java/org/apache/fop/fo/properties/CondLengthProperty.java
@@ -26,6 +26,7 @@ import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.util.CompareUtil;
/**
* Superclass for properties that have conditional lengths
@@ -192,8 +193,8 @@ public class CondLengthProperty extends Property implements CompoundDatatype {
if (obj instanceof CondLengthProperty) {
CondLengthProperty clp = (CondLengthProperty)obj;
- return (this.length == clp.length
- && this.conditionality == clp.conditionality);
+ return (CompareUtil.equal(this.length, clp.length)
+ && CompareUtil.equal(this.conditionality, clp.conditionality));
}
return false;
}
diff --git a/src/java/org/apache/fop/fonts/CIDFontType.java b/src/java/org/apache/fop/fonts/CIDFontType.java
index ce01fa629..20a94b9dd 100644
--- a/src/java/org/apache/fop/fonts/CIDFontType.java
+++ b/src/java/org/apache/fop/fonts/CIDFontType.java
@@ -34,7 +34,7 @@ public class CIDFontType extends ValuedEnum {
/**
* CID Font Type 2 (based on TrueType format)
*/
- public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 1);
+ public static final CIDFontType CIDTYPE2 = new CIDFontType("CIDFontType2", 2);
/**
diff --git a/src/java/org/apache/fop/fonts/BFEntry.java b/src/java/org/apache/fop/fonts/CMapSegment.java
index d3c7956ba..816df2ca0 100644
--- a/src/java/org/apache/fop/fonts/BFEntry.java
+++ b/src/java/org/apache/fop/fonts/CMapSegment.java
@@ -20,26 +20,49 @@
package org.apache.fop.fonts;
/**
- * This is just a holder class for bfentries, groups of characters of a base font (bf).
+ * A segment in a cmap table of format 4. Unicode code points between
+ * {@link #getUnicodeStart()} and {@link #getUnicodeEnd()} map to contiguous glyph indices
+ * starting from {@link #getGlyphStartIndex()}.
*/
-public class BFEntry {
+public final class CMapSegment {
- private int unicodeStart;
- private int unicodeEnd;
- private int glyphStartIndex;
+ private final int unicodeStart;
+ private final int unicodeEnd;
+ private final int glyphStartIndex;
/**
- * Main constructor.
+ * Creates a new segment.
+ *
* @param unicodeStart Unicode start index
* @param unicodeEnd Unicode end index
* @param glyphStartIndex glyph start index
*/
- public BFEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
+ public CMapSegment(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
this.unicodeStart = unicodeStart;
this.unicodeEnd = unicodeEnd;
this.glyphStartIndex = glyphStartIndex;
}
+ @Override
+ public int hashCode() {
+ int hc = 17;
+ hc = 31 * hc + unicodeStart;
+ hc = 31 * hc + unicodeEnd;
+ hc = 31 * hc + glyphStartIndex;
+ return hc;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof CMapSegment) {
+ CMapSegment ce = (CMapSegment) o;
+ return ce.unicodeStart == this.unicodeStart
+ && ce.unicodeEnd == this.unicodeEnd
+ && ce.glyphStartIndex == this.glyphStartIndex;
+ }
+ return false;
+ }
+
/**
* Returns the unicodeStart.
* @return the Unicode start index
@@ -67,7 +90,7 @@ public class BFEntry {
/** {@inheritDoc} */
@Override
public String toString() {
- StringBuilder sb = new StringBuilder("BFEntry: ");
+ StringBuilder sb = new StringBuilder("CMapSegment: ");
sb.append ( "{ UC[" );
sb.append ( unicodeStart );
sb.append ( ',' );
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index c6b43fe98..89f515205 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -42,6 +42,7 @@ public abstract class CustomFont extends Typeface
private String embedFileName = null;
private String embedResourceName = null;
private FontResolver resolver = null;
+ private EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
private int capHeight = 0;
private int xHeight = 0;
@@ -62,6 +63,9 @@ public abstract class CustomFont extends Typeface
private boolean useKerning = true;
private boolean useAdvanced = true;
+ /** the character map, mapping Unicode ranges to glyph indices. */
+ protected CMapSegment[] cmap;
+
/** {@inheritDoc} */
public String getFontName() {
return fontName;
@@ -112,6 +116,14 @@ public abstract class CustomFont extends Typeface
}
/**
+ * Returns the embedding mode for this font.
+ * @return embedding mode
+ */
+ public EmbeddingMode getEmbeddingMode() {
+ return embeddingMode;
+ }
+
+ /**
* Returns a Source representing an embeddable font file.
* @return Source for an embeddable font file
* @throws IOException if embedFileName is not null but Source is not found
@@ -337,6 +349,13 @@ public abstract class CustomFont extends Typeface
/**
* {@inheritDoc}
*/
+ public void setEmbeddingMode(EmbeddingMode embeddingMode) {
+ this.embeddingMode = embeddingMode;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void setCapHeight(int capHeight) {
this.capHeight = capHeight;
}
@@ -473,4 +492,25 @@ public abstract class CustomFont extends Typeface
}
}
+ /**
+ * Sets the character map for this font. It maps all available Unicode characters
+ * to their glyph indices inside the font.
+ * @param cmap the character map
+ */
+ public void setCMap(CMapSegment[] cmap) {
+ this.cmap = new CMapSegment[cmap.length];
+ System.arraycopy(cmap, 0, this.cmap, 0, cmap.length);
+ }
+
+ /**
+ * Returns the character map for this font. It maps all available Unicode characters
+ * to their glyph indices inside the font.
+ * @return the character map
+ */
+ public CMapSegment[] getCMap() {
+ CMapSegment[] copy = new CMapSegment[cmap.length];
+ System.arraycopy(this.cmap, 0, copy, 0, this.cmap.length);
+ return copy;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/CustomFontCollection.java b/src/java/org/apache/fop/fonts/CustomFontCollection.java
index 6e798a8f7..fc8c947e4 100644
--- a/src/java/org/apache/fop/fonts/CustomFontCollection.java
+++ b/src/java/org/apache/fop/fonts/CustomFontCollection.java
@@ -72,7 +72,7 @@ public class CustomFontCollection implements FontCollection {
List<FontTriplet> triplets = embedFontInfo.getFontTriplets();
for (int tripletIndex = 0; tripletIndex < triplets.size(); tripletIndex++) {
- FontTriplet triplet = (FontTriplet) triplets.get(tripletIndex);
+ FontTriplet triplet = triplets.get(tripletIndex);
fontInfo.addFontProperties(internalName, triplet);
}
}
diff --git a/src/java/org/apache/fop/fonts/EmbedFontInfo.java b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
index 8848c0a87..64bd200be 100644
--- a/src/java/org/apache/fop/fonts/EmbedFontInfo.java
+++ b/src/java/org/apache/fop/fonts/EmbedFontInfo.java
@@ -25,6 +25,8 @@ import java.util.List;
/**
* FontInfo contains meta information on fonts (where is the metrics file etc.)
+ * TODO: We need to remove this class and think about more intelligent design patterns
+ * (Data classes => Procedural code)
*/
public class EmbedFontInfo implements Serializable {
@@ -41,6 +43,8 @@ public class EmbedFontInfo implements Serializable {
protected boolean advanced;
/** the requested encoding mode for the font */
protected EncodingMode encodingMode = EncodingMode.AUTO;
+ /** the requested embedding mode for this font */
+ protected EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
/** the PostScript name of the font */
protected String postScriptName = null;
@@ -149,6 +153,14 @@ public class EmbedFontInfo implements Serializable {
}
/**
+ * Returns the embedding mode for this font.
+ * @return the embedding mode.
+ */
+ public EmbeddingMode getEmbeddingMode() {
+ return embeddingMode;
+ }
+
+ /**
* Defines whether the font is embedded or not.
* @param value true to embed the font, false to reference it
*/
@@ -175,6 +187,17 @@ public class EmbedFontInfo implements Serializable {
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();
diff --git a/src/java/org/apache/fop/fonts/EmbeddingMode.java b/src/java/org/apache/fop/fonts/EmbeddingMode.java
new file mode 100644
index 000000000..5a3e905c9
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/EmbeddingMode.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Locale;
+
+/**
+ * This enumerates the embedding mode of fonts; full; subset; auto (auto defaults to full for
+ * Type 1 fonts and subset for TrueType fonts.
+ */
+public enum EmbeddingMode {
+ /** Default option: assumes FULL for Type 1 fonts and SUBSET for TrueType fonts. */
+ AUTO,
+ /** Full font embedding: This means the whole of the font is written to file. */
+ FULL,
+ /** Subset font embedding: Only the mandatory tables and a subset of glyphs are written
+ * to file.*/
+ SUBSET;
+
+ /**
+ * Returns the name of this embedding mode.
+ * @return the name of this embedding mode in lower case.
+ */
+ public String getName() {
+ return this.toString().toLowerCase(Locale.ENGLISH);
+ }
+
+ /**
+ * Returns the embedding mode corresponding to the given name.
+ * @param value the name of an embedding mode (not case sensitive)
+ * @return the corresponding embedding mode
+ */
+ public static EmbeddingMode getValue(String value) {
+ for (EmbeddingMode mode : EmbeddingMode.values()) {
+ if (mode.toString().equalsIgnoreCase(value)) {
+ return mode;
+ }
+ }
+ throw new IllegalArgumentException("Invalid embedding-mode: " + value);
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/EncodingMode.java b/src/java/org/apache/fop/fonts/EncodingMode.java
index 8a40d6593..78ffb7ac6 100644
--- a/src/java/org/apache/fop/fonts/EncodingMode.java
+++ b/src/java/org/apache/fop/fonts/EncodingMode.java
@@ -52,7 +52,7 @@ public enum EncodingMode {
* @param name the name of the encoding mode to look up
* @return the encoding mode constant
*/
- public static EncodingMode getEncodingMode(String name) {
+ public static EncodingMode getValue(String name) {
for (EncodingMode em : EncodingMode.values()) {
if (name.equalsIgnoreCase(em.getName())) {
return em;
diff --git a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
index 34b6ed1d0..042709884 100644
--- a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
+++ b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java
@@ -254,12 +254,16 @@ public class FontInfoConfigurator {
boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true);
boolean useAdvanced = fontCfg.getAttributeAsBoolean("advanced", true);
- EncodingMode encodingMode = EncodingMode.getEncodingMode(
+ 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)) {
diff --git a/src/java/org/apache/fop/fonts/FontLoader.java b/src/java/org/apache/fop/fonts/FontLoader.java
index 91b763939..9bdbcd350 100644
--- a/src/java/org/apache/fop/fonts/FontLoader.java
+++ b/src/java/org/apache/fop/fonts/FontLoader.java
@@ -85,15 +85,17 @@ public abstract class FontLoader {
* @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, EncodingMode encodingMode, FontResolver resolver) throws IOException {
+ boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
+ FontResolver resolver) throws IOException {
return loadFont(fontFile.toURI().toURL(), subFontName,
- embedded, encodingMode, resolver);
+ embedded, embeddingMode, encodingMode, resolver);
}
/**
@@ -101,16 +103,17 @@ public abstract class FontLoader {
* @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, EncodingMode encodingMode,
+ boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
FontResolver resolver) throws IOException {
return loadFont(fontUrl.toExternalForm(), subFontName,
- embedded, encodingMode, true, true,
+ embedded, embeddingMode, encodingMode, true, true,
resolver);
}
@@ -119,6 +122,7 @@ public abstract class FontLoader {
* @param fontFileURI the URI to 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 useKerning indicates whether kerning information should be loaded if available
* @param useAdvanced indicates whether advanced typographic information shall be loaded if
@@ -128,8 +132,8 @@ public abstract class FontLoader {
* @throws IOException In case of an I/O error
*/
public static CustomFont loadFont(String fontFileURI, String subFontName,
- boolean embedded, EncodingMode encodingMode, boolean useKerning,
- boolean useAdvanced, FontResolver resolver) throws IOException {
+ boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
+ boolean useKerning, boolean useAdvanced, FontResolver resolver) throws IOException {
fontFileURI = fontFileURI.trim();
boolean type1 = isType1(fontFileURI);
FontLoader loader;
@@ -138,10 +142,14 @@ public abstract class FontLoader {
throw new IllegalArgumentException(
"CID encoding mode not supported for Type 1 fonts");
}
+ if (embeddingMode == EmbeddingMode.SUBSET) {
+ throw new IllegalArgumentException(
+ "Subset embedding for Type 1 fonts is not supported");
+ }
loader = new Type1FontLoader(fontFileURI, embedded, useKerning, resolver);
} else {
loader = new TTFFontLoader(fontFileURI, subFontName,
- embedded, encodingMode, useKerning, useAdvanced, resolver);
+ embedded, embeddingMode, encodingMode, useKerning, useAdvanced, resolver);
}
return loader.getFont();
}
diff --git a/src/java/org/apache/fop/fonts/FontReader.java b/src/java/org/apache/fop/fonts/FontReader.java
index 9d75ad74f..46ea9123d 100644
--- a/src/java/org/apache/fop/fonts/FontReader.java
+++ b/src/java/org/apache/fop/fonts/FontReader.java
@@ -64,7 +64,7 @@ public class FontReader extends DefaultHandler {
private Map<Integer, Integer> currentKerning = null;
- private List<BFEntry> bfranges = null;
+ private List<CMapSegment> bfranges = null;
private void createFont(InputSource source) throws FOPException {
XMLReader parser = null;
@@ -154,12 +154,14 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void startDocument() {
}
/**
* {@inheritDoc}
*/
+ @Override
public void setDocumentLocator(Locator locator) {
// this.locator = locator; // not used at present
}
@@ -167,6 +169,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("font-metrics")) {
@@ -198,9 +201,9 @@ public class FontReader extends DefaultHandler {
returnFont.putKerningEntry(new Integer(attributes.getValue("kpx1")),
currentKerning);
} else if ("bfranges".equals(localName)) {
- bfranges = new ArrayList<BFEntry>();
+ bfranges = new ArrayList<CMapSegment>();
} else if ("bf".equals(localName)) {
- BFEntry entry = new BFEntry(getInt(attributes.getValue("us")),
+ CMapSegment entry = new CMapSegment(getInt(attributes.getValue("us")),
getInt(attributes.getValue("ue")),
getInt(attributes.getValue("gi")));
bfranges.add(entry);
@@ -236,6 +239,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
String content = text.toString().trim();
if ("font-name".equals(localName)) {
@@ -303,7 +307,7 @@ public class FontReader extends DefaultHandler {
multiFont.setWidthArray(wds);
} else if ("bfranges".equals(localName)) {
- multiFont.setBFEntries(bfranges.toArray(new BFEntry[0]));
+ multiFont.setCMap(bfranges.toArray(new CMapSegment[0]));
}
text.setLength(0); //Reset text buffer (see characters())
}
@@ -311,6 +315,7 @@ public class FontReader extends DefaultHandler {
/**
* {@inheritDoc}
*/
+ @Override
public void characters(char[] ch, int start, int length) {
text.append(ch, start, length);
}
diff --git a/src/java/org/apache/fop/fonts/FontType.java b/src/java/org/apache/fop/fonts/FontType.java
index 56039b519..edd8d0c37 100644
--- a/src/java/org/apache/fop/fonts/FontType.java
+++ b/src/java/org/apache/fop/fonts/FontType.java
@@ -130,4 +130,9 @@ public class FontType {
return value;
}
+ @Override
+ public String toString() {
+ return name;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
index 7077c53b9..dfad4ffce 100644
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ b/src/java/org/apache/fop/fonts/LazyFont.java
@@ -36,7 +36,6 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.complexscripts.fonts.Positionable;
import org.apache.fop.complexscripts.fonts.Substitutable;
-
/**
* This class is used to defer the loading of a font until it is really used.
*/
@@ -49,7 +48,8 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
private boolean useKerning;
private boolean useAdvanced;
private EncodingMode encodingMode = EncodingMode.AUTO;
- private boolean embedded;
+ private EmbeddingMode embeddingMode = EmbeddingMode.AUTO;
+ private boolean embedded = true;
private String subFontName;
private boolean isMetricsLoaded;
@@ -74,6 +74,7 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
this.useAdvanced = fontInfo.getAdvanced();
}
this.encodingMode = fontInfo.getEncodingMode();
+ this.embeddingMode = fontInfo.getEmbeddingMode();
this.subFontName = fontInfo.getSubFontName();
this.embedded = fontInfo.isEmbedded();
this.resolver = resolver;
@@ -147,8 +148,9 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
if (fontEmbedPath == null) {
throw new RuntimeException("Cannot load font. No font URIs available.");
}
- realFont = FontLoader.loadFont(fontEmbedPath, this.subFontName,
- this.embedded, this.encodingMode, useKerning, useAdvanced, resolver);
+ realFont = FontLoader.loadFont(fontEmbedPath, subFontName,
+ embedded, embeddingMode, encodingMode,
+ useKerning, useAdvanced, resolver);
}
if (realFont instanceof FontDescriptor) {
realFontDescriptor = (FontDescriptor) realFont;
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index 73ef7c228..54b772b2e 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -51,14 +51,6 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
private CIDSubset subset = new CIDSubset();
- /**
- * A map from Unicode indices to glyph indices. No assumption
- * about ordering is made below. If lookup is changed to a binary
- * search (from the current linear search), then addPrivateUseMapping()
- * needs to be changed to perform ordered inserts.
- */
- private BFEntry[] bfentries = null;
-
/* advanced typographic support */
private GlyphDefinitionTable gdef;
private GlyphSubstitutionTable gsub;
@@ -82,26 +74,31 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
}
/** {@inheritDoc} */
+ @Override
public int getDefaultWidth() {
return defaultWidth;
}
/** {@inheritDoc} */
+ @Override
public String getRegistry() {
return "Adobe";
}
/** {@inheritDoc} */
+ @Override
public String getOrdering() {
return "UCS";
}
/** {@inheritDoc} */
+ @Override
public int getSupplement() {
return 0;
}
/** {@inheritDoc} */
+ @Override
public CIDFontType getCIDType() {
return cidType;
}
@@ -115,6 +112,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
}
/** {@inheritDoc} */
+ @Override
public String getEmbedFontName() {
if (isEmbeddable()) {
return FontUtil.stripWhiteSpace(super.getFontName());
@@ -128,17 +126,18 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return !(getEmbedFileName() == null && getEmbedResourceName() == null);
}
- /** {@inheritDoc} */
public boolean isSubsetEmbedded() {
return true;
}
/** {@inheritDoc} */
+ @Override
public CIDSubset getCIDSubset() {
return this.subset;
}
/** {@inheritDoc} */
+ @Override
public String getEncodingName() {
return encoding;
}
@@ -171,30 +170,30 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
int idx = c;
int retIdx = SingleByteEncoding.NOT_FOUND_CODE_POINT;
- for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
- if (bfentries[i].getUnicodeStart() <= idx
- && bfentries[i].getUnicodeEnd() >= idx) {
+ for (int i = 0; (i < cmap.length) && retIdx == 0; i++) {
+ if (cmap[i].getUnicodeStart() <= idx
+ && cmap[i].getUnicodeEnd() >= idx) {
- retIdx = bfentries[i].getGlyphStartIndex()
+ retIdx = cmap[i].getGlyphStartIndex()
+ idx
- - bfentries[i].getUnicodeStart();
+ - cmap[i].getUnicodeStart();
}
}
return retIdx;
}
/**
- * Add a private use mapping {PU,GI} to the existing BFENTRIES map.
+ * Add a private use mapping {PU,GI} to the existing character map.
* N.B. Does not insert in order, merely appends to end of existing map.
*/
private synchronized void addPrivateUseMapping ( int pu, int gi ) {
assert findGlyphIndex ( pu ) == SingleByteEncoding.NOT_FOUND_CODE_POINT;
- BFEntry[] bfeOld = bfentries;
- int bfeCnt = bfeOld.length;
- BFEntry[] bfeNew = new BFEntry [ bfeCnt + 1 ];
- System.arraycopy ( bfeOld, 0, bfeNew, 0, bfeCnt );
- bfeNew [ bfeCnt ] = new BFEntry ( pu, pu, gi );
- bfentries = bfeNew;
+ CMapSegment[] oldCmap = cmap;
+ int cmapLength = oldCmap.length;
+ CMapSegment[] newCmap = new CMapSegment [ cmapLength + 1 ];
+ System.arraycopy ( oldCmap, 0, newCmap, 0, cmapLength );
+ newCmap [ cmapLength ] = new CMapSegment ( pu, pu, gi );
+ cmap = newCmap;
}
/**
@@ -252,12 +251,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
// [TBD] - needs optimization, i.e., change from linear search to binary search
private int findCharacterFromGlyphIndex ( int gi, boolean augment ) {
int cc = 0;
- for ( int i = 0, n = bfentries.length; i < n; i++ ) {
- BFEntry be = bfentries [ i ];
- int s = be.getGlyphStartIndex();
- int e = s + ( be.getUnicodeEnd() - be.getUnicodeStart() );
+ for ( int i = 0, n = cmap.length; i < n; i++ ) {
+ CMapSegment segment = cmap [ i ];
+ int s = segment.getGlyphStartIndex();
+ int e = s + ( segment.getUnicodeEnd() - segment.getUnicodeStart() );
if ( ( gi >= s ) && ( gi <= e ) ) {
- cc = be.getUnicodeStart() + ( gi - s );
+ cc = segment.getUnicodeStart() + ( gi - s );
break;
}
}
@@ -273,6 +272,7 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
/** {@inheritDoc} */
+ @Override
public char mapChar(char c) {
notifyMapOperation();
int glyphIndex = findGlyphIndex(c);
@@ -287,20 +287,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
}
/** {@inheritDoc} */
+ @Override
public boolean hasChar(char c) {
return (findGlyphIndex(c) != SingleByteEncoding.NOT_FOUND_CODE_POINT);
}
/**
- * Sets the array of BFEntry instances which constitutes the Unicode to glyph index map for
- * a font. ("BF" means "base font")
- * @param entries the Unicode to glyph index map
- */
- public void setBFEntries(BFEntry[] entries) {
- this.bfentries = entries;
- }
-
- /**
* Sets the defaultWidth.
* @param defaultWidth The defaultWidth to set
*/
diff --git a/src/java/org/apache/fop/fonts/MutableFont.java b/src/java/org/apache/fop/fonts/MutableFont.java
index 41c552a0b..3ebc3c465 100644
--- a/src/java/org/apache/fop/fonts/MutableFont.java
+++ b/src/java/org/apache/fop/fonts/MutableFont.java
@@ -61,6 +61,12 @@ public interface MutableFont {
void setEmbedResourceName(String name);
/**
+ * Sets the embedding mode.
+ * @param embeddingMode the embedding mode
+ */
+ void setEmbeddingMode(EmbeddingMode embeddingMode);
+
+ /**
* Sets the capital height value.
* @param capHeight capital height
*/
diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java
index d5901297f..1aed72d69 100644
--- a/src/java/org/apache/fop/fonts/SingleByteFont.java
+++ b/src/java/org/apache/fop/fonts/SingleByteFont.java
@@ -31,6 +31,8 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.fonts.Glyphs;
+import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
+
/**
* Generic SingleByte font
*/
@@ -48,6 +50,7 @@ public class SingleByteFont extends CustomFont {
private List<SimpleSingleByteEncoding> additionalEncodings;
private Map<Character, Character> alternativeCodes;
+ private PostScriptVersion ttPostScriptVersion;
/**
* Main constructor.
@@ -397,5 +400,26 @@ public class SingleByteFont extends CustomFont {
}
}
+ /**
+ * Sets the version of the PostScript table stored in the TrueType font represented by
+ * this instance.
+ *
+ * @param version version of the <q>post</q> table
+ */
+ public void setTrueTypePostScriptVersion(PostScriptVersion version) {
+ ttPostScriptVersion = version;
+ }
+
+ /**
+ * Returns the version of the PostScript table stored in the TrueType font represented by
+ * this instance.
+ *
+ * @return the version of the <q>post</q> table
+ */
+ public PostScriptVersion getTrueTypePostScriptVersion() {
+ assert getFontType() == FontType.TRUETYPE;
+ return ttPostScriptVersion;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/apps/TTFReader.java b/src/java/org/apache/fop/fonts/apps/TTFReader.java
index 6acb490c2..224c8de2f 100644
--- a/src/java/org/apache/fop/fonts/apps/TTFReader.java
+++ b/src/java/org/apache/fop/fonts/apps/TTFReader.java
@@ -20,7 +20,6 @@
package org.apache.fop.fonts.apps;
import java.io.IOException;
-import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -34,9 +33,9 @@ import org.xml.sax.SAXException;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.Version;
+import org.apache.fop.fonts.CMapSegment;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.truetype.FontFileReader;
-import org.apache.fop.fonts.truetype.TTFCmapEntry;
import org.apache.fop.fonts.truetype.TTFFile;
import org.apache.fop.util.CommandLineLogger;
@@ -288,9 +287,9 @@ public class TTFReader extends AbstractFontReader {
root.appendChild(el);
el.appendChild(doc.createTextNode(ttf.getFullName()));
}
- Set familyNames = ttf.getFamilyNames();
+ Set<String> familyNames = ttf.getFamilyNames();
if (familyNames.size() > 0) {
- String familyName = (String)familyNames.iterator().next();
+ String familyName = familyNames.iterator().next();
el = doc.createElement("family-name");
root.appendChild(el);
el.appendChild(doc.createTextNode(familyName));
@@ -386,9 +385,7 @@ public class TTFReader extends AbstractFontReader {
el = doc.createElement("bfranges");
mel.appendChild(el);
- Iterator iter = ttf.getCMaps().listIterator();
- while (iter.hasNext()) {
- TTFCmapEntry ce = (TTFCmapEntry)iter.next();
+ for (CMapSegment ce : ttf.getCMaps()) {
Element el2 = doc.createElement("bf");
el.appendChild(el2);
el2.setAttribute("us", String.valueOf(ce.getUnicodeStart()));
@@ -443,31 +440,28 @@ public class TTFReader extends AbstractFontReader {
Document doc = parent.getOwnerDocument();
// Get kerning
- Iterator iter;
+ Set<Integer> kerningKeys;
if (isCid) {
- iter = ttf.getKerning().keySet().iterator();
+ kerningKeys = ttf.getKerning().keySet();
} else {
- iter = ttf.getAnsiKerning().keySet().iterator();
+ kerningKeys = ttf.getAnsiKerning().keySet();
}
- while (iter.hasNext()) {
- Integer kpx1 = (Integer)iter.next();
+ for (Integer kpx1 : kerningKeys) {
el = doc.createElement("kerning");
el.setAttribute("kpx1", kpx1.toString());
parent.appendChild(el);
Element el2 = null;
- Map h2;
+ Map<Integer, Integer> h2;
if (isCid) {
- h2 = (Map)ttf.getKerning().get(kpx1);
+ h2 = ttf.getKerning().get(kpx1);
} else {
- h2 = (Map)ttf.getAnsiKerning().get(kpx1);
+ h2 = ttf.getAnsiKerning().get(kpx1);
}
- Iterator iter2 = h2.keySet().iterator();
- while (iter2.hasNext()) {
- Integer kpx2 = (Integer)iter2.next();
+ for (Integer kpx2 : h2.keySet()) {
if (isCid || kpx2.intValue() < 256) {
el2 = doc.createElement("pair");
el2.setAttribute("kpx2", kpx2.toString());
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
index bd0a33cb1..deee4b018 100644
--- a/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
+++ b/src/java/org/apache/fop/fonts/autodetect/FontInfoFinder.java
@@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.CustomFont;
import org.apache.fop.fonts.EmbedFontInfo;
+import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontCache;
@@ -222,7 +223,7 @@ public class FontInfoFinder {
}
try {
TTFFontLoader ttfLoader = new TTFFontLoader(
- fontFileURL, fontName, true, EncodingMode.AUTO,
+ fontFileURL, fontName, true, EmbeddingMode.AUTO, EncodingMode.AUTO,
useKerning, useAdvanced, resolver);
customFont = ttfLoader.getFont();
if (this.eventListener != null) {
@@ -247,7 +248,8 @@ public class FontInfoFinder {
} else {
// The normal case
try {
- customFont = FontLoader.loadFont(fontURL, null, true, EncodingMode.AUTO, resolver);
+ customFont = FontLoader.loadFont(fontURL, null, true, EmbeddingMode.AUTO,
+ EncodingMode.AUTO, resolver);
if (this.eventListener != null) {
customFont.setEventListener(this.eventListener);
}
diff --git a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
index b97120990..5da25e4b4 100644
--- a/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
+++ b/src/java/org/apache/fop/fonts/truetype/FontFileReader.java
@@ -90,23 +90,13 @@ public class FontFileReader {
}
/**
- * Set current file position to offset
- *
- * @param add The number of bytes to advance
- * @throws IOException In case of an I/O problem
- */
- public void seekAdd(long add) throws IOException {
- seekSet(current + add);
- }
-
- /**
* Skip a given number of bytes.
*
* @param add The number of bytes to advance
* @throws IOException In case of an I/O problem
*/
public void skip(long add) throws IOException {
- seekAdd(add);
+ seekSet(current + add);
}
/**
@@ -133,7 +123,7 @@ public class FontFileReader {
* @return One byte
* @throws IOException If EOF is reached
*/
- public byte read() throws IOException {
+ private byte read() throws IOException {
if (current >= fsize) {
throw new java.io.EOFException("Reached EOF, file size=" + fsize);
}
@@ -278,14 +268,14 @@ public class FontFileReader {
public final String readTTFString() throws IOException {
int i = current;
while (file[i++] != 0) {
- if (i > fsize) {
+ if (i >= fsize) {
throw new java.io.EOFException("Reached EOF, file size="
+ fsize);
}
}
- byte[] tmp = new byte[i - current];
- System.arraycopy(file, current, tmp, 0, i - current);
+ byte[] tmp = new byte[i - current - 1];
+ System.arraycopy(file, current, tmp, 0, i - current - 1);
return new String(tmp, "ISO-8859-1");
}
@@ -353,6 +343,11 @@ public class FontFileReader {
System.arraycopy(file, offset, ret, 0, length);
return ret;
}
-
-
+ /**
+ * Returns the full byte array representation of the file.
+ * @return byte array.
+ */
+ public byte[] getAllBytes() {
+ return file;
+ }
}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
deleted file mode 100644
index 897d5e2de..000000000
--- a/src/java/org/apache/fop/fonts/truetype/TTFCmapEntry.java
+++ /dev/null
@@ -1,118 +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.truetype;
-
-/**
- * The CMap entry contains information of a Unicode range and the
- * the glyph indexes related to the range
- */
-public class TTFCmapEntry {
-
- private int unicodeStart;
- private int unicodeEnd;
- private int glyphStartIndex;
-
- TTFCmapEntry() {
- unicodeStart = 0;
- unicodeEnd = 0;
- glyphStartIndex = 0;
- }
-
- TTFCmapEntry(int unicodeStart, int unicodeEnd, int glyphStartIndex) {
- this.unicodeStart = unicodeStart;
- this.unicodeEnd = unicodeEnd;
- this.glyphStartIndex = glyphStartIndex;
- }
-
- /**
- * {@inheritDoc}
- */
- public int hashCode() {
- int hc = super.hashCode();
- hc ^= ( hc * 11 ) + unicodeStart;
- hc ^= ( hc * 19 ) + unicodeEnd;
- hc ^= ( hc * 23 ) + glyphStartIndex;
- return hc;
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean equals(Object o) {
- if (o instanceof TTFCmapEntry) {
- TTFCmapEntry ce = (TTFCmapEntry)o;
- if (ce.unicodeStart == this.unicodeStart
- && ce.unicodeEnd == this.unicodeEnd
- && ce.glyphStartIndex == this.glyphStartIndex) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the glyphStartIndex.
- * @return int
- */
- public int getGlyphStartIndex() {
- return glyphStartIndex;
- }
-
- /**
- * Returns the unicodeEnd.
- * @return int
- */
- public int getUnicodeEnd() {
- return unicodeEnd;
- }
-
- /**
- * Returns the unicodeStart.
- * @return int
- */
- public int getUnicodeStart() {
- return unicodeStart;
- }
-
- /**
- * Sets the glyphStartIndex.
- * @param glyphStartIndex The glyphStartIndex to set
- */
- public void setGlyphStartIndex(int glyphStartIndex) {
- this.glyphStartIndex = glyphStartIndex;
- }
-
- /**
- * Sets the unicodeEnd.
- * @param unicodeEnd The unicodeEnd to set
- */
- public void setUnicodeEnd(int unicodeEnd) {
- this.unicodeEnd = unicodeEnd;
- }
-
- /**
- * Sets the unicodeStart.
- * @param unicodeStart The unicodeStart to set
- */
- public void setUnicodeStart(int unicodeStart) {
- this.unicodeStart = unicodeStart;
- }
-
-}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java b/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java
index 1f05ebfa1..c273d4471 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFDirTabEntry.java
@@ -33,6 +33,14 @@ public class TTFDirTabEntry {
private long offset;
private long length;
+ public TTFDirTabEntry() {
+ }
+
+ public TTFDirTabEntry(long offset, long length) {
+ this.offset = offset;
+ this.length = length;
+ }
+
/**
* Read Dir Tab.
* @param in font file reader
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
index 65ab560cf..bc979f277 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
@@ -20,11 +20,18 @@
package org.apache.fop.fonts.truetype;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.BitSet;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -36,6 +43,7 @@ import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
import org.apache.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader;
+import org.apache.fop.fonts.CMapSegment;
import org.apache.fop.fonts.FontUtil;
/**
@@ -46,10 +54,100 @@ import org.apache.fop.fonts.FontUtil;
public class TTFFile {
static final byte NTABS = 24;
- static final int NMACGLYPHS = 258;
static final int MAX_CHAR_CODE = 255;
static final int ENC_BUF_SIZE = 1024;
+ private static final String[] MAC_GLYPH_ORDERING = {
+ /* 0x000 */
+ ".notdef", ".null", "nonmarkingreturn", "space",
+ "exclam", "quotedbl", "numbersign", "dollar",
+ "percent", "ampersand", "quotesingle", "parenleft",
+ "parenright", "asterisk", "plus", "comma",
+ /* 0x010 */
+ "hyphen", "period", "slash", "zero",
+ "one", "two", "three", "four",
+ "five", "six", "seven", "eight",
+ "nine", "colon", "semicolon", "less",
+ /* 0x020 */
+ "equal", "greater", "question", "at",
+ "A", "B", "C", "D",
+ "E", "F", "G", "H",
+ "I", "J", "K", "L",
+ /* 0x030 */
+ "M", "N", "O", "P",
+ "Q", "R", "S", "T",
+ "U", "V", "W", "X",
+ "Y", "Z", "bracketleft", "backslash",
+ /* 0x040 */
+ "bracketright", "asciicircum", "underscore", "grave",
+ "a", "b", "c", "d",
+ "e", "f", "g", "h",
+ "i", "j", "k", "l",
+ /* 0x050 */
+ "m", "n", "o", "p",
+ "q", "r", "s", "t",
+ "u", "v", "w", "x",
+ "y", "z", "braceleft", "bar",
+ /* 0x060 */
+ "braceright", "asciitilde", "Adieresis", "Aring",
+ "Ccedilla", "Eacute", "Ntilde", "Odieresis",
+ "Udieresis", "aacute", "agrave", "acircumflex",
+ "adieresis", "atilde", "aring", "ccedilla",
+ /* 0x070 */
+ "eacute", "egrave", "ecircumflex", "edieresis",
+ "iacute", "igrave", "icircumflex", "idieresis",
+ "ntilde", "oacute", "ograve", "ocircumflex",
+ "odieresis", "otilde", "uacute", "ugrave",
+ /* 0x080 */
+ "ucircumflex", "udieresis", "dagger", "degree",
+ "cent", "sterling", "section", "bullet",
+ "paragraph", "germandbls", "registered", "copyright",
+ "trademark", "acute", "dieresis", "notequal",
+ /* 0x090 */
+ "AE", "Oslash", "infinity", "plusminus",
+ "lessequal", "greaterequal", "yen", "mu",
+ "partialdiff", "summation", "product", "pi",
+ "integral", "ordfeminine", "ordmasculine", "Omega",
+ /* 0x0A0 */
+ "ae", "oslash", "questiondown", "exclamdown",
+ "logicalnot", "radical", "florin", "approxequal",
+ "Delta", "guillemotleft", "guillemotright", "ellipsis",
+ "nonbreakingspace", "Agrave", "Atilde", "Otilde",
+ /* 0x0B0 */
+ "OE", "oe", "endash", "emdash",
+ "quotedblleft", "quotedblright", "quoteleft", "quoteright",
+ "divide", "lozenge", "ydieresis", "Ydieresis",
+ "fraction", "currency", "guilsinglleft", "guilsinglright",
+ /* 0x0C0 */
+ "fi", "fl", "daggerdbl", "periodcentered",
+ "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
+ "Ecircumflex", "Aacute", "Edieresis", "Egrave",
+ "Iacute", "Icircumflex", "Idieresis", "Igrave",
+ /* 0x0D0 */
+ "Oacute", "Ocircumflex", "apple", "Ograve",
+ "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
+ "circumflex", "tilde", "macron", "breve",
+ "dotaccent", "ring", "cedilla", "hungarumlaut",
+ /* 0x0E0 */
+ "ogonek", "caron", "Lslash", "lslash",
+ "Scaron", "scaron", "Zcaron", "zcaron",
+ "brokenbar", "Eth", "eth", "Yacute",
+ "yacute", "Thorn", "thorn", "minus",
+ /* 0x0F0 */
+ "multiply", "onesuperior", "twosuperior", "threesuperior",
+ "onehalf", "onequarter", "threequarters", "franc",
+ "Gbreve", "gbreve", "Idotaccent", "Scedilla",
+ "scedilla", "Cacute", "cacute", "Ccaron",
+ /* 0x100 */
+ "ccaron", "dcroat"
+ };
+
+ /** The FontFileReader used to read this TrueType font. */
+ protected FontFileReader fontFile;
+
+ /** Set to true to get even more debug output than with level DEBUG */
+ public static final boolean TRACE_ENABLED = false;
+
private final String encoding = "WinAnsiEncoding"; // Default encoding
private final short firstChar = 0;
@@ -61,33 +159,31 @@ public class TTFFile {
/**
* Table directory
*/
- protected Map dirTabs;
- private Map<Integer, Map<Integer, Integer>> kerningTab; // for CIDs
+ protected Map<TTFTableName, TTFDirTabEntry> dirTabs;
+ private Map<Integer, Map<Integer, Integer>> kerningTab; // for CIDs
private Map<Integer, Map<Integer, Integer>> ansiKerningTab; // For winAnsiEncoding
- private List cmaps;
- private Set unicodeMappings;
+ private List<CMapSegment> cmaps;
+ private Set<UnicodeMapping> unicodeMappings;
private int upem; // unitsPerEm from "head" table
private int nhmtx; // Number of horizontal metrics
- private int postFormat;
+ private PostScriptVersion postScriptVersion;
private int locaFormat;
/**
* Offset to last loca
*/
protected long lastLoca = 0;
private int numberOfGlyphs; // Number of glyphs in font (read from "maxp" table)
- private int nmGlyphs; // Used in fixWidths - remove?
/**
* Contains glyph data
*/
protected TTFMtxEntry[] mtxTab; // Contains glyph data
- private final int[] mtxEncoded = null;
private String postScriptName = "";
private String fullName = "";
private String notice = "";
- private final Set familyNames = new java.util.HashSet(); //Set<String>
+ private Set<String> familyNames = new HashSet<String>();
private String subFamilyName = "";
private long italicAngle = 0;
@@ -116,12 +212,12 @@ public class TTFFile {
private short lastChar = 0;
private int[] ansiWidth;
- private Map ansiIndex;
+ private Map<Integer, List<Integer>> ansiIndex;
// internal mapping of glyph indexes to unicode indexes
// used for quick mappings in this class
- private final Map glyphToUnicodeMap = new java.util.HashMap();
- private final Map unicodeToGlyphMap = new java.util.HashMap();
+ private final Map<Integer, Integer> glyphToUnicodeMap = new HashMap<Integer, Integer> ();
+ private final Map<Integer, Integer> unicodeToGlyphMap = new HashMap<Integer, Integer> ();
private TTFDirTabEntry currentDirTab;
@@ -136,6 +232,10 @@ public class TTFFile {
*/
protected Log log = LogFactory.getLog(TTFFile.class);
+ public TTFFile() {
+ this(true, false);
+ }
+
/**
* Constructor
* @param useKerning true if kerning data should be loaded
@@ -147,9 +247,9 @@ public class TTFFile {
}
/**
- * Key-value helper class
+ * Key-value helper class.
*/
- class UnicodeMapping implements Comparable {
+ final class UnicodeMapping implements Comparable {
private final int unicodeIndex;
private final int glyphIndex;
@@ -217,28 +317,42 @@ public class TTFFile {
}
/**
+ * Version of the PostScript table (<q>post</q>) contained in this font.
+ */
+ public static enum PostScriptVersion {
+ /** PostScript table version 1.0. */
+ V1,
+ /** PostScript table version 2.0. */
+ V2,
+ /** PostScript table version 3.0. */
+ V3,
+ /** Unknown version of the PostScript table. */
+ UNKNOWN;
+ }
+
+ /**
* Obtain directory table entry.
* @param name (tag) of entry
* @return a directory table entry or null if none found
*/
- public TTFDirTabEntry getDirectoryEntry ( String name ) {
- return (TTFDirTabEntry) dirTabs.get ( name );
+ public TTFDirTabEntry getDirectoryEntry(TTFTableName name) {
+ return dirTabs.get(name);
}
/**
* Position inputstream to position indicated
* in the dirtab offset + offset
* @param in font file reader
- * @param name (tag) of table
+ * @param tableName (tag) of table
* @param offset from start of table
* @return true if seek succeeded
* @throws IOException if I/O exception occurs during seek
*/
- public boolean seekTab(FontFileReader in, String name,
+ public boolean seekTab(FontFileReader in, TTFTableName tableName,
long offset) throws IOException {
- TTFDirTabEntry dt = getDirectoryEntry ( name );
+ TTFDirTabEntry dt = dirTabs.get(tableName);
if (dt == null) {
- log.error("Dirtab " + name + " not found.");
+ log.error("Dirtab " + tableName.getName() + " not found.");
return false;
} else {
in.seekSet(dt.getOffset() + offset);
@@ -274,12 +388,12 @@ public class TTFFile {
* Set the unicodeIndex in the TTFMtxEntries and fills in the
* cmaps vector.
*/
- private boolean readCMAP(FontFileReader in) throws IOException {
+ private boolean readCMAP() throws IOException {
unicodeMappings = new java.util.TreeSet();
- seekTab(in, "cmap", 2);
- int numCMap = in.readTTFUShort(); // Number of cmap subtables
+ seekTab(fontFile, TTFTableName.CMAP, 2);
+ int numCMap = fontFile.readTTFUShort(); // Number of cmap subtables
long cmapUniOffset = 0;
long symbolMapOffset = 0;
@@ -289,9 +403,9 @@ public class TTFFile {
//Read offset for all tables. We are only interested in the unicode table
for (int i = 0; i < numCMap; i++) {
- int cmapPID = in.readTTFUShort();
- int cmapEID = in.readTTFUShort();
- long cmapOffset = in.readTTFULong();
+ int cmapPID = fontFile.readTTFUShort();
+ int cmapEID = fontFile.readTTFUShort();
+ long cmapOffset = fontFile.readTTFLong();
if (log.isDebugEnabled()) {
log.debug("Platform ID: " + cmapPID + " Encoding: " + cmapEID);
@@ -306,9 +420,9 @@ public class TTFFile {
}
if (cmapUniOffset > 0) {
- return readUnicodeCmap(in, cmapUniOffset, 1);
+ return readUnicodeCmap(cmapUniOffset, 1);
} else if (symbolMapOffset > 0) {
- return readUnicodeCmap(in, symbolMapOffset, 0);
+ return readUnicodeCmap(symbolMapOffset, 0);
} else {
log.fatal("Unsupported TrueType font: No Unicode or Symbol cmap table"
+ " not present. Aborting");
@@ -317,26 +431,26 @@ public class TTFFile {
}
private boolean readUnicodeCmap // CSOK: MethodLength
- (FontFileReader in, long cmapUniOffset, int encodingID)
+ (long cmapUniOffset, int encodingID)
throws IOException {
//Read CMAP table and correct mtxTab.index
int mtxPtr = 0;
// Read unicode cmap
- seekTab(in, "cmap", cmapUniOffset);
- int cmapFormat = in.readTTFUShort();
- /*int cmap_length =*/ in.readTTFUShort(); //skip cmap length
+ seekTab(fontFile, TTFTableName.CMAP, cmapUniOffset);
+ int cmapFormat = fontFile.readTTFUShort();
+ /*int cmap_length =*/ fontFile.readTTFUShort(); //skip cmap length
if (log.isDebugEnabled()) {
log.debug("CMAP format: " + cmapFormat);
}
if (cmapFormat == 4) {
- in.skip(2); // Skip version number
- int cmapSegCountX2 = in.readTTFUShort();
- int cmapSearchRange = in.readTTFUShort();
- int cmapEntrySelector = in.readTTFUShort();
- int cmapRangeShift = in.readTTFUShort();
+ fontFile.skip(2); // Skip version number
+ int cmapSegCountX2 = fontFile.readTTFUShort();
+ int cmapSearchRange = fontFile.readTTFUShort();
+ int cmapEntrySelector = fontFile.readTTFUShort();
+ int cmapRangeShift = fontFile.readTTFUShort();
if (log.isDebugEnabled()) {
log.debug("segCountX2 : " + cmapSegCountX2);
@@ -352,26 +466,26 @@ public class TTFFile {
int[] cmapRangeOffsets = new int[cmapSegCountX2 / 2];
for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapEndCounts[i] = in.readTTFUShort();
+ cmapEndCounts[i] = fontFile.readTTFUShort();
}
- in.skip(2); // Skip reservedPad
+ fontFile.skip(2); // Skip reservedPad
for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapStartCounts[i] = in.readTTFUShort();
+ cmapStartCounts[i] = fontFile.readTTFUShort();
}
for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapDeltas[i] = in.readTTFShort();
+ cmapDeltas[i] = fontFile.readTTFShort();
}
//int startRangeOffset = in.getCurrentPos();
for (int i = 0; i < (cmapSegCountX2 / 2); i++) {
- cmapRangeOffsets[i] = in.readTTFUShort();
+ cmapRangeOffsets[i] = fontFile.readTTFUShort();
}
- int glyphIdArrayOffset = in.getCurrentPos();
+ int glyphIdArrayOffset = fontFile.getCurrentPos();
BitSet eightBitGlyphs = new BitSet(256);
@@ -413,19 +527,17 @@ public class TTFFile {
+ (j - cmapStartCounts[i])
+ (i)
- cmapSegCountX2 / 2) * 2;
- in.seekSet(glyphOffset);
- glyphIdx = (in.readTTFUShort() + cmapDeltas[i])
+ fontFile.seekSet(glyphOffset);
+ glyphIdx = (fontFile.readTTFUShort() + cmapDeltas[i])
& 0xffff;
unicodeMappings.add(new UnicodeMapping(glyphIdx, j));
mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
// Also add winAnsiWidth
- List v = (List)ansiIndex.get(new Integer(j));
+ List<Integer> v = ansiIndex.get(new Integer(j));
if (v != null) {
- Iterator e = v.listIterator();
- while (e.hasNext()) {
- Integer aIdx = (Integer)e.next();
+ for (Integer aIdx : v) {
ansiWidth[aIdx.intValue()]
= mtxTab[glyphIdx].getWx();
@@ -466,11 +578,9 @@ public class TTFFile {
}
// Also add winAnsiWidth
- List v = (List)ansiIndex.get(new Integer(j));
+ List<Integer> v = ansiIndex.get(new Integer(j));
if (v != null) {
- Iterator e = v.listIterator();
- while (e.hasNext()) {
- Integer aIdx = (Integer)e.next();
+ for (Integer aIdx : v) {
ansiWidth[aIdx.intValue()] = mtxTab[glyphIdx].getWx();
}
}
@@ -548,14 +658,14 @@ public class TTFFile {
// Create an index hash to the ansiWidth
// Can't just index the winAnsiEncoding when inserting widths
// same char (eg bullet) is repeated more than one place
- ansiIndex = new java.util.HashMap();
+ ansiIndex = new HashMap<Integer, List<Integer>>();
for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
Integer ansi = new Integer(i);
Integer uni = new Integer(Glyphs.WINANSI_ENCODING[i]);
- List v = (List)ansiIndex.get(uni);
+ List<Integer> v = ansiIndex.get(uni);
if (v == null) {
- v = new java.util.ArrayList();
+ v = new ArrayList<Integer>();
ansiIndex.put(uni, v);
}
v.add(ansi);
@@ -574,12 +684,12 @@ public class TTFFile {
* @throws IOException In case of an I/O problem
*/
public boolean readFont(FontFileReader in, String name) throws IOException {
-
+ fontFile = in;
/*
* Check if TrueType collection, and that the name
* exists in the collection
*/
- if (!checkTTC(in, name)) {
+ if (!checkTTC(name)) {
if (name == null) {
throw new IllegalArgumentException(
"For TrueType collection you must specify which font "
@@ -590,26 +700,26 @@ public class TTFFile {
}
}
- readDirTabs(in);
- readFontHeader(in);
- getNumGlyphs(in);
+ readDirTabs();
+ readFontHeader();
+ getNumGlyphs();
if (log.isDebugEnabled()) {
log.debug("Number of glyphs in font: " + numberOfGlyphs);
}
- readHorizontalHeader(in);
- readHorizontalMetrics(in);
+ readHorizontalHeader();
+ readHorizontalMetrics();
initAnsiWidths();
- readPostScript(in);
- readOS2(in);
+ readPostScript();
+ readOS2();
determineAscDesc();
if (!isCFF) {
- readIndexToLocation(in);
- readGlyf(in);
+ readIndexToLocation();
+ readGlyf();
}
- readName(in);
- boolean pcltFound = readPCLT(in);
+ readName();
+ boolean pcltFound = readPCLT();
// Read cmap table and fill in ansiwidths
- boolean valid = readCMAP(in);
+ boolean valid = readCMAP();
if (!valid) {
return false;
}
@@ -617,7 +727,7 @@ public class TTFFile {
createCMaps();
if ( useKerning ) {
- readKerning(in);
+ readKerning();
}
// Read advanced typographic tables.
@@ -640,33 +750,47 @@ public class TTFFile {
return true;
}
+ /**
+ * Reads a font.
+ *
+ * @param in FontFileReader to read from
+ * @param name Name to be checked for in the font file
+ * @param glyphs Map of glyphs (glyphs has old index as (Integer) key and
+ * new index as (Integer) value)
+ * @throws IOException in case of an I/O problem
+ */
+ public void readFont(FontFileReader in, String name,
+ Map<Integer, Integer> glyphs) throws IOException {
+ readFont(in, name);
+ }
+
private void createCMaps() {
- cmaps = new java.util.ArrayList();
- TTFCmapEntry tce = new TTFCmapEntry();
+ cmaps = new ArrayList<CMapSegment>();
+ int unicodeStart;
+ int glyphStart;
+ int unicodeEnd;
- Iterator e = unicodeMappings.iterator();
- UnicodeMapping um = (UnicodeMapping)e.next();
+ Iterator<UnicodeMapping> e = unicodeMappings.iterator();
+ UnicodeMapping um = e.next();
UnicodeMapping lastMapping = um;
- tce.setUnicodeStart(um.getUnicodeIndex());
- tce.setGlyphStartIndex(um.getGlyphIndex());
+ unicodeStart = um.getUnicodeIndex();
+ glyphStart = um.getGlyphIndex();
while (e.hasNext()) {
- um = (UnicodeMapping)e.next();
+ um = e.next();
if (((lastMapping.getUnicodeIndex() + 1) != um.getUnicodeIndex())
|| ((lastMapping.getGlyphIndex() + 1) != um.getGlyphIndex())) {
- tce.setUnicodeEnd(lastMapping.getUnicodeIndex());
- cmaps.add(tce);
-
- tce = new TTFCmapEntry();
- tce.setUnicodeStart(um.getUnicodeIndex());
- tce.setGlyphStartIndex(um.getGlyphIndex());
+ unicodeEnd = lastMapping.getUnicodeIndex();
+ cmaps.add(new CMapSegment(unicodeStart, unicodeEnd, glyphStart));
+ unicodeStart = um.getUnicodeIndex();
+ glyphStart = um.getGlyphIndex();
}
lastMapping = um;
}
- tce.setUnicodeEnd(um.getUnicodeIndex());
- cmaps.add(tce);
+ unicodeEnd = lastMapping.getUnicodeIndex();
+ cmaps.add(new CMapSegment(unicodeStart, unicodeEnd, glyphStart));
}
/**
@@ -681,11 +805,15 @@ public class TTFFile {
}
}
+ PostScriptVersion getPostScriptVersion() {
+ return postScriptVersion;
+ }
+
/**
* Returns the font family names of the font.
* @return Set The family names (a Set of Strings)
*/
- public Set getFamilyNames() {
+ public Set<String> getFamilyNames() {
return familyNames;
}
@@ -730,19 +858,30 @@ public class TTFFile {
}
/**
+ * Returns the number of bytes necessary to pad the currentPosition so that a table begins
+ * on a 4-byte boundary.
+ * @param currentPosition the position to pad.
+ * @return int the number of bytes to pad.
+ */
+ protected int getPadSize(int currentPosition) {
+ int padSize = 4 - (currentPosition % 4);
+ return padSize < 4 ? padSize : 0;
+ }
+
+ /**
* Returns the Flags attribute of the font.
* @return int The Flags
*/
public int getFlags() {
int flags = 32; // Use Adobe Standard charset
if (italicAngle != 0) {
- flags = flags | 64;
+ flags |= 64;
}
if (isFixedPitch != 0) {
- flags = flags | 2;
+ flags |= 2;
}
if (hasSerifs) {
- flags = flags | 1;
+ flags |= 1;
}
return flags;
}
@@ -780,7 +919,6 @@ public class TTFFile {
}
/**
- * Returns the font bounding box.
* @return int[] The font bbox
*/
public int[] getFontBBox() {
@@ -886,11 +1024,10 @@ public class TTFFile {
* FontFileReader and fill the global HashMap dirTabs
* with the table name (String) as key and a TTFDirTabEntry
* as value.
- * @param in FontFileReader to read the table directory from
* @throws IOException in case of an I/O problem
*/
- protected void readDirTabs(FontFileReader in) throws IOException {
- int sfntVersion = in.readTTFLong(); // TTF_FIXED_SIZE (4 bytes)
+ protected void readDirTabs() throws IOException {
+ int sfntVersion = fontFile.readTTFLong(); // TTF_FIXED_SIZE (4 bytes)
switch (sfntVersion) {
case 0x10000:
log.debug("sfnt version: OpenType 1.0");
@@ -909,42 +1046,45 @@ public class TTFFile {
log.debug("Unknown sfnt version: " + Integer.toHexString(sfntVersion));
break;
}
- int ntabs = in.readTTFUShort();
- in.skip(6); // 3xTTF_USHORT_SIZE
+ int ntabs = fontFile.readTTFUShort();
+ fontFile.skip(6); // 3xTTF_USHORT_SIZE
- dirTabs = new java.util.HashMap();
+ dirTabs = new HashMap<TTFTableName, TTFDirTabEntry>();
TTFDirTabEntry[] pd = new TTFDirTabEntry[ntabs];
log.debug("Reading " + ntabs + " dir tables");
+
for (int i = 0; i < ntabs; i++) {
pd[i] = new TTFDirTabEntry();
- dirTabs.put(pd[i].read(in), pd[i]);
+ String tableName = pd[i].read(fontFile);
+ dirTabs.put(TTFTableName.getValue(tableName), pd[i]);
}
+ dirTabs.put(TTFTableName.TABLE_DIRECTORY,
+ new TTFDirTabEntry(0L, fontFile.getCurrentPos()));
log.debug("dir tables: " + dirTabs.keySet());
}
/**
* Read the "head" table, this reads the bounding box and
* sets the upem (unitsPerEM) variable
- * @param in FontFileReader to read the header from
* @throws IOException in case of an I/O problem
*/
- protected void readFontHeader(FontFileReader in) throws IOException {
- seekTab(in, "head", 2 * 4 + 2 * 4);
- int flags = in.readTTFUShort();
+ protected void readFontHeader() throws IOException {
+ seekTab(fontFile, TTFTableName.HEAD, 2 * 4 + 2 * 4);
+ int flags = fontFile.readTTFUShort();
if (log.isDebugEnabled()) {
log.debug("flags: " + flags + " - " + Integer.toString(flags, 2));
}
- upem = in.readTTFUShort();
+ upem = fontFile.readTTFUShort();
if (log.isDebugEnabled()) {
log.debug("unit per em: " + upem);
}
- in.skip(16);
+ fontFile.skip(16);
- fontBBox1 = in.readTTFShort();
- fontBBox2 = in.readTTFShort();
- fontBBox3 = in.readTTFShort();
- fontBBox4 = in.readTTFShort();
+ fontBBox1 = fontFile.readTTFShort();
+ fontBBox2 = fontFile.readTTFShort();
+ fontBBox3 = fontFile.readTTFShort();
+ fontBBox4 = fontFile.readTTFShort();
if (log.isDebugEnabled()) {
log.debug("font bbox: xMin=" + fontBBox1
+ " yMin=" + fontBBox2
@@ -952,19 +1092,18 @@ public class TTFFile {
+ " yMax=" + fontBBox4);
}
- in.skip(2 + 2 + 2);
+ fontFile.skip(2 + 2 + 2);
- locaFormat = in.readTTFShort();
+ locaFormat = fontFile.readTTFShort();
}
/**
* Read the number of glyphs from the "maxp" table
- * @param in FontFileReader to read the number of glyphs from
* @throws IOException in case of an I/O problem
*/
- protected void getNumGlyphs(FontFileReader in) throws IOException {
- seekTab(in, "maxp", 4);
- numberOfGlyphs = in.readTTFUShort();
+ protected void getNumGlyphs() throws IOException {
+ seekTab(fontFile, TTFTableName.MAXP, 4);
+ numberOfGlyphs = fontFile.readTTFUShort();
}
@@ -972,17 +1111,16 @@ public class TTFFile {
* Read the "hhea" table to find the ascender and descender and
* size of "hmtx" table, as a fixed size font might have only
* one width.
- * @param in FontFileReader to read the hhea table from
* @throws IOException in case of an I/O problem
*/
- protected void readHorizontalHeader(FontFileReader in)
+ protected void readHorizontalHeader()
throws IOException {
- seekTab(in, "hhea", 4);
- hheaAscender = in.readTTFShort();
- hheaDescender = in.readTTFShort();
+ seekTab(fontFile, TTFTableName.HHEA, 4);
+ hheaAscender = fontFile.readTTFShort();
+ hheaDescender = fontFile.readTTFShort();
- in.skip(2 + 2 + 3 * 2 + 8 * 2);
- nhmtx = in.readTTFUShort();
+ fontFile.skip(2 + 2 + 3 * 2 + 8 * 2);
+ nhmtx = fontFile.readTTFUShort();
if (log.isDebugEnabled()) {
log.debug("hhea.Ascender: " + formatUnitsForDebug(hheaAscender));
@@ -996,12 +1134,11 @@ public class TTFFile {
* in the mtxTab array. If the number of metrics is less
* than the number of glyphs (eg fixed size fonts), extend
* the mtxTab array and fill in the missing widths
- * @param in FontFileReader to read the hmtx table from
* @throws IOException in case of an I/O problem
*/
- protected void readHorizontalMetrics(FontFileReader in)
+ protected void readHorizontalMetrics()
throws IOException {
- seekTab(in, "hmtx", 0);
+ seekTab(fontFile, TTFTableName.HMTX, 0);
int mtxSize = Math.max(numberOfGlyphs, nhmtx);
mtxTab = new TTFMtxEntry[mtxSize];
@@ -1013,8 +1150,8 @@ public class TTFFile {
mtxTab[i] = new TTFMtxEntry();
}
for (int i = 0; i < nhmtx; i++) {
- mtxTab[i].setWx(in.readTTFUShort());
- mtxTab[i].setLsb(in.readTTFUShort());
+ mtxTab[i].setWx(fontFile.readTTFUShort());
+ mtxTab[i].setLsb(fontFile.readTTFUShort());
if (log.isTraceEnabled()) {
log.trace(" width[" + i + "] = "
@@ -1027,7 +1164,7 @@ public class TTFFile {
int lastWidth = mtxTab[nhmtx - 1].getWx();
for (int i = nhmtx; i < mtxSize; i++) {
mtxTab[i].setWx(lastWidth);
- mtxTab[i].setLsb(in.readTTFUShort());
+ mtxTab[i].setLsb(fontFile.readTTFUShort());
}
}
}
@@ -1037,35 +1174,37 @@ public class TTFFile {
* Read the "post" table
* containing the PostScript names of the glyphs.
*/
- private void readPostScript(FontFileReader in) throws IOException {
- seekTab(in, "post", 0);
- postFormat = in.readTTFLong();
- italicAngle = in.readTTFULong();
- underlinePosition = in.readTTFShort();
- underlineThickness = in.readTTFShort();
- isFixedPitch = in.readTTFULong();
+ private void readPostScript() throws IOException {
+ seekTab(fontFile, TTFTableName.POST, 0);
+ int postFormat = fontFile.readTTFLong();
+ italicAngle = fontFile.readTTFULong();
+ underlinePosition = fontFile.readTTFShort();
+ underlineThickness = fontFile.readTTFShort();
+ isFixedPitch = fontFile.readTTFULong();
//Skip memory usage values
- in.skip(4 * 4);
+ fontFile.skip(4 * 4);
log.debug("PostScript format: 0x" + Integer.toHexString(postFormat));
switch (postFormat) {
case 0x00010000:
log.debug("PostScript format 1");
- for (int i = 0; i < Glyphs.MAC_GLYPH_NAMES.length; i++) {
- mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[i]);
+ postScriptVersion = PostScriptVersion.V1;
+ for (int i = 0; i < MAC_GLYPH_ORDERING.length; i++) {
+ mtxTab[i].setName(MAC_GLYPH_ORDERING[i]);
}
break;
case 0x00020000:
log.debug("PostScript format 2");
+ postScriptVersion = PostScriptVersion.V2;
int numGlyphStrings = 0;
// Read Number of Glyphs
- int l = in.readTTFUShort();
+ int l = fontFile.readTTFUShort();
// Read indexes
for (int i = 0; i < l; i++) {
- mtxTab[i].setIndex(in.readTTFUShort());
+ mtxTab[i].setIndex(fontFile.readTTFUShort());
if (mtxTab[i].getIndex() > 257) {
//Index is not in the Macintosh standard set
@@ -1085,16 +1224,16 @@ public class TTFFile {
+ " set. Total number of glyphs=" + l);
}
for (int i = 0; i < psGlyphsBuffer.length; i++) {
- psGlyphsBuffer[i] = in.readTTFString(in.readTTFUByte());
+ psGlyphsBuffer[i] = fontFile.readTTFString(fontFile.readTTFUByte());
}
//Set glyph names
for (int i = 0; i < l; i++) {
- if (mtxTab[i].getIndex() < NMACGLYPHS) {
- mtxTab[i].setName(Glyphs.MAC_GLYPH_NAMES[mtxTab[i].getIndex()]);
+ if (mtxTab[i].getIndex() < MAC_GLYPH_ORDERING.length) {
+ mtxTab[i].setName(MAC_GLYPH_ORDERING[mtxTab[i].getIndex()]);
} else {
if (!mtxTab[i].isIndexReserved()) {
- int k = mtxTab[i].getIndex() - NMACGLYPHS;
+ int k = mtxTab[i].getIndex() - MAC_GLYPH_ORDERING.length;
if (log.isTraceEnabled()) {
log.trace(k + " i=" + i + " mtx=" + mtxTab.length
@@ -1110,9 +1249,11 @@ public class TTFFile {
case 0x00030000:
// PostScript format 3 contains no glyph names
log.debug("PostScript format 3");
+ postScriptVersion = PostScriptVersion.V3;
break;
default:
log.error("Unknown PostScript format: " + postFormat);
+ postScriptVersion = PostScriptVersion.UNKNOWN;
}
}
@@ -1120,60 +1261,60 @@ public class TTFFile {
/**
* Read the "OS/2" table
*/
- private void readOS2(FontFileReader in) throws IOException {
+ private void readOS2() throws IOException {
// Check if font is embeddable
- TTFDirTabEntry os2Entry = getDirectoryEntry ( "OS/2" );
+ TTFDirTabEntry os2Entry = dirTabs.get(TTFTableName.OS2);
if (os2Entry != null) {
- seekTab(in, "OS/2", 0);
- int version = in.readTTFUShort();
+ seekTab(fontFile, TTFTableName.OS2, 0);
+ int version = fontFile.readTTFUShort();
if (log.isDebugEnabled()) {
log.debug("OS/2 table: version=" + version
+ ", offset=" + os2Entry.getOffset() + ", len=" + os2Entry.getLength());
}
- in.skip(2); //xAvgCharWidth
- this.usWeightClass = in.readTTFUShort();
+ fontFile.skip(2); //xAvgCharWidth
+ this.usWeightClass = fontFile.readTTFUShort();
// usWidthClass
- in.skip(2);
+ fontFile.skip(2);
- int fsType = in.readTTFUShort();
+ int fsType = fontFile.readTTFUShort();
if (fsType == 2) {
isEmbeddable = false;
} else {
isEmbeddable = true;
}
- in.skip(11 * 2);
- in.skip(10); //panose array
- in.skip(4 * 4); //unicode ranges
- in.skip(4);
- in.skip(3 * 2);
+ fontFile.skip(11 * 2);
+ fontFile.skip(10); //panose array
+ fontFile.skip(4 * 4); //unicode ranges
+ fontFile.skip(4);
+ fontFile.skip(3 * 2);
int v;
- os2Ascender = in.readTTFShort(); //sTypoAscender
- os2Descender = in.readTTFShort(); //sTypoDescender
+ os2Ascender = fontFile.readTTFShort(); //sTypoAscender
+ os2Descender = fontFile.readTTFShort(); //sTypoDescender
if (log.isDebugEnabled()) {
log.debug("sTypoAscender: " + os2Ascender
+ " -> internal " + convertTTFUnit2PDFUnit(os2Ascender));
log.debug("sTypoDescender: " + os2Descender
+ " -> internal " + convertTTFUnit2PDFUnit(os2Descender));
}
- v = in.readTTFShort(); //sTypoLineGap
+ v = fontFile.readTTFShort(); //sTypoLineGap
if (log.isDebugEnabled()) {
log.debug("sTypoLineGap: " + v);
}
- v = in.readTTFUShort(); //usWinAscent
+ v = fontFile.readTTFUShort(); //usWinAscent
if (log.isDebugEnabled()) {
log.debug("usWinAscent: " + formatUnitsForDebug(v));
}
- v = in.readTTFUShort(); //usWinDescent
+ v = fontFile.readTTFUShort(); //usWinDescent
if (log.isDebugEnabled()) {
log.debug("usWinDescent: " + formatUnitsForDebug(v));
}
//version 1 OS/2 table might end here
if (os2Entry.getLength() >= 78 + (2 * 4) + (2 * 2)) {
- in.skip(2 * 4);
- this.os2xHeight = in.readTTFShort(); //sxHeight
- this.os2CapHeight = in.readTTFShort(); //sCapHeight
+ fontFile.skip(2 * 4);
+ this.os2xHeight = fontFile.readTTFShort(); //sxHeight
+ this.os2CapHeight = fontFile.readTTFShort(); //sCapHeight
if (log.isDebugEnabled()) {
log.debug("sxHeight: " + this.os2xHeight);
log.debug("sCapHeight: " + this.os2CapHeight);
@@ -1187,42 +1328,40 @@ public class TTFFile {
/**
* Read the "loca" table.
- * @param in FontFileReader to read from
* @throws IOException In case of a I/O problem
*/
- protected final void readIndexToLocation(FontFileReader in)
+ protected final void readIndexToLocation()
throws IOException {
- if (!seekTab(in, "loca", 0)) {
+ if (!seekTab(fontFile, TTFTableName.LOCA, 0)) {
throw new IOException("'loca' table not found, happens when the font file doesn't"
+ " contain TrueType outlines (trying to read an OpenType CFF font maybe?)");
}
for (int i = 0; i < numberOfGlyphs; i++) {
- mtxTab[i].setOffset(locaFormat == 1 ? in.readTTFULong()
- : (in.readTTFUShort() << 1));
+ mtxTab[i].setOffset(locaFormat == 1 ? fontFile.readTTFULong()
+ : (fontFile.readTTFUShort() << 1));
}
- lastLoca = (locaFormat == 1 ? in.readTTFULong()
- : (in.readTTFUShort() << 1));
+ lastLoca = (locaFormat == 1 ? fontFile.readTTFULong()
+ : (fontFile.readTTFUShort() << 1));
}
/**
* Read the "glyf" table to find the bounding boxes.
- * @param in FontFileReader to read from
* @throws IOException In case of a I/O problem
*/
- private void readGlyf(FontFileReader in) throws IOException {
- TTFDirTabEntry dirTab = getDirectoryEntry ( "glyf" );
+ private void readGlyf() throws IOException {
+ TTFDirTabEntry dirTab = dirTabs.get(TTFTableName.GLYF);
if (dirTab == null) {
throw new IOException("glyf table not found, cannot continue");
}
for (int i = 0; i < (numberOfGlyphs - 1); i++) {
if (mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- in.seekSet(dirTab.getOffset() + mtxTab[i].getOffset());
- in.skip(2);
+ fontFile.seekSet(dirTab.getOffset() + mtxTab[i].getOffset());
+ fontFile.skip(2);
final int[] bbox = {
- in.readTTFShort(),
- in.readTTFShort(),
- in.readTTFShort(),
- in.readTTFShort()};
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort()};
mtxTab[i].setBoundingBox(bbox);
} else {
mtxTab[i].setBoundingBox(mtxTab[0].getBoundingBox());
@@ -1230,17 +1369,17 @@ public class TTFFile {
}
- long n = dirTab.getOffset();
+ long n = (dirTabs.get(TTFTableName.GLYF)).getOffset();
for (int i = 0; i < numberOfGlyphs; i++) {
if ((i + 1) >= mtxTab.length
|| mtxTab[i].getOffset() != mtxTab[i + 1].getOffset()) {
- in.seekSet(n + mtxTab[i].getOffset());
- in.skip(2);
+ fontFile.seekSet(n + mtxTab[i].getOffset());
+ fontFile.skip(2);
final int[] bbox = {
- in.readTTFShort(),
- in.readTTFShort(),
- in.readTTFShort(),
- in.readTTFShort()};
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort(),
+ fontFile.readTTFShort()};
mtxTab[i].setBoundingBox(bbox);
} else {
/**@todo Verify that this is correct, looks like a copy/paste bug (jm)*/
@@ -1261,34 +1400,33 @@ public class TTFFile {
/**
* Read the "name" table.
- * @param in FontFileReader to read from
* @throws IOException In case of a I/O problem
*/
- private void readName(FontFileReader in) throws IOException {
- seekTab(in, "name", 2);
- int i = in.getCurrentPos();
- int n = in.readTTFUShort();
- int j = in.readTTFUShort() + i - 2;
+ private void readName() throws IOException {
+ seekTab(fontFile, TTFTableName.NAME, 2);
+ int i = fontFile.getCurrentPos();
+ int n = fontFile.readTTFUShort();
+ int j = fontFile.readTTFUShort() + i - 2;
i += 2 * 2;
while (n-- > 0) {
// getLogger().debug("Iteration: " + n);
- in.seekSet(i);
- final int platformID = in.readTTFUShort();
- final int encodingID = in.readTTFUShort();
- final int languageID = in.readTTFUShort();
+ fontFile.seekSet(i);
+ final int platformID = fontFile.readTTFUShort();
+ final int encodingID = fontFile.readTTFUShort();
+ final int languageID = fontFile.readTTFUShort();
- int k = in.readTTFUShort();
- int l = in.readTTFUShort();
+ int k = fontFile.readTTFUShort();
+ int l = fontFile.readTTFUShort();
if (((platformID == 1 || platformID == 3)
&& (encodingID == 0 || encodingID == 1))) {
- in.seekSet(j + in.readTTFUShort());
+ fontFile.seekSet(j + fontFile.readTTFUShort());
String txt;
if (platformID == 3) {
- txt = in.readTTFString(l, encodingID);
+ txt = fontFile.readTTFString(l, encodingID);
} else {
- txt = in.readTTFString(l);
+ txt = fontFile.readTTFString(l);
}
if (log.isDebugEnabled()) {
@@ -1332,21 +1470,20 @@ public class TTFFile {
/**
* Read the "PCLT" table to find xHeight and capHeight.
- * @param in FontFileReader to read from
* @throws IOException In case of a I/O problem
*/
- private boolean readPCLT(FontFileReader in) throws IOException {
- TTFDirTabEntry dirTab = getDirectoryEntry ( "PCLT" );
+ private boolean readPCLT() throws IOException {
+ TTFDirTabEntry dirTab = dirTabs.get(TTFTableName.PCLT);
if (dirTab != null) {
- in.seekSet(dirTab.getOffset() + 4 + 4 + 2);
- xHeight = in.readTTFUShort();
+ fontFile.seekSet(dirTab.getOffset() + 4 + 4 + 2);
+ xHeight = fontFile.readTTFUShort();
log.debug("xHeight from PCLT: " + formatUnitsForDebug(xHeight));
- in.skip(2 * 2);
- capHeight = in.readTTFUShort();
+ fontFile.skip(2 * 2);
+ capHeight = fontFile.readTTFUShort();
log.debug("capHeight from PCLT: " + formatUnitsForDebug(capHeight));
- in.skip(2 + 16 + 8 + 6 + 1 + 1);
+ fontFile.skip(2 + 16 + 8 + 6 + 1 + 1);
- int serifStyle = in.readTTFUByte();
+ int serifStyle = fontFile.readTTFUByte();
serifStyle = serifStyle >> 6;
serifStyle = serifStyle & 3;
if (serifStyle == 1) {
@@ -1476,19 +1613,18 @@ public class TTFFile {
/**
* Read the kerning table, create a table for both CIDs and
* winAnsiEncoding.
- * @param in FontFileReader to read from
* @throws IOException In case of a I/O problem
*/
- private void readKerning(FontFileReader in) throws IOException {
+ private void readKerning() throws IOException {
// Read kerning
- kerningTab = new java.util.HashMap();
- ansiKerningTab = new java.util.HashMap();
- TTFDirTabEntry dirTab = getDirectoryEntry ( "kern" );
+ kerningTab = new HashMap<Integer, Map<Integer, Integer>>();
+ ansiKerningTab = new HashMap<Integer, Map<Integer, Integer>>();
+ TTFDirTabEntry dirTab = dirTabs.get(TTFTableName.KERN);
if (dirTab != null) {
- seekTab(in, "kern", 2);
- for (int n = in.readTTFUShort(); n > 0; n--) {
- in.skip(2 * 2);
- int k = in.readTTFUShort();
+ seekTab(fontFile, TTFTableName.KERN, 2);
+ for (int n = fontFile.readTTFUShort(); n > 0; n--) {
+ fontFile.skip(2 * 2);
+ int k = fontFile.readTTFUShort();
if (!((k & 1) != 0) || (k & 2) != 0 || (k & 4) != 0) {
return;
}
@@ -1496,12 +1632,12 @@ public class TTFFile {
continue;
}
- k = in.readTTFUShort();
- in.skip(3 * 2);
+ k = fontFile.readTTFUShort();
+ fontFile.skip(3 * 2);
while (k-- > 0) {
- int i = in.readTTFUShort();
- int j = in.readTTFUShort();
- int kpx = in.readTTFShort();
+ int i = fontFile.readTTFUShort();
+ int j = fontFile.readTTFUShort();
+ int kpx = fontFile.readTTFShort();
if (kpx != 0) {
// CID kerning table entry, using unicode indexes
final Integer iObj = glyphToUnicode(i);
@@ -1515,9 +1651,9 @@ public class TTFFile {
log.debug("Ignoring kerning pair because Unicode index was"
+ " found for the second glyph " + i);
} else {
- Map adjTab = kerningTab.get(iObj);
+ Map<Integer, Integer> adjTab = kerningTab.get(iObj);
if (adjTab == null) {
- adjTab = new java.util.HashMap();
+ adjTab = new HashMap<Integer, Integer>();
}
adjTab.put(u2, new Integer(convertTTFUnit2PDFUnit(kpx)));
kerningTab.put(iObj, adjTab);
@@ -1529,16 +1665,12 @@ public class TTFFile {
// Create winAnsiEncoded kerning table from kerningTab
// (could probably be simplified, for now we remap back to CID indexes and
// then to winAnsi)
- Iterator ae = kerningTab.keySet().iterator();
- while (ae.hasNext()) {
- Integer unicodeKey1 = (Integer)ae.next();
+ for (Integer unicodeKey1 : kerningTab.keySet()) {
Integer cidKey1 = unicodeToGlyph(unicodeKey1.intValue());
- Map<Integer, Integer> akpx = new java.util.HashMap();
- Map ckpx = kerningTab.get(unicodeKey1);
+ Map<Integer, Integer> akpx = new HashMap<Integer, Integer>();
+ Map<Integer, Integer> ckpx = kerningTab.get(unicodeKey1);
- Iterator aee = ckpx.keySet().iterator();
- while (aee.hasNext()) {
- Integer unicodeKey2 = (Integer)aee.next();
+ for (Integer unicodeKey2 : ckpx.keySet()) {
Integer cidKey2 = unicodeToGlyph(unicodeKey2.intValue());
Integer kern = (Integer)ckpx.get(unicodeKey2);
@@ -1567,10 +1699,71 @@ public class TTFFile {
}
/**
- * Return a List with TTFCmapEntry.
- * @return A list of TTFCmapEntry objects
+ * Streams a font.
+ * @param ttfOut The interface for streaming TrueType tables.
+ * @exception IOException file write error
+ */
+ public void stream(TTFOutputStream ttfOut) throws IOException {
+ SortedSet<Map.Entry<TTFTableName, TTFDirTabEntry>> sortedDirTabs = sortDirTabMap(dirTabs);
+ byte[] file = fontFile.getAllBytes();
+ TTFTableOutputStream tableOut = ttfOut.getTableOutputStream();
+ TTFGlyphOutputStream glyphOut = ttfOut.getGlyphOutputStream();
+ ttfOut.startFontStream();
+ for (Map.Entry<TTFTableName, TTFDirTabEntry> entry : sortedDirTabs) {
+ int offset = (int) entry.getValue().getOffset();
+ int paddedLength = (int) entry.getValue().getLength();
+ paddedLength += getPadSize(offset + paddedLength);
+ if (entry.getKey().equals(TTFTableName.GLYF)) {
+ streamGlyf(glyphOut, file, offset, paddedLength);
+ } else {
+ tableOut.streamTable(file, offset, paddedLength);
+ }
+ }
+ ttfOut.endFontStream();
+ }
+
+ private void streamGlyf(TTFGlyphOutputStream glyphOut, byte[] fontFile, int tableOffset,
+ int tableLength) throws IOException {
+ //Stream all but the last glyph
+ int glyphStart = 0;
+ int glyphEnd = 0;
+ glyphOut.startGlyphStream();
+ for (int i = 0; i < mtxTab.length - 1; i++) {
+ glyphStart = (int) mtxTab[i].getOffset() + tableOffset;
+ glyphEnd = (int) mtxTab[i + 1].getOffset() + tableOffset;
+ glyphOut.streamGlyph(fontFile, glyphStart, glyphEnd - glyphStart);
+ }
+ glyphOut.streamGlyph(fontFile, glyphEnd, (tableOffset + tableLength) - glyphEnd);
+ glyphOut.endGlyphStream();
+ }
+
+ /**
+ * Returns the order in which the tables in a TrueType font should be written to file.
+ * @param directoryTabs the map that is to be sorted.
+ * @return TTFTablesNames[] an array of table names sorted in the order they should appear in
+ * the TTF file.
*/
- public List getCMaps() {
+ SortedSet<Map.Entry<TTFTableName, TTFDirTabEntry>>
+ sortDirTabMap(Map<TTFTableName, TTFDirTabEntry> directoryTabs) {
+ SortedSet<Map.Entry<TTFTableName, TTFDirTabEntry>> sortedSet
+ = new TreeSet<Map.Entry<TTFTableName, TTFDirTabEntry>>(
+ new Comparator<Map.Entry<TTFTableName, TTFDirTabEntry>>() {
+
+ public int compare(Entry<TTFTableName, TTFDirTabEntry> o1,
+ Entry<TTFTableName, TTFDirTabEntry> o2) {
+ return (int) (o1.getValue().getOffset() - o2.getValue().getOffset());
+ }
+ });
+ sortedSet.addAll(directoryTabs.entrySet());
+ return sortedSet;
+ }
+
+ /**
+ * Returns this font's character to glyph mapping.
+ *
+ * @return the font's cmap
+ */
+ public List<CMapSegment> getCMaps() {
return cmaps;
}
@@ -1579,24 +1772,23 @@ public class TTFFile {
* name exists in the collection.
* If it does, set offset in fontfile to the beginning of
* the Table Directory for that font.
- * @param in FontFileReader to read from
* @param name The name to check
* @return True if not collection or font name present, false otherwise
* @throws IOException In case of an I/O problem
*/
- protected final boolean checkTTC(FontFileReader in, String name) throws IOException {
- String tag = in.readTTFString(4);
+ protected final boolean checkTTC(String name) throws IOException {
+ String tag = fontFile.readTTFString(4);
if ("ttcf".equals(tag)) {
// This is a TrueType Collection
- in.skip(4);
+ fontFile.skip(4);
// Read directory offsets
- int numDirectories = (int)in.readTTFULong();
+ int numDirectories = (int)fontFile.readTTFULong();
// int numDirectories=in.readTTFUShort();
long[] dirOffsets = new long[numDirectories];
for (int i = 0; i < numDirectories; i++) {
- dirOffsets[i] = in.readTTFULong();
+ dirOffsets[i] = fontFile.readTTFULong();
}
log.info("This is a TrueType collection file with "
@@ -1610,10 +1802,10 @@ public class TTFFile {
// Is found, just to show all the names
long dirTabOffset = 0;
for (int i = 0; (i < numDirectories); i++) {
- in.seekSet(dirOffsets[i]);
- readDirTabs(in);
+ fontFile.seekSet(dirOffsets[i]);
+ readDirTabs();
- readName(in);
+ readName();
if (fullName.equals(name)) {
found = true;
@@ -1631,10 +1823,10 @@ public class TTFFile {
subFamilyName = "";
}
- in.seekSet(dirTabOffset);
+ fontFile.seekSet(dirTabOffset);
return found;
} else {
- in.seekSet(0);
+ fontFile.seekSet(0);
return true;
}
}
@@ -1646,8 +1838,7 @@ public class TTFFile {
* @throws IOException In case of an I/O problem
*/
public final List<String> getTTCnames(FontFileReader in) throws IOException {
- List<String> fontNames = new java.util.ArrayList<String>();
-
+ List<String> fontNames = new ArrayList<String>();
String tag = in.readTTFString(4);
if ("ttcf".equals(tag)) {
@@ -1667,9 +1858,9 @@ public class TTFFile {
for (int i = 0; (i < numDirectories); i++) {
in.seekSet(dirOffsets[i]);
- readDirTabs(in);
+ readDirTabs();
- readName(in);
+ readName();
log.info(fullName);
fontNames.add(fullName);
@@ -1695,13 +1886,13 @@ public class TTFFile {
* doesn't matter...
*/
private Integer[] unicodeToWinAnsi(int unicode) {
- List ret = new java.util.ArrayList();
+ List<Integer> ret = new ArrayList<Integer>();
for (int i = 32; i < Glyphs.WINANSI_ENCODING.length; i++) {
if (unicode == Glyphs.WINANSI_ENCODING[i]) {
ret.add(new Integer(i));
}
}
- return (Integer[])ret.toArray(new Integer[0]);
+ return ret.toArray(new Integer[0]);
}
/**
@@ -1744,7 +1935,7 @@ public class TTFFile {
* @return unicode code point
*/
private Integer glyphToUnicode(int glyphIndex) {
- return (Integer) glyphToUnicodeMap.get(new Integer(glyphIndex));
+ return glyphToUnicodeMap.get(new Integer(glyphIndex));
}
/**
@@ -1755,7 +1946,7 @@ public class TTFFile {
*/
private Integer unicodeToGlyph(int unicodeIndex) throws IOException {
final Integer result
- = (Integer) unicodeToGlyphMap.get(new Integer(unicodeIndex));
+ = unicodeToGlyphMap.get(new Integer(unicodeIndex));
if (result == null) {
throw new IOException(
"Glyph index not found for unicode value " + unicodeIndex);
@@ -1763,6 +1954,10 @@ public class TTFFile {
return result;
}
+ String getGlyphName(int glyphIndex) {
+ return mtxTab[glyphIndex].getName();
+ }
+
/**
* Determine if advanced (typographic) table is present.
* @return true if advanced (typographic) table is present
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
index c03f0fb6a..1410239ee 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFontLoader.java
@@ -21,17 +21,14 @@ package org.apache.fop.fonts.truetype;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.io.IOUtils;
-import org.apache.xmlgraphics.fonts.Glyphs;
-
-import org.apache.fop.fonts.BFEntry;
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;
@@ -39,6 +36,8 @@ import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.NamedCharacter;
import org.apache.fop.fonts.SingleByteFont;
+import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
+import org.apache.fop.util.HexEncoder;
/**
* Loads a TrueType font into memory directly from the original font file.
@@ -49,6 +48,7 @@ public class TTFFontLoader extends FontLoader {
private SingleByteFont singleFont;
private final String subFontName;
private EncodingMode encodingMode;
+ private EmbeddingMode embeddingMode;
/**
* Default constructor
@@ -56,7 +56,7 @@ public class TTFFontLoader extends FontLoader {
* @param resolver the FontResolver for font URI resolution
*/
public TTFFontLoader(String fontFileURI, FontResolver resolver) {
- this(fontFileURI, null, true, EncodingMode.AUTO, true, true, resolver);
+ this(fontFileURI, null, true, EmbeddingMode.AUTO, EncodingMode.AUTO, true, true, resolver);
}
/**
@@ -65,24 +65,28 @@ public class TTFFontLoader extends FontLoader {
* @param subFontName the sub-fontname of a font in a TrueType Collection (or null for normal
* TrueType fonts)
* @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 useKerning true to enable loading kerning info if available, false to disable
* @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, EncodingMode encodingMode, boolean useKerning,
- boolean useAdvanced, FontResolver resolver) {
+ boolean embedded, EmbeddingMode embeddingMode, EncodingMode encodingMode,
+ boolean useKerning, boolean useAdvanced, FontResolver resolver) {
super(fontFileURI, embedded, useKerning, useAdvanced, resolver);
this.subFontName = subFontName;
this.encodingMode = encodingMode;
+ this.embeddingMode = embeddingMode;
if (this.encodingMode == EncodingMode.AUTO) {
this.encodingMode = EncodingMode.CID; //Default to CID mode for TrueType
}
+ if (this.embeddingMode == EmbeddingMode.AUTO) {
+ this.embeddingMode = EmbeddingMode.SUBSET;
+ }
}
/** {@inheritDoc} */
- @Override
protected void read() throws IOException {
read(this.subFontName);
}
@@ -145,29 +149,20 @@ public class TTFFontLoader extends FontLoader {
returnFont.setItalicAngle(Integer.parseInt(ttf.getItalicAngle()));
returnFont.setMissingWidth(0);
returnFont.setWeight(ttf.getWeightClass());
-
+ returnFont.setEmbeddingMode(this.embeddingMode);
if (isCid) {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
int[] wx = ttf.getWidths();
multiFont.setWidthArray(wx);
- List entries = ttf.getCMaps();
- BFEntry[] bfentries = new BFEntry[entries.size()];
- int pos = 0;
- Iterator iter = ttf.getCMaps().listIterator();
- while (iter.hasNext()) {
- TTFCmapEntry ce = (TTFCmapEntry)iter.next();
- bfentries[pos] = new BFEntry(ce.getUnicodeStart(), ce.getUnicodeEnd(),
- ce.getGlyphStartIndex());
- pos++;
- }
- multiFont.setBFEntries(bfentries);
} else {
singleFont.setFontType(FontType.TRUETYPE);
singleFont.setEncoding(ttf.getCharSetName());
returnFont.setFirstChar(ttf.getFirstChar());
returnFont.setLastChar(ttf.getLastChar());
+ singleFont.setTrueTypePostScriptVersion(ttf.getPostScriptVersion());
copyWidthsSingleByte(ttf);
}
+ returnFont.setCMap(getCMap(ttf));
if (useKerning) {
copyKerning(ttf, isCid);
@@ -186,23 +181,30 @@ public class TTFFontLoader extends FontLoader {
}
}
+ private CMapSegment[] getCMap(TTFFile ttf) {
+ CMapSegment[] array = new CMapSegment[ttf.getCMaps().size()];
+ return ttf.getCMaps().toArray(array);
+ }
+
private void copyWidthsSingleByte(TTFFile ttf) {
int[] wx = ttf.getWidths();
for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
singleFont.setWidth(i, ttf.getCharWidth(i));
}
- Iterator iter = ttf.getCMaps().listIterator();
- while (iter.hasNext()) {
- TTFCmapEntry ce = (TTFCmapEntry)iter.next();
- if (ce.getUnicodeStart() < 0xFFFE) {
- for (char u = (char)ce.getUnicodeStart(); u <= ce.getUnicodeEnd(); u++) {
+
+ for (CMapSegment segment : ttf.getCMaps()) {
+ if (segment.getUnicodeStart() < 0xFFFE) {
+ for (char u = (char)segment.getUnicodeStart(); u <= segment.getUnicodeEnd(); u++) {
int codePoint = singleFont.getEncoding().mapChar(u);
if (codePoint <= 0) {
- String unicode = Character.toString(u);
- String charName = Glyphs.stringToGlyph(unicode);
- if (charName.length() > 0) {
- NamedCharacter nc = new NamedCharacter(charName, unicode);
- int glyphIndex = ce.getGlyphStartIndex() + u - ce.getUnicodeStart();
+ int glyphIndex = segment.getGlyphStartIndex() + u - segment.getUnicodeStart();
+ String glyphName = ttf.getGlyphName(glyphIndex);
+ if (glyphName.length() == 0 && ttf.getPostScriptVersion() != PostScriptVersion.V2) {
+ glyphName = "u" + HexEncoder.encode(u);
+ }
+ if (glyphName.length() > 0) {
+ String unicode = Character.toString(u);
+ NamedCharacter nc = new NamedCharacter(glyphName, unicode);
singleFont.addUnencodedCharacter(nc, wx[glyphIndex]);
}
}
@@ -225,7 +227,6 @@ public class TTFFontLoader extends FontLoader {
}
for (Integer kpx1 : kerningSet) {
-
Map<Integer, Integer> h2;
if (isCid) {
h2 = ttf.getKerning().get(kpx1);
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.java
new file mode 100644
index 000000000..313d5836d
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/truetype/TTFGlyphOutputStream.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.fonts.truetype;
+
+import java.io.IOException;
+
+/**
+ * An interface for writing individual glyphs from the glyf table of a TrueType font to an output stream.
+ */
+public interface TTFGlyphOutputStream {
+
+ /**
+ * Begins the streaming of glyphs.
+ */
+ void startGlyphStream() throws IOException;
+
+ /**
+ * Streams an individual glyph from the given byte array.
+ *
+ * @param glyphData the source of the glyph data to stream from
+ * @param offset the position in the glyph data where the glyph starts
+ * @param size the size of the glyph data in bytes
+ */
+ void streamGlyph(byte[] glyphData, int offset, int size) throws IOException;
+
+ /**
+ * Ends the streaming of glyphs.
+ */
+ void endGlyphStream() throws IOException;
+
+}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.java
new file mode 100644
index 000000000..09b5b6f50
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/truetype/TTFOutputStream.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.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts.truetype;
+
+import java.io.IOException;
+
+/**
+ * An interface for writing a TrueType font to an output stream.
+ */
+public interface TTFOutputStream {
+
+ /**
+ * Starts writing the font.
+ */
+ void startFontStream() throws IOException;
+
+ /**
+ * Returns an object for streaming TrueType tables.
+ */
+ TTFTableOutputStream getTableOutputStream();
+
+ /**
+ * Returns an object for streaming TrueType glyphs in the glyf table.
+ */
+ TTFGlyphOutputStream getGlyphOutputStream();
+
+ /**
+ * Ends writing the font.
+ */
+ void endFontStream() throws IOException;
+
+}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
index d400c0bfd..292ae191c 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFSubSetFile.java
@@ -20,8 +20,9 @@
package org.apache.fop.fonts.truetype;
import java.io.IOException;
-import java.util.Iterator;
+import java.util.HashMap;
import java.util.Map;
+import java.util.SortedSet;
/**
@@ -42,24 +43,18 @@ public class TTFSubSetFile extends TTFFile {
* Offsets in name table to be filled out by table.
* The offsets are to the checkSum field
*/
- private int cvtDirOffset = 0;
- private int fpgmDirOffset = 0;
- private int glyfDirOffset = 0;
- private int headDirOffset = 0;
- private int hheaDirOffset = 0;
- private int hmtxDirOffset = 0;
- private int locaDirOffset = 0;
- private int maxpDirOffset = 0;
- private int prepDirOffset = 0;
+ private Map<TTFTableName, Integer> offsets = new HashMap<TTFTableName, Integer>();
private int checkSumAdjustmentOffset = 0;
private int locaOffset = 0;
+ /** Stores the glyph offsets so that we can end strings at glyph boundaries */
+ private int[] glyphOffsets;
+
/**
* Default Constructor
*/
public TTFSubSetFile() {
- this(false, false);
}
/**
@@ -71,16 +66,9 @@ public class TTFSubSetFile extends TTFFile {
super(useKerning, useAdvanced);
}
- /**
- * Initalize the output array
- */
- private void init(int size) {
- output = new byte[size];
- realSize = 0;
- currentPos = 0;
-
- // createDirectory()
- }
+ /** The dir tab entries in the new subset font. */
+ private Map<TTFTableName, TTFDirTabEntry> newDirTabs
+ = new HashMap<TTFTableName, TTFDirTabEntry>();
private int determineTableCount() {
int numTables = 4; //4 req'd tables: head,hhea,hmtx,maxp
@@ -88,7 +76,7 @@ public class TTFSubSetFile extends TTFFile {
throw new UnsupportedOperationException(
"OpenType fonts with CFF glyphs are not supported");
} else {
- numTables += 2; //1 req'd table: glyf,loca
+ numTables += 5; //5 req'd tables: glyf,loca,post,name,OS/2
if (hasCvt()) {
numTables++;
}
@@ -119,7 +107,7 @@ public class TTFSubSetFile extends TTFFile {
// Create searchRange, entrySelector and rangeShift
int maxPow = maxPow2(numTables);
- int searchRange = maxPow * 16;
+ int searchRange = (int) Math.pow(2, maxPow) * 16;
writeUShort(searchRange);
realSize += 2;
@@ -128,151 +116,122 @@ public class TTFSubSetFile extends TTFFile {
writeUShort((numTables * 16) - searchRange);
realSize += 2;
+ // Create space for the table entries (these must be in ASCII alphabetical order[A-Z] then[a-z])
+ writeTableName(TTFTableName.OS2);
- // Create space for the table entries
if (hasCvt()) {
- writeString("cvt ");
- cvtDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
+ writeTableName(TTFTableName.CVT);
}
-
if (hasFpgm()) {
- writeString("fpgm");
- fpgmDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
+ writeTableName(TTFTableName.FPGM);
}
+ writeTableName(TTFTableName.GLYF);
+ writeTableName(TTFTableName.HEAD);
+ writeTableName(TTFTableName.HHEA);
+ writeTableName(TTFTableName.HMTX);
+ writeTableName(TTFTableName.LOCA);
+ writeTableName(TTFTableName.MAXP);
+ writeTableName(TTFTableName.NAME);
+ writeTableName(TTFTableName.POST);
+ if (hasPrep()) {
+ writeTableName(TTFTableName.PREP);
+ }
+ newDirTabs.put(TTFTableName.TABLE_DIRECTORY, new TTFDirTabEntry(0, currentPos));
+ }
- writeString("glyf");
- glyfDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("head");
- headDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("hhea");
- hheaDirOffset = currentPos;
+ private void writeTableName(TTFTableName tableName) {
+ writeString(tableName.getName());
+ offsets.put(tableName, currentPos);
currentPos += 12;
realSize += 16;
+ }
- writeString("hmtx");
- hmtxDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
- writeString("loca");
- locaDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
-
- writeString("maxp");
- maxpDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
+ private boolean hasCvt() {
+ return dirTabs.containsKey(TTFTableName.CVT);
+ }
- if (hasPrep()) {
- writeString("prep");
- prepDirOffset = currentPos;
- currentPos += 12;
- realSize += 16;
- }
+ private boolean hasFpgm() {
+ return dirTabs.containsKey(TTFTableName.FPGM);
}
+ private boolean hasPrep() {
+ return dirTabs.containsKey(TTFTableName.PREP);
+ }
/**
- * Copy the cvt table as is from original font to subset font
+ * Create an empty loca table without updating checksum
*/
- private boolean createCvt(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("cvt ");
+ private void createLoca(int size) throws IOException {
+ pad4();
+ locaOffset = currentPos;
+ int dirTableOffset = offsets.get(TTFTableName.LOCA);
+ writeULong(dirTableOffset + 4, currentPos);
+ writeULong(dirTableOffset + 8, size * 4 + 4);
+ currentPos += size * 4 + 4;
+ realSize += size * 4 + 4;
+ }
+
+ private boolean copyTable(FontFileReader in, TTFTableName tableName) throws IOException {
+ TTFDirTabEntry entry = dirTabs.get(tableName);
if (entry != null) {
pad4();
- seekTab(in, "cvt ", 0);
+ seekTab(in, tableName, 0);
System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
0, output, currentPos, (int)entry.getLength());
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(cvtDirOffset, checksum);
- writeULong(cvtDirOffset + 4, currentPos);
- writeULong(cvtDirOffset + 8, (int)entry.getLength());
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
+ updateCheckSum(currentPos, (int) entry.getLength(), tableName);
+ currentPos += (int) entry.getLength();
+ realSize += (int) entry.getLength();
return true;
} else {
return false;
- //throw new IOException("Can't find cvt table");
}
}
- private boolean hasCvt() {
- return dirTabs.containsKey("cvt ");
- }
-
- private boolean hasFpgm() {
- return dirTabs.containsKey("fpgm");
- }
-
- private boolean hasPrep() {
- return dirTabs.containsKey("prep");
+ /**
+ * Copy the cvt table as is from original font to subset font
+ */
+ private boolean createCvt(FontFileReader in) throws IOException {
+ return copyTable(in, TTFTableName.CVT);
}
/**
* Copy the fpgm table as is from original font to subset font
*/
private boolean createFpgm(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("fpgm");
- if (entry != null) {
- pad4();
- seekTab(in, "fpgm", 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(fpgmDirOffset, checksum);
- writeULong(fpgmDirOffset + 4, currentPos);
- writeULong(fpgmDirOffset + 8, (int)entry.getLength());
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
- return true;
- } else {
- return false;
- }
+ return copyTable(in, TTFTableName.FPGM);
}
-
-
/**
- * Create an empty loca table without updating checksum
+ * Copy the name table as is from the original.
*/
- private void createLoca(int size) throws IOException {
- pad4();
- locaOffset = currentPos;
- writeULong(locaDirOffset + 4, currentPos);
- writeULong(locaDirOffset + 8, size * 4 + 4);
- currentPos += size * 4 + 4;
- realSize += size * 4 + 4;
+ private boolean createName(FontFileReader in) throws IOException {
+ return copyTable(in, TTFTableName.NAME);
}
+ /**
+ * Copy the OS/2 table as is from the original.
+ */
+ private boolean createOS2(FontFileReader in) throws IOException {
+ return copyTable(in, TTFTableName.OS2);
+ }
/**
* Copy the maxp table as is from original font to subset font
* and set num glyphs to size
*/
private void createMaxp(FontFileReader in, int size) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("maxp");
+ TTFTableName maxp = TTFTableName.MAXP;
+ TTFDirTabEntry entry = dirTabs.get(maxp);
if (entry != null) {
pad4();
- seekTab(in, "maxp", 0);
+ seekTab(in, maxp, 0);
System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
0, output, currentPos, (int)entry.getLength());
writeUShort(currentPos + 4, size);
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(maxpDirOffset, checksum);
- writeULong(maxpDirOffset + 4, currentPos);
- writeULong(maxpDirOffset + 8, (int)entry.getLength());
+ updateCheckSum(currentPos, (int)entry.getLength(), maxp);
currentPos += (int)entry.getLength();
realSize += (int)entry.getLength();
} else {
@@ -280,28 +239,34 @@ public class TTFSubSetFile extends TTFFile {
}
}
+ private void createPost(FontFileReader in) throws IOException {
+ TTFTableName post = TTFTableName.POST;
+ TTFDirTabEntry entry = dirTabs.get(post);
+ if (entry != null) {
+ pad4();
+ seekTab(in, post, 0);
+ int newTableSize = 32; // This is the post table size with glyphs truncated
+ byte[] newPostTable = new byte[newTableSize];
+ // We only want the first 28 bytes (truncate the glyph names);
+ System.arraycopy(in.getBytes((int) entry.getOffset(), newTableSize),
+ 0, newPostTable, 0, newTableSize);
+ // set the post table to Format 3.0
+ newPostTable[1] = 0x03;
+ System.arraycopy(newPostTable, 0, output, currentPos, newTableSize);
+ updateCheckSum(currentPos, newTableSize, post);
+ currentPos += newTableSize;
+ realSize += newTableSize;
+ } else {
+ throw new IOException("Can't find post table");
+ }
+ }
+
/**
* Copy the prep table as is from original font to subset font
*/
private boolean createPrep(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("prep");
- if (entry != null) {
- pad4();
- seekTab(in, "prep", 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
-
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(prepDirOffset, checksum);
- writeULong(prepDirOffset + 4, currentPos);
- writeULong(prepDirOffset + 8, (int)entry.getLength());
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
- return true;
- } else {
- return false;
- }
+ return copyTable(in, TTFTableName.PREP);
}
@@ -310,20 +275,17 @@ public class TTFSubSetFile extends TTFFile {
* and fill in size of hmtx table
*/
private void createHhea(FontFileReader in, int size) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hhea");
+ TTFDirTabEntry entry = dirTabs.get(TTFTableName.HHEA);
if (entry != null) {
pad4();
- seekTab(in, "hhea", 0);
- System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
- 0, output, currentPos, (int)entry.getLength());
- writeUShort((int)entry.getLength() + currentPos - 2, size);
-
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(hheaDirOffset, checksum);
- writeULong(hheaDirOffset + 4, currentPos);
- writeULong(hheaDirOffset + 8, (int)entry.getLength());
- currentPos += (int)entry.getLength();
- realSize += (int)entry.getLength();
+ seekTab(in, TTFTableName.HHEA, 0);
+ System.arraycopy(in.getBytes((int) entry.getOffset(), (int) entry.getLength()), 0,
+ output, currentPos, (int) entry.getLength());
+ writeUShort((int) entry.getLength() + currentPos - 2, size);
+
+ updateCheckSum(currentPos, (int) entry.getLength(), TTFTableName.HHEA);
+ currentPos += (int) entry.getLength();
+ realSize += (int) entry.getLength();
} else {
throw new IOException("Can't find hhea table");
}
@@ -337,10 +299,11 @@ public class TTFSubSetFile extends TTFFile {
* in checkSumAdjustmentOffset
*/
private void createHead(FontFileReader in) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("head");
+ TTFTableName head = TTFTableName.HEAD;
+ TTFDirTabEntry entry = dirTabs.get(head);
if (entry != null) {
pad4();
- seekTab(in, "head", 0);
+ seekTab(in, head, 0);
System.arraycopy(in.getBytes((int)entry.getOffset(), (int)entry.getLength()),
0, output, currentPos, (int)entry.getLength());
@@ -352,11 +315,7 @@ public class TTFSubSetFile extends TTFFile {
output[currentPos + 50] = 0; // long locaformat
output[currentPos + 51] = 1; // long locaformat
- int checksum = getCheckSum(currentPos, (int)entry.getLength());
- writeULong(headDirOffset, checksum);
- writeULong(headDirOffset + 4, currentPos);
- writeULong(headDirOffset + 8, (int)entry.getLength());
-
+ updateCheckSum(currentPos, (int)entry.getLength(), head);
currentPos += (int)entry.getLength();
realSize += (int)entry.getLength();
} else {
@@ -369,30 +328,24 @@ public class TTFSubSetFile extends TTFFile {
* Create the glyf table and fill in loca table
*/
private void createGlyf(FontFileReader in,
- Map glyphs) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("glyf");
+ Map<Integer, Integer> glyphs) throws IOException {
+ TTFTableName glyf = TTFTableName.GLYF;
+ TTFDirTabEntry entry = dirTabs.get(glyf);
int size = 0;
- int start = 0;
+ int startPos = 0;
int endOffset = 0; // Store this as the last loca
if (entry != null) {
pad4();
- start = currentPos;
+ startPos = currentPos;
/* Loca table must be in order by glyph index, so build
* an array first and then write the glyph info and
* location offset.
*/
- int[] origIndexes = new int[glyphs.size()];
-
- Iterator e = glyphs.keySet().iterator();
- while (e.hasNext()) {
- Integer origIndex = (Integer)e.next();
- Integer subsetIndex = (Integer)glyphs.get(origIndex);
- origIndexes[subsetIndex.intValue()] = origIndex.intValue();
- }
+ int[] origIndexes = buildSubsetIndexToOrigIndexMap(glyphs);
+ glyphOffsets = new int[origIndexes.length];
for (int i = 0; i < origIndexes.length; i++) {
- int glyphLength = 0;
int nextOffset = 0;
int origGlyphIndex = origIndexes[i];
if (origGlyphIndex >= (mtxTab.length - 1)) {
@@ -400,46 +353,64 @@ public class TTFSubSetFile extends TTFFile {
} else {
nextOffset = (int)mtxTab[origGlyphIndex + 1].getOffset();
}
- glyphLength = nextOffset - (int)mtxTab[origGlyphIndex].getOffset();
+ int glyphOffset = (int)mtxTab[origGlyphIndex].getOffset();
+ int glyphLength = nextOffset - glyphOffset;
+ byte[] glyphData = in.getBytes(
+ (int)entry.getOffset() + glyphOffset,
+ glyphLength);
+ int endOffset1 = endOffset;
// Copy glyph
System.arraycopy(
- in.getBytes((int)entry.getOffset() + (int)mtxTab[origGlyphIndex].getOffset(),
- glyphLength), 0,
+ glyphData, 0,
output, currentPos,
glyphLength);
// Update loca table
- writeULong(locaOffset + i * 4, currentPos - start);
- if ((currentPos - start + glyphLength) > endOffset) {
- endOffset = (currentPos - start + glyphLength);
+ writeULong(locaOffset + i * 4, currentPos - startPos);
+ if ((currentPos - startPos + glyphLength) > endOffset1) {
+ endOffset1 = (currentPos - startPos + glyphLength);
}
+ // Store the glyph boundary positions relative to the start of the font
+ glyphOffsets[i] = currentPos;
currentPos += glyphLength;
realSize += glyphLength;
+
+ endOffset = endOffset1;
}
- size = currentPos - start;
- int checksum = getCheckSum(start, size);
- writeULong(glyfDirOffset, checksum);
- writeULong(glyfDirOffset + 4, start);
- writeULong(glyfDirOffset + 8, size);
+ size = currentPos - startPos;
+
currentPos += 12;
realSize += 12;
+ updateCheckSum(startPos, size + 12, glyf);
// Update loca checksum and last loca index
writeULong(locaOffset + glyphs.size() * 4, endOffset);
-
- checksum = getCheckSum(locaOffset, glyphs.size() * 4 + 4);
- writeULong(locaDirOffset, checksum);
+ int locaSize = glyphs.size() * 4 + 4;
+ int checksum = getCheckSum(output, locaOffset, locaSize);
+ writeULong(offsets.get(TTFTableName.LOCA), checksum);
+ int padSize = (locaOffset + locaSize) % 4;
+ newDirTabs.put(TTFTableName.LOCA,
+ new TTFDirTabEntry(locaOffset, locaSize + padSize));
} else {
throw new IOException("Can't find glyf table");
}
}
+ private int[] buildSubsetIndexToOrigIndexMap(Map<Integer, Integer> glyphs) {
+ int[] origIndexes = new int[glyphs.size()];
+ for (Map.Entry<Integer, Integer> glyph : glyphs.entrySet()) {
+ int origIndex = glyph.getKey();
+ int subsetIndex = glyph.getValue();
+ origIndexes[subsetIndex] = origIndex;
+ }
+ return origIndexes;
+ }
/**
* Create the hmtx table by copying metrics from original
@@ -448,8 +419,9 @@ public class TTFSubSetFile extends TTFFile {
* metric (key) to the subset metric (value)
*/
private void createHmtx(FontFileReader in,
- Map glyphs) throws IOException {
- TTFDirTabEntry entry = (TTFDirTabEntry)dirTabs.get("hmtx");
+ Map<Integer, Integer> glyphs) throws IOException {
+ TTFTableName hmtx = TTFTableName.HMTX;
+ TTFDirTabEntry entry = dirTabs.get(hmtx);
int longHorMetricSize = glyphs.size() * 2;
int leftSideBearingSize = glyphs.size() * 2;
@@ -458,10 +430,9 @@ public class TTFSubSetFile extends TTFFile {
if (entry != null) {
pad4();
//int offset = (int)entry.offset;
- Iterator e = glyphs.keySet().iterator();
- while (e.hasNext()) {
- Integer origIndex = (Integer)e.next();
- Integer subsetIndex = (Integer)glyphs.get(origIndex);
+ for (Map.Entry<Integer, Integer> glyph : glyphs.entrySet()) {
+ Integer origIndex = glyph.getKey();
+ Integer subsetIndex = glyph.getValue();
writeUShort(currentPos + subsetIndex.intValue() * 4,
mtxTab[origIndex.intValue()].getWx());
@@ -469,10 +440,7 @@ public class TTFSubSetFile extends TTFFile {
mtxTab[origIndex.intValue()].getLsb());
}
- int checksum = getCheckSum(currentPos, hmtxSize);
- writeULong(hmtxDirOffset, checksum);
- writeULong(hmtxDirOffset + 4, currentPos);
- writeULong(hmtxDirOffset + 8, hmtxSize);
+ updateCheckSum(currentPos, hmtxSize, hmtx);
currentPos += hmtxSize;
realSize += hmtxSize;
} else {
@@ -481,43 +449,37 @@ public class TTFSubSetFile extends TTFFile {
}
/**
- * Returns a subset of the original font.
+ * Reads a font and creates a subset of the font.
*
* @param in FontFileReader to read from
* @param name Name to be checked for in the font file
* @param glyphs Map of glyphs (glyphs has old index as (Integer) key and
* new index as (Integer) value)
- * @return A subset of the original font
* @throws IOException in case of an I/O problem
*/
- public byte[] readFont(FontFileReader in, String name,
+ public void readFont(FontFileReader in, String name,
Map<Integer, Integer> glyphs) throws IOException {
-
+ fontFile = in;
//Check if TrueType collection, and that the name exists in the collection
- if (!checkTTC(in, name)) {
+ if (!checkTTC(name)) {
throw new IOException("Failed to read font");
}
//Copy the Map as we're going to modify it
- Map<Integer, Integer> subsetGlyphs = new java.util.HashMap<Integer, Integer>(glyphs);
+ Map<Integer, Integer> subsetGlyphs = new HashMap<Integer, Integer>(glyphs);
output = new byte[in.getFileSize()];
- readDirTabs(in);
- readFontHeader(in);
- getNumGlyphs(in);
- readHorizontalHeader(in);
- readHorizontalMetrics(in);
- readIndexToLocation(in);
+ readDirTabs();
+ readFontHeader();
+ getNumGlyphs();
+ readHorizontalHeader();
+ readHorizontalMetrics();
+ readIndexToLocation();
scanGlyphs(in, subsetGlyphs);
- createDirectory(); // Create the TrueType header and directory
-
- createHead(in);
- createHhea(in, subsetGlyphs.size()); // Create the hhea table
- createHmtx(in, subsetGlyphs); // Create hmtx table
- createMaxp(in, subsetGlyphs.size()); // copy the maxp table
+ createDirectory(); // Create the TrueType header and directory
boolean optionalTableFound;
optionalTableFound = createCvt(in); // copy the cvt table
@@ -531,6 +493,16 @@ public class TTFSubSetFile extends TTFFile {
// fpgm is optional (used in TrueType fonts only)
log.debug("TrueType: fpgm table not present. Skipped.");
}
+ createLoca(subsetGlyphs.size()); // create empty loca table
+ createGlyf(in, subsetGlyphs); //create glyf table and update loca table
+
+ createOS2(in); // copy the OS/2 table
+ createHead(in);
+ createHhea(in, subsetGlyphs.size()); // Create the hhea table
+ createHmtx(in, subsetGlyphs); // Create hmtx table
+ createMaxp(in, subsetGlyphs.size()); // copy the maxp table
+ createName(in); // copy the name table
+ createPost(in); // copy the post table
optionalTableFound = createPrep(in); // copy prep table
if (!optionalTableFound) {
@@ -538,21 +510,59 @@ public class TTFSubSetFile extends TTFFile {
log.debug("TrueType: prep table not present. Skipped.");
}
- createLoca(subsetGlyphs.size()); // create empty loca table
- createGlyf(in, subsetGlyphs); //create glyf table and update loca table
-
pad4();
createCheckSumAdjustment();
+ }
+ /**
+ * Returns a subset of the fonts (readFont() MUST be called first in order to create the
+ * subset).
+ * @return byte array
+ */
+ public byte[] getFontSubset() {
byte[] ret = new byte[realSize];
System.arraycopy(output, 0, ret, 0, realSize);
-
return ret;
}
+ private void handleGlyphSubset(TTFGlyphOutputStream glyphOut) throws IOException {
+ glyphOut.startGlyphStream();
+ // Stream all but the last glyph
+ for (int i = 0; i < glyphOffsets.length - 1; i++) {
+ glyphOut.streamGlyph(output, glyphOffsets[i],
+ glyphOffsets[i + 1] - glyphOffsets[i]);
+ }
+ // Stream the last glyph
+ TTFDirTabEntry glyf = newDirTabs.get(TTFTableName.GLYF);
+ long lastGlyphLength = glyf.getLength()
+ - (glyphOffsets[glyphOffsets.length - 1] - glyf.getOffset());
+ glyphOut.streamGlyph(output, glyphOffsets[glyphOffsets.length - 1],
+ (int) lastGlyphLength);
+ glyphOut.endGlyphStream();
+ }
+
+ @Override
+ public void stream(TTFOutputStream ttfOut) throws IOException {
+ SortedSet<Map.Entry<TTFTableName, TTFDirTabEntry>> sortedDirTabs
+ = sortDirTabMap(newDirTabs);
+ TTFTableOutputStream tableOut = ttfOut.getTableOutputStream();
+ TTFGlyphOutputStream glyphOut = ttfOut.getGlyphOutputStream();
+
+ ttfOut.startFontStream();
+ for (Map.Entry<TTFTableName, TTFDirTabEntry> entry : sortedDirTabs) {
+ if (entry.getKey().equals(TTFTableName.GLYF)) {
+ handleGlyphSubset(glyphOut);
+ } else {
+ tableOut.streamTable(output, (int) entry.getValue().getOffset(),
+ (int) entry.getValue().getLength());
+ }
+ }
+ ttfOut.endFontStream();
+ }
+
private void scanGlyphs(FontFileReader in, Map<Integer, Integer> subsetGlyphs)
throws IOException {
- TTFDirTabEntry glyfTableInfo = (TTFDirTabEntry) dirTabs.get("glyf");
+ TTFDirTabEntry glyfTableInfo = dirTabs.get(TTFTableName.GLYF);
if (glyfTableInfo == null) {
throw new IOException("Glyf table could not be found");
}
@@ -610,20 +620,6 @@ public class TTFSubSetFile extends TTFFile {
output[pos + 1] = b2;
}
- /**
- * Appends a ULONG to the output array,
- * updates currentPos but not realSize
- */
- private void writeULong(int s) {
- byte b1 = (byte)((s >> 24) & 0xff);
- byte b2 = (byte)((s >> 16) & 0xff);
- byte b3 = (byte)((s >> 8) & 0xff);
- byte b4 = (byte)(s & 0xff);
- writeByte(b1);
- writeByte(b2);
- writeByte(b3);
- writeByte(b4);
- }
/**
* Appends a ULONG to the output array,
@@ -641,40 +637,16 @@ public class TTFSubSetFile extends TTFFile {
}
/**
- * Read a signed short value at given position
- */
- private short readShort(int pos) {
- int ret = readUShort(pos);
- return (short)ret;
- }
-
- /**
- * Read a unsigned short value at given position
- */
- private int readUShort(int pos) {
- int ret = output[pos];
- if (ret < 0) {
- ret += 256;
- }
- ret = ret << 8;
- if (output[pos + 1] < 0) {
- ret |= output[pos + 1] + 256;
- } else {
- ret |= output[pos + 1];
- }
-
- return ret;
- }
-
- /**
* Create a padding in the fontfile to align
* on a 4-byte boundary
*/
private void pad4() {
- int padSize = currentPos % 4;
- for (int i = 0; i < padSize; i++) {
- output[currentPos++] = 0;
- realSize++;
+ int padSize = getPadSize(currentPos);
+ if (padSize < 4) {
+ for (int i = 0; i < padSize; i++) {
+ output[currentPos++] = 0;
+ realSize++;
+ }
}
}
@@ -683,23 +655,25 @@ public class TTFSubSetFile extends TTFFile {
*/
private int maxPow2(int max) {
int i = 0;
- while (Math.pow(2, i) < max) {
+ while (Math.pow(2, i) <= max) {
i++;
}
return (i - 1);
}
- private int log2(int num) {
- return (int)(Math.log(num) / Math.log(2));
- }
-
- private int getCheckSum(int start, int size) {
- return (int)getLongCheckSum(start, size);
+ private void updateCheckSum(int tableStart, int tableSize, TTFTableName tableName) {
+ int checksum = getCheckSum(output, tableStart, tableSize);
+ int offset = offsets.get(tableName);
+ int padSize = getPadSize(tableStart + tableSize);
+ newDirTabs.put(tableName, new TTFDirTabEntry(tableStart, tableSize + padSize));
+ writeULong(offset, checksum);
+ writeULong(offset + 4, tableStart);
+ writeULong(offset + 8, tableSize);
}
- private long getLongCheckSum(int start, int size) {
+ private static int getCheckSum(byte[] data, int start, int size) {
// All the tables here are aligned on four byte boundaries
// Add remainder to size if it's not a multiple of 4
int remainder = size % 4;
@@ -710,26 +684,19 @@ public class TTFSubSetFile extends TTFFile {
long sum = 0;
for (int i = 0; i < size; i += 4) {
- int l = (output[start + i] << 24);
- l += (output[start + i + 1] << 16);
- l += (output[start + i + 2] << 16);
- l += (output[start + i + 3] << 16);
- sum += l;
- if (sum > 0xffffffff) {
- sum = sum - 0xffffffff;
+ long l = 0;
+ for (int j = 0; j < 4; j++) {
+ l <<= 8;
+ l |= data[start + i + j] & 0xff;
}
+ sum += l;
}
-
- return sum;
+ return (int) sum;
}
private void createCheckSumAdjustment() {
- long sum = getLongCheckSum(0, realSize);
+ long sum = getCheckSum(output, 0, realSize);
int checksum = (int)(0xb1b0afba - sum);
writeULong(checkSumAdjustmentOffset, checksum);
}
-
}
-
-
-
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFTableName.java b/src/java/org/apache/fop/fonts/truetype/TTFTableName.java
new file mode 100644
index 000000000..e5ad63128
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/truetype/TTFTableName.java
@@ -0,0 +1,163 @@
+/*
+ * 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.truetype;
+
+
+/**
+ * Represents table names as found in a TrueType font's Table Directory.
+ * TrueType fonts may have custom tables so we cannot use an enum.
+ */
+public final class TTFTableName {
+
+ /** The first table in a TrueType font file containing metadata about other tables. */
+ public static final TTFTableName TABLE_DIRECTORY = new TTFTableName("tableDirectory");
+
+ /** Embedded bitmap data. */
+ public static final TTFTableName EBDT = new TTFTableName("EBDT");
+
+ /** Embedded bitmap location data. */
+ public static final TTFTableName EBLC = new TTFTableName("EBLC");
+
+ /** Embedded bitmap scaling data. */
+ public static final TTFTableName EBSC = new TTFTableName("EBSC");
+
+ /** A FontForge specific table. */
+ public static final TTFTableName FFTM = new TTFTableName("FFTM");
+
+ /** Divides glyphs into various classes that make using the GPOS/GSUB tables easier. */
+ public static final TTFTableName GDEF = new TTFTableName("GDEF");
+
+ /** Provides kerning information, mark-to-base, etc. for opentype fonts. */
+ public static final TTFTableName GPOS = new TTFTableName("GPOS");
+
+ /** Provides ligature information, swash, etc. for opentype fonts. */
+ public static final TTFTableName GSUB = new TTFTableName("GSUB");
+
+ /** Linear threshold table. */
+ public static final TTFTableName LTSH = new TTFTableName("LTSH");
+
+ /** OS/2 and Windows specific metrics. */
+ public static final TTFTableName OS2 = new TTFTableName("OS/2");
+
+ /** PCL 5 data. */
+ public static final TTFTableName PCLT = new TTFTableName("PCLT");
+
+ /** Vertical Device Metrics table. */
+ public static final TTFTableName VDMX = new TTFTableName("VDMX");
+
+ /** Character to glyph mapping. */
+ public static final TTFTableName CMAP = new TTFTableName("cmap");
+
+ /** Control Value Table. */
+ public static final TTFTableName CVT = new TTFTableName("cvt ");
+
+ /** Font program. */
+ public static final TTFTableName FPGM = new TTFTableName("fpgm");
+
+ /** Grid-fitting and scan conversion procedure (grayscale). */
+ public static final TTFTableName GASP = new TTFTableName("gasp");
+
+ /** Glyph data. */
+ public static final TTFTableName GLYF = new TTFTableName("glyf");
+
+ /** Horizontal device metrics. */
+ public static final TTFTableName HDMX = new TTFTableName("hdmx");
+
+ /** Font header. */
+ public static final TTFTableName HEAD = new TTFTableName("head");
+
+ /** Horizontal header. */
+ public static final TTFTableName HHEA = new TTFTableName("hhea");
+
+ /** Horizontal metrics. */
+ public static final TTFTableName HMTX = new TTFTableName("hmtx");
+
+ /** Kerning. */
+ public static final TTFTableName KERN = new TTFTableName("kern");
+
+ /** Index to location. */
+ public static final TTFTableName LOCA = new TTFTableName("loca");
+
+ /** Maximum profile. */
+ public static final TTFTableName MAXP = new TTFTableName("maxp");
+
+ /** Naming table. */
+ public static final TTFTableName NAME = new TTFTableName("name");
+
+ /** PostScript information. */
+ public static final TTFTableName POST = new TTFTableName("post");
+
+ /** CVT Program. */
+ public static final TTFTableName PREP = new TTFTableName("prep");
+
+ /** Vertical Metrics header. */
+ public static final TTFTableName VHEA = new TTFTableName("vhea");
+
+ /** Vertical Metrics. */
+ public static final TTFTableName VMTX = new TTFTableName("vmtx");
+
+ private final String name;
+
+ private TTFTableName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of the table as it should be in the Directory Table.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns an instance of this class corresponding to the given string representation.
+ * @param tableName table name as in the Table Directory
+ * @return TTFTableName
+ */
+ public static TTFTableName getValue(String tableName) {
+ if (tableName != null) {
+ return new TTFTableName(tableName);
+ }
+ throw new IllegalArgumentException("A TrueType font table name must not be null");
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof TTFTableName)) {
+ return false;
+ }
+ TTFTableName to = (TTFTableName) o;
+ return this.name.equals(to.getName());
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java b/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java
new file mode 100644
index 000000000..d0d2007f5
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/truetype/TTFTableOutputStream.java
@@ -0,0 +1,37 @@
+/*
+ * 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.truetype;
+
+import java.io.IOException;
+
+/**
+ * An interface for writing a TrueType table to an output stream.
+ */
+public interface TTFTableOutputStream {
+
+ /**
+ * Streams a table from the given byte array.
+ *
+ * @param ttfData the source of the table to stream from
+ * @param offset the position in the byte array where the table starts
+ * @param size the size of the table in bytes
+ */
+ void streamTable(byte[] ttfData, int offset, int size) throws IOException;
+}
diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java
index c5845977f..ec16810b3 100644
--- a/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java
+++ b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java
@@ -79,7 +79,7 @@ public class HyphenationTreeCache {
String userKey = null;
if (hyphPatNames != null) {
String key = constructLlccKey(lang, country);
- key.replace('_', '-');
+ key = key.replace('_', '-');
userKey = (String) hyphPatNames.get(key);
}
return userKey;
@@ -96,7 +96,7 @@ public class HyphenationTreeCache {
/**
* Notes a key to a hyphenation tree as missing.
- * This is to avoid searching a second time for a hyphneation pattern file which is not
+ * This is to avoid searching a second time for a hyphenation pattern file which is not
* available.
* @param key the key (ex. "de_CH" or "en")
*/
@@ -109,7 +109,7 @@ public class HyphenationTreeCache {
/**
* Indicates whether a hyphenation file has been requested before but it wasn't available.
- * This is to avoid searching a second time for a hyphneation pattern file which is not
+ * This is to avoid searching a second time for a hyphenation pattern file which is not
* available.
* @param key the key (ex. "de_CH" or "en")
* @return true if the hyphenation tree is unavailable
diff --git a/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
index 2bcdb6127..03c159843 100644
--- a/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/BalancingColumnBreakingAlgorithm.java
@@ -41,12 +41,16 @@ public class BalancingColumnBreakingAlgorithm extends PageBreakingAlgorithm {
* @param topLevelLM the top level layout manager
* @param pageProvider the page provider
* @param layoutListener the layout listener
- * @param alignment alignment of the paragraph/page. One of {@link Constants#EN_START},
- * {@link Constants#EN_JUSTIFY}, {@link Constants#EN_CENTER},
- * {@link Constants#EN_END}.
- * For pages, {@link Constants#EN_BEFORE} and {@link Constants#EN_AFTER}
- * are mapped to the corresponding inline properties,
- * {@link Constants#EN_START} and {@link Constants#EN_END}.
+ * @param alignment alignment of the paragraph/page. One of
+ * {@link org.apache.fop.fo.Constants#EN_START},
+ * {@link org.apache.fop.fo.Constants#EN_JUSTIFY},
+ * {@link org.apache.fop.fo.Constants#EN_CENTER},
+ * {@link org.apache.fop.fo.Constants#EN_END}.
+ * For pages, {@link org.apache.fop.fo.Constants#EN_BEFORE} and
+ * {@link org.apache.fop.fo.Constants#EN_AFTER}
+ * are mapped to the corresponding inline properties,
+ * {@link org.apache.fop.fo.Constants#EN_START} and
+ * {@link org.apache.fop.fo.Constants#EN_END}.
* @param alignmentLast alignment of the paragraph's last line
* @param footnoteSeparatorLength length of footnote separator
* @param partOverflowRecovery {@code true} if too long elements should be moved to
diff --git a/src/java/org/apache/fop/layoutmgr/BreakElement.java b/src/java/org/apache/fop/layoutmgr/BreakElement.java
index 1c89c2009..77e7f140b 100644
--- a/src/java/org/apache/fop/layoutmgr/BreakElement.java
+++ b/src/java/org/apache/fop/layoutmgr/BreakElement.java
@@ -46,8 +46,11 @@ public class BreakElement extends UnresolvedListElement {
* Create a new BreakElement for the given {@code position}, {@code penaltyValue}
* and {@code breakClass}. (Used principally to generate break-possibilities in
* ranges of content that must be kept together within the context corresponding
- * to the {@code breakClass}; expected to be one of {@link Constants#EN_AUTO},
- * {@link Constants#EN_LINE}, {@link Constants#EN_COLUMN} or {@link Constants#EN_PAGE})
+ * to the {@code breakClass}; expected to be one of
+ * {@link org.apache.fop.fo.Constants#EN_AUTO},
+ * {@link org.apache.fop.fo.Constants#EN_LINE},
+ * {@link org.apache.fop.fo.Constants#EN_COLUMN} or
+ * {@link org.apache.fop.fo.Constants#EN_PAGE})
* @param position the corresponding {@link Position}
* @param penaltyValue the penalty value
* @param breakClass the break class
@@ -64,9 +67,12 @@ public class BreakElement extends UnresolvedListElement {
* @param position the Position instance needed by the addAreas stage of the LMs.
* @param penaltyWidth the penalty width
* @param penaltyValue the penalty value for the penalty element to be constructed
- * @param breakClass the break class of this penalty (one of {@link Constants#EN_AUTO},
- * {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
- * {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE})
+ * @param breakClass the break class of this penalty (one of
+ * {@link org.apache.fop.fo.Constants#EN_AUTO},
+ * {@link org.apache.fop.fo.Constants#EN_COLUMN},
+ * {@link org.apache.fop.fo.Constants#EN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_ODD_PAGE})
* @param context the layout context which contains the pending conditional elements
*/
public BreakElement(Position position, int penaltyWidth, int penaltyValue,
@@ -120,9 +126,12 @@ public class BreakElement extends UnresolvedListElement {
/**
* Returns the break class of this penalty.
*
- * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
- * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE},
- * {@link Constants#EN_ODD_PAGE}
+ * @return one of
+ * {@link org.apache.fop.fo.Constants#EN_AUTO},
+ * {@link org.apache.fop.fo.Constants#EN_COLUMN},
+ * {@link org.apache.fop.fo.Constants#EN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}.
*/
public int getBreakClass() {
return breakClass;
@@ -131,9 +140,12 @@ public class BreakElement extends UnresolvedListElement {
/**
* Sets the break class.
*
- * @param breakClass one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN},
- * {@link Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE},
- * {@link Constants#EN_ODD_PAGE}
+ * @param breakClass one of
+ * {@link org.apache.fop.fo.Constants#EN_AUTO},
+ * {@link org.apache.fop.fo.Constants#EN_COLUMN},
+ * {@link org.apache.fop.fo.Constants#EN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}.
*/
public void setBreakClass(int breakClass) {
this.breakClass = breakClass;
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
index 2d4e1f2be..220f9c35d 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
@@ -72,8 +72,11 @@ public class KnuthPenalty extends KnuthElement {
* @param penalty the penalty value of this penalty
* @param penaltyFlagged is this penalty flagged?
* @param breakClass the break class of this penalty (one of
- * {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
- * {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE})
+ * {@link org.apache.fop.fo.Constants#EN_AUTO},
+ * {@link org.apache.fop.fo.Constants#EN_COLUMN},
+ * {@link org.apache.fop.fo.Constants#EN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_EVEN_PAGE},
+ * {@link org.apache.fop.fo.Constants#EN_ODD_PAGE}).
* @param pos the Position stored in this penalty
* @param isAuxiliary is this penalty auxiliary?
*/
diff --git a/src/java/org/apache/fop/pdf/AbstractPDFStream.java b/src/java/org/apache/fop/pdf/AbstractPDFStream.java
index 0181728b8..0948a7d2b 100644
--- a/src/java/org/apache/fop/pdf/AbstractPDFStream.java
+++ b/src/java/org/apache/fop/pdf/AbstractPDFStream.java
@@ -78,7 +78,7 @@ public abstract class AbstractPDFStream extends PDFObject {
* from outside.
*/
protected void setupFilterList() {
- if (!getFilterList().isInitialized()) {
+ if (multipleFiltersAllowed() && !getFilterList().isInitialized()) {
getFilterList().addDefaultFilters(
getDocumentSafely().getFilterMap(),
getDefaultFilterName());
@@ -273,4 +273,11 @@ public abstract class AbstractPDFStream extends PDFObject {
//nop: No default implicit filters
}
+ /**
+ * Whether multiple filters can be applied.
+ * @return true if multiple filters allowed
+ */
+ protected boolean multipleFiltersAllowed() {
+ return true;
+ }
}
diff --git a/src/java/org/apache/fop/pdf/AlphaRasterImage.java b/src/java/org/apache/fop/pdf/AlphaRasterImage.java
index 7272c5edd..250b5daa2 100644
--- a/src/java/org/apache/fop/pdf/AlphaRasterImage.java
+++ b/src/java/org/apache/fop/pdf/AlphaRasterImage.java
@@ -212,6 +212,10 @@ public class AlphaRasterImage implements PDFImage {
return null;
}
+ /** {@inheritDoc} */
+ public boolean multipleFiltersAllowed() {
+ return true;
+ }
}
diff --git a/src/java/org/apache/fop/pdf/BitmapImage.java b/src/java/org/apache/fop/pdf/BitmapImage.java
index 186c00986..ac7af1dbd 100644
--- a/src/java/org/apache/fop/pdf/BitmapImage.java
+++ b/src/java/org/apache/fop/pdf/BitmapImage.java
@@ -37,6 +37,8 @@ public class BitmapImage implements PDFImage {
private PDFColor transparent = null;
private String key;
private PDFDocument pdfDoc;
+ private PDFFilter pdfFilter;
+ private boolean multipleFiltersAllowed = true;
/**
* Create a bitmap image.
@@ -208,9 +210,23 @@ public class BitmapImage implements PDFImage {
* {@inheritDoc}
*/
public PDFFilter getPDFFilter() {
- return null;
+ return pdfFilter;
}
-}
+ public void setPDFFilter(PDFFilter pdfFilter) {
+ this.pdfFilter = pdfFilter;
+ }
+
+ /** {@inheritDoc} */
+ public boolean multipleFiltersAllowed() {
+ return multipleFiltersAllowed;
+ }
+ /**
+ * Disallows multiple filters.
+ */
+ public void disallowMultipleFilters() {
+ multipleFiltersAllowed = false;
+ }
+}
diff --git a/src/java/org/apache/fop/pdf/PDFColor.java b/src/java/org/apache/fop/pdf/PDFColor.java
index 8eea7e390..1fb544368 100644
--- a/src/java/org/apache/fop/pdf/PDFColor.java
+++ b/src/java/org/apache/fop/pdf/PDFColor.java
@@ -30,7 +30,7 @@ import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
* image. And in this context, only RGB and Gray values are used.
* <p>
* Use of this class is discouraged. {@link PDFColorHandler} is now used for in-content color
- * selection. For masked bitmaps, it may be wiser to switch to {@link Color} in the long run.
+ * selection. For masked bitmaps, it may be wiser to switch to {@link java.awt.Color} in the long run.
*/
public class PDFColor extends PDFPathPaint {
// could be 3.0 as well.
diff --git a/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java b/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
index dc0681405..ae6893944 100644
--- a/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
+++ b/src/java/org/apache/fop/pdf/PDFEmbeddedFile.java
@@ -38,7 +38,10 @@ public class PDFEmbeddedFile extends PDFStream {
put("Params", params);
}
- /** {@inheritDoc} */
+ /**
+ * Determine if should encode on the fly.
+ * @return true if should encode on the fly
+ */
protected boolean isEncodingOnTheFly() {
//Acrobat doesn't like an indirect /Length object in this case,
//but only when the embedded file is a PDF file.
diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java
index cc1d93de0..beb384dcf 100644
--- a/src/java/org/apache/fop/pdf/PDFFactory.java
+++ b/src/java/org/apache/fop/pdf/PDFFactory.java
@@ -45,6 +45,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.java2d.color.ColorUtil;
import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
+
import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.fop.fonts.CIDFont;
@@ -1674,8 +1675,8 @@ public class PDFFactory {
FontFileReader reader = new FontFileReader(in);
TTFSubSetFile subset = new TTFSubSetFile();
- byte[] subsetFont = subset.readFont(reader,
- mbfont.getTTCName(), mbfont.getUsedGlyphs());
+ subset.readFont(reader, mbfont.getTTCName(), mbfont.getUsedGlyphs());
+ byte[] subsetFont = subset.getFontSubset();
// Only TrueType CID fonts are supported now
embeddedFont = new PDFTTFStream(subsetFont.length);
diff --git a/src/java/org/apache/fop/pdf/PDFImage.java b/src/java/org/apache/fop/pdf/PDFImage.java
index e2b9e521c..38da60e7b 100644
--- a/src/java/org/apache/fop/pdf/PDFImage.java
+++ b/src/java/org/apache/fop/pdf/PDFImage.java
@@ -151,5 +151,13 @@ public interface PDFImage {
*/
String getFilterHint();
+ /**
+ * Indicates whether multiple image filters are allowed; this is implemented because Adobe
+ * Reader does not like multiple FlateDecode filters applied to an image even though that
+ * allowed by the PDF spec; this is probable due to security concerns since many PDF malware
+ * exploits, like zip bombs, make use of a chain of FlateDecode filters.
+ */
+ boolean multipleFiltersAllowed();
+
}
diff --git a/src/java/org/apache/fop/pdf/PDFImageXObject.java b/src/java/org/apache/fop/pdf/PDFImageXObject.java
index acab4c19c..1c28cb2a7 100644
--- a/src/java/org/apache/fop/pdf/PDFImageXObject.java
+++ b/src/java/org/apache/fop/pdf/PDFImageXObject.java
@@ -166,4 +166,9 @@ public class PDFImageXObject extends PDFXObject {
return pdfimage.getFilterHint();
}
+ /** {@inheritDoc} */
+ protected boolean multipleFiltersAllowed() {
+ return pdfimage.multipleFiltersAllowed();
+ }
+
}
diff --git a/src/java/org/apache/fop/pdf/PDFObject.java b/src/java/org/apache/fop/pdf/PDFObject.java
index 1b9c4eea7..e0f950154 100644
--- a/src/java/org/apache/fop/pdf/PDFObject.java
+++ b/src/java/org/apache/fop/pdf/PDFObject.java
@@ -22,7 +22,6 @@ package org.apache.fop.pdf;
// Java
import java.io.IOException;
import java.io.OutputStream;
-import java.io.Writer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -211,11 +210,6 @@ public abstract class PDFObject implements PDFWritable {
}
/** {@inheritDoc} */
- public void outputInline(OutputStream out, Writer writer) throws IOException {
- throw new UnsupportedOperationException("Don't use anymore: " + getClass().getName());
- }
-
- /** {@inheritDoc} */
public void outputInline(OutputStream out, StringBuilder textBuffer) throws IOException {
if (hasObjectNumber()) {
textBuffer.append(referencePDF());
diff --git a/src/java/org/apache/fop/pdf/PDFResources.java b/src/java/org/apache/fop/pdf/PDFResources.java
index df8647bf4..cded7c00a 100644
--- a/src/java/org/apache/fop/pdf/PDFResources.java
+++ b/src/java/org/apache/fop/pdf/PDFResources.java
@@ -21,9 +21,8 @@ package org.apache.fop.pdf;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -46,33 +45,33 @@ public class PDFResources extends PDFDictionary {
/**
* /Font objects keyed by their internal name
*/
- protected Map fonts = new HashMap();
+ protected Map<String, PDFFont> fonts = new LinkedHashMap<String, PDFFont>();
/**
* Set of XObjects
*/
- protected Set xObjects = new HashSet();
+ protected Set<PDFXObject> xObjects = new LinkedHashSet<PDFXObject>();
/**
* Set of patterns
*/
- protected Set patterns = new HashSet();
+ protected Set<PDFPattern> patterns = new LinkedHashSet<PDFPattern>();
/**
* Set of shadings
*/
- protected Set shadings = new HashSet();
+ protected Set<PDFShading> shadings = new LinkedHashSet<PDFShading>();
/**
* Set of ExtGStates
*/
- protected Set gstates = new HashSet();
+ protected Set<PDFGState> gstates = new LinkedHashSet<PDFGState>();
/** Map of color spaces (key: color space name) */
- protected Map colorSpaces = new HashMap();
+ protected Map<PDFName, PDFColorSpace> colorSpaces = new LinkedHashMap<PDFName, PDFColorSpace>();
/** Map of ICC color spaces (key: ICC profile description) */
- protected Map iccColorSpaces = new HashMap();
+ protected Map<String, PDFICCBasedColorSpace> iccColorSpaces = new LinkedHashMap<String, PDFICCBasedColorSpace>();
/**
* create a /Resources object.
@@ -168,7 +167,7 @@ public class PDFResources extends PDFDictionary {
PDFICCBasedColorSpace icc = (PDFICCBasedColorSpace)colorSpace;
String desc = ColorProfileUtil.getICCProfileDescription(
icc.getICCStream().getICCProfile());
- this.iccColorSpaces.put(desc, colorSpace);
+ this.iccColorSpaces.put(desc, icc);
}
}
@@ -178,7 +177,7 @@ public class PDFResources extends PDFDictionary {
* @return the requested color space or null if it wasn't found
*/
public PDFICCBasedColorSpace getICCColorSpaceByProfileName(String desc) {
- PDFICCBasedColorSpace cs = (PDFICCBasedColorSpace)this.iccColorSpaces.get(desc);
+ PDFICCBasedColorSpace cs = this.iccColorSpaces.get(desc);
return cs;
}
@@ -188,7 +187,7 @@ public class PDFResources extends PDFDictionary {
* @return the requested color space or null if it wasn't found
*/
public PDFColorSpace getColorSpace(PDFName name) {
- PDFColorSpace cs = (PDFColorSpace)this.colorSpaces.get(name);
+ PDFColorSpace cs = this.colorSpaces.get(name);
return cs;
}
@@ -202,28 +201,24 @@ public class PDFResources extends PDFDictionary {
if (!this.fonts.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
/* construct PDF dictionary of font object references */
- Iterator fontIterator = this.fonts.keySet().iterator();
- while (fontIterator.hasNext()) {
- String fontName = (String)fontIterator.next();
- dict.put(fontName, (PDFFont)this.fonts.get(fontName));
+ for (Map.Entry<String, PDFFont> entry : fonts.entrySet()) {
+ dict.put(entry.getKey(), entry.getValue());
}
put("Font", dict);
}
if (!this.shadings.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
- for (Iterator iter = shadings.iterator(); iter.hasNext();) {
- PDFShading currentShading = (PDFShading)iter.next();
- dict.put(currentShading.getName(), currentShading);
+ for (PDFShading shading : shadings) {
+ dict.put(shading.getName(), shading);
}
put("Shading", dict);
}
if (!this.patterns.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
- for (Iterator iter = patterns.iterator(); iter.hasNext();) {
- PDFPattern currentPattern = (PDFPattern)iter.next();
- dict.put(currentPattern.getName(), currentPattern);
+ for (PDFPattern pattern : patterns) {
+ dict.put(pattern.getName(), pattern);
}
put("Pattern", dict);
}
@@ -237,26 +232,23 @@ public class PDFResources extends PDFDictionary {
if (this.xObjects != null && !this.xObjects.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
- for (Iterator iter = xObjects.iterator(); iter.hasNext();) {
- PDFXObject xobj = (PDFXObject)iter.next();
- dict.put(xobj.getName().toString(), xobj);
+ for (PDFXObject xObject : xObjects) {
+ dict.put(xObject.getName().toString(), xObject);
}
put("XObject", dict);
}
if (!this.gstates.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
- for (Iterator iter = gstates.iterator(); iter.hasNext();) {
- PDFGState gs = (PDFGState)iter.next();
- dict.put(gs.getName(), gs);
+ for (PDFGState gstate : gstates) {
+ dict.put(gstate.getName(), gstate);
}
put("ExtGState", dict);
}
if (!this.colorSpaces.isEmpty()) {
PDFDictionary dict = new PDFDictionary(this);
- for (Iterator iter = colorSpaces.values().iterator(); iter.hasNext();) {
- PDFColorSpace colorSpace = (PDFColorSpace)iter.next();
+ for (PDFColorSpace colorSpace : colorSpaces.values()) {
dict.put(colorSpace.getName(), colorSpace);
}
put("ColorSpace", dict);
diff --git a/src/java/org/apache/fop/render/ImageHandler.java b/src/java/org/apache/fop/render/ImageHandler.java
index fe6952de1..190d7c5d6 100644
--- a/src/java/org/apache/fop/render/ImageHandler.java
+++ b/src/java/org/apache/fop/render/ImageHandler.java
@@ -33,7 +33,8 @@ public interface ImageHandler extends ImageHandlerBase {
* Indicates whether the image handler is compatible with the indicated target represented
* by the rendering context object and with the image to be processed. The image is also
* passed as a parameter because a handler might not support every subtype of image that is
- * presented. For example: in the case of {@link ImageXMLDOM}, the image might carry an SVG
+ * presented. For example: in the case of
+ * {@link org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM}, the image might carry an SVG
* or some other XML format. One handler might only handle SVG but no other XML format.
* @param targetContext the target rendering context
* @param image the image to be processed (or null if only to check based on the rendering
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index 7823a2ce6..2ae95dd4c 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -58,7 +58,8 @@ import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
/**
- * {@link 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 {
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java b/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java
index 842456f69..824ecbabb 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMap.java
@@ -27,7 +27,7 @@ import org.xml.sax.helpers.AttributesImpl;
/**
* This extension allows to include an AFP form map resource. It is implemented as an extension
- * attachment ({@link ExtensionAttachment}).
+ * attachment ({@link org.apache.fop.fo.extensions.ExtensionAttachment}).
*/
public class AFPIncludeFormMap extends AFPExtensionAttachment {
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java
index 37f818f64..c5079b2bd 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPIncludeFormMapElement.java
@@ -32,8 +32,8 @@ import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.extensions.ExtensionAttachment;
/**
- * This class extends the {@link ExtensionObj} class. It represents the "include-form-map"
- * extension in the FO tree.
+ * This class extends the {@link org.apache.fop.fo.extensions.ExtensionObj} class.
+ * It represents the "include-form-map" extension in the FO tree.
*/
public class AFPIncludeFormMapElement extends AbstractAFPExtensionObject {
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java
index 0900d40b4..1e6aee7d5 100644
--- a/src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageOverlay.java
@@ -25,7 +25,7 @@ import org.xml.sax.helpers.AttributesImpl;
/**
* This extension allows to include an AFP Page Overlay resource. It is implemented as an extension
- * attachment ({@link ExtensionAttachment}).
+ * attachment ({@link org.apache.fop.fo.extensions.ExtensionAttachment}).
*/
public class AFPPageOverlay extends AFPExtensionAttachment {
diff --git a/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
index c98c05a8e..0c6ebde56 100644
--- a/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/AbstractBitmapDocumentHandler.java
@@ -47,7 +47,8 @@ import org.apache.fop.render.java2d.Java2DPainter;
import org.apache.fop.render.java2d.Java2DUtil;
/**
- * Abstract {@link IFDocumentHandler} implementation for producing bitmap images.
+ * Abstract {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * for producing bitmap images.
*/
public abstract class AbstractBitmapDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
diff --git a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
index 05c44a1a6..ed92b852f 100644
--- a/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/PNGDocumentHandler.java
@@ -23,7 +23,8 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
/**
- * {@link IFDocumentHandler} implementation that produces PNG files.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that produces PNG files.
*/
public class PNGDocumentHandler extends AbstractBitmapDocumentHandler {
diff --git a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
index 4b7fa3c2d..1c9a39bbe 100644
--- a/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/bitmap/TIFFDocumentHandler.java
@@ -23,7 +23,8 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.intermediate.IFDocumentHandlerConfigurator;
/**
- * {@link IFDocumentHandler} implementation that produces TIFF files.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that produces TIFF files.
*/
public class TIFFDocumentHandler extends AbstractBitmapDocumentHandler {
diff --git a/src/java/org/apache/fop/render/intermediate/IFContext.java b/src/java/org/apache/fop/render/intermediate/IFContext.java
index c59a02ba8..681b996e4 100644
--- a/src/java/org/apache/fop/render/intermediate/IFContext.java
+++ b/src/java/org/apache/fop/render/intermediate/IFContext.java
@@ -145,7 +145,7 @@ public class IFContext {
/**
* Resets the current structure tree element.
- * @see #setStructureTreeElement(String)
+ * @see #setStructureTreeElement(StructureTreeElement)
*/
public void resetStructureTreeElement() {
setStructureTreeElement(null);
@@ -154,7 +154,7 @@ public class IFContext {
/**
* Returns the current structure tree element.
* @return the structure tree element (or null if no element is active)
- * @see #setStructureTreeElement(String)
+ * @see #setStructureTreeElement(StructureTreeElement)
*/
public StructureTreeElement getStructureTreeElement() {
return this.structureTreeElement;
diff --git a/src/java/org/apache/fop/render/intermediate/IFUtil.java b/src/java/org/apache/fop/render/intermediate/IFUtil.java
index e8651a3df..c4f681936 100644
--- a/src/java/org/apache/fop/render/intermediate/IFUtil.java
+++ b/src/java/org/apache/fop/render/intermediate/IFUtil.java
@@ -147,8 +147,8 @@ public final class IFUtil {
/**
* Sets up the fonts on a document handler. If the document handler provides a configurator
- * object the configuration from the {@link FopFactory} will be used. Otherwise,
- * a default font configuration will be set up.
+ * object the configuration from the {@link org.apache.fop.apps.FopFactory} will be used.
+ * Otherwise, a default font configuration will be set up.
* @param documentHandler the document handler
* @param fontInfo the font info object (may be null)
* @throws FOPException if an error occurs while setting up the fonts
@@ -175,8 +175,8 @@ public final class IFUtil {
/**
* Sets up the fonts on a document handler. If the document handler provides a configurator
- * object the configuration from the {@link FopFactory} will be used. Otherwise,
- * a default font configuration will be set up.
+ * object the configuration from the {@link org.apache.fop.apps.FopFactory} will be used.
+ * Otherwise, a default font configuration will be set up.
* @param documentHandler the document handler
* @throws FOPException if an error occurs while setting up the fonts
*/
diff --git a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
index 7ac350d5d..9c404be3e 100644
--- a/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
+++ b/src/java/org/apache/fop/render/java2d/ConfiguredFontCollection.java
@@ -89,7 +89,8 @@ public class ConfiguredFontCollection implements FontCollection {
font = new CustomFontMetricsMapper(fontMetrics, fontSource);
} else {
CustomFont fontMetrics = FontLoader.loadFont(
- fontFile, null, true, EncodingMode.AUTO,
+ fontFile, null, true, configFontInfo.getEmbeddingMode(),
+ EncodingMode.AUTO,
configFontInfo.getKerning(),
configFontInfo.getAdvanced(), fontResolver);
font = new CustomFontMetricsMapper(fontMetrics);
diff --git a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
index 5d964cbbf..36df00f20 100644
--- a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
+++ b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
@@ -36,7 +36,7 @@ import org.apache.fop.fonts.Typeface;
/**
* FontMetricsMapper that delegates most methods to an underlying
- * {@link FontMetrics} instance. This class was designed to allow
+ * {@link org.apache.fop.fonts.FontMetrics} instance. This class was designed to allow
* the underlying {@link Font} to be loaded from a
* user-configured file not registered in the current graphics environment.
*/
diff --git a/src/java/org/apache/fop/render/java2d/Java2DPainter.java b/src/java/org/apache/fop/render/java2d/Java2DPainter.java
index dd830a15b..575242d38 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DPainter.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DPainter.java
@@ -47,7 +47,8 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
/**
- * {@link 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 {
diff --git a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
index 52e522c7a..332b4a77d 100644
--- a/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
+++ b/src/java/org/apache/fop/render/pcl/PCLDocumentHandler.java
@@ -45,7 +45,8 @@ import org.apache.fop.render.java2d.Java2DUtil;
import org.apache.fop.render.pcl.extensions.PCLElementMapping;
/**
- * {@link IFDocumentHandler} implementation that produces PCL 5.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that produces PCL 5.
*/
public class PCLDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
implements PCLConstants {
diff --git a/src/java/org/apache/fop/render/pcl/PCLPainter.java b/src/java/org/apache/fop/render/pcl/PCLPainter.java
index 9fc575456..0d630826c 100644
--- a/src/java/org/apache/fop/render/pcl/PCLPainter.java
+++ b/src/java/org/apache/fop/render/pcl/PCLPainter.java
@@ -58,7 +58,8 @@ import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
/**
- * {@link 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 {
diff --git a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
index 59d3930f7..46e8ebe95 100644
--- a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
@@ -20,13 +20,16 @@
package org.apache.fop.render.pdf;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
+import java.awt.image.IndexColorModel;
+import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
+import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFConformanceException;
import org.apache.fop.pdf.PDFDeviceColorSpace;
@@ -50,7 +53,11 @@ public abstract class AbstractImageAdapter implements PDFImage {
/** the image */
protected Image image;
- private PDFICCStream pdfICCStream = null;
+ private PDFICCStream pdfICCStream;
+
+ private static final int MAX_HIVAL = 255;
+
+ private boolean multipleFiltersAllowed = true;
/**
* Creates a new PDFImage from an Image instance.
@@ -203,6 +210,68 @@ public abstract class AbstractImageAdapter implements PDFImage {
}
/**
+ * This is to be used by populateXObjectDictionary() when the image is palette based.
+ * @param dict the dictionary to fill in
+ * @param icm the image color model
+ */
+ protected void populateXObjectDictionaryForIndexColorModel(PDFDictionary dict, IndexColorModel icm) {
+ PDFArray indexed = new PDFArray(dict);
+ indexed.add(new PDFName("Indexed"));
+ if (icm.getColorSpace().getType() != ColorSpace.TYPE_RGB) {
+ log.warn("Indexed color space is not using RGB as base color space."
+ + " The image may not be handled correctly." + " Base color space: "
+ + icm.getColorSpace() + " Image: " + image.getInfo());
+ }
+ indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
+ int c = icm.getMapSize();
+ int hival = c - 1;
+ if (hival > MAX_HIVAL) {
+ throw new UnsupportedOperationException("hival must not go beyond " + MAX_HIVAL);
+ }
+ indexed.add(Integer.valueOf(hival));
+ int[] palette = new int[c];
+ icm.getRGBs(palette);
+ ByteArrayOutputStream baout = new ByteArrayOutputStream();
+ for (int i = 0; i < c; i++) {
+ // TODO Probably doesn't work for non RGB based color spaces
+ // See log warning above
+ int entry = palette[i];
+ baout.write((entry & 0xFF0000) >> 16);
+ baout.write((entry & 0xFF00) >> 8);
+ baout.write(entry & 0xFF);
+ }
+ indexed.add(baout.toByteArray());
+
+ dict.put("ColorSpace", indexed);
+ dict.put("BitsPerComponent", icm.getPixelSize());
+
+ Integer index = getIndexOfFirstTransparentColorInPalette(icm);
+ if (index != null) {
+ PDFArray mask = new PDFArray(dict);
+ mask.add(index);
+ mask.add(index);
+ dict.put("Mask", mask);
+ }
+ }
+
+ private static Integer getIndexOfFirstTransparentColorInPalette(IndexColorModel icm) {
+ byte[] alphas = new byte[icm.getMapSize()];
+ byte[] reds = new byte[icm.getMapSize()];
+ byte[] greens = new byte[icm.getMapSize()];
+ byte[] blues = new byte[icm.getMapSize()];
+ icm.getAlphas(alphas);
+ icm.getReds(reds);
+ icm.getGreens(greens);
+ icm.getBlues(blues);
+ for (int i = 0; i < icm.getMapSize(); i++) {
+ if ((alphas[i] & 0xFF) == 0) {
+ return Integer.valueOf(i);
+ }
+ }
+ return null;
+ }
+
+ /**
* Converts a ColorSpace object to a PDFColorSpace object.
* @param cs ColorSpace instance
* @return PDFColorSpace new converted object
@@ -226,5 +295,17 @@ public abstract class AbstractImageAdapter implements PDFImage {
return pdfCS;
}
+ /** {@inheritDoc} */
+ public boolean multipleFiltersAllowed() {
+ return multipleFiltersAllowed;
+ }
+
+ /**
+ * Disallows multiple filters.
+ */
+ public void disallowMultipleFilters() {
+ multipleFiltersAllowed = false;
+ }
+
}
diff --git a/src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java b/src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java
new file mode 100644
index 000000000..b9f5e1d28
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/ImageRawPNGAdapter.java
@@ -0,0 +1,260 @@
+/*
+ * 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$ */
+
+// Original author: Matthias Reichenbacher
+
+package org.apache.fop.render.pdf;
+
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+
+import org.apache.fop.pdf.BitmapImage;
+import org.apache.fop.pdf.FlateFilter;
+import org.apache.fop.pdf.PDFColor;
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFFilter;
+import org.apache.fop.pdf.PDFFilterException;
+import org.apache.fop.pdf.PDFFilterList;
+import org.apache.fop.pdf.PDFICCStream;
+import org.apache.fop.pdf.PDFReference;
+
+public class ImageRawPNGAdapter extends AbstractImageAdapter {
+
+ /** logging instance */
+ private static Log log = LogFactory.getLog(ImageRawPNGAdapter.class);
+
+ private PDFICCStream pdfICCStream;
+ private PDFFilter pdfFilter;
+ private String maskRef;
+ private PDFReference softMask;
+ private int numberOfInterleavedComponents;
+
+ /**
+ * Creates a new PDFImage from an Image instance.
+ * @param image the image
+ * @param key XObject key
+ */
+ public ImageRawPNGAdapter(ImageRawPNG image, String key) {
+ super(image, key);
+ }
+
+ /** {@inheritDoc} */
+ public void setup(PDFDocument doc) {
+ super.setup(doc);
+ ColorModel cm = ((ImageRawPNG) this.image).getColorModel();
+ if (cm instanceof IndexColorModel) {
+ numberOfInterleavedComponents = 1;
+ } else {
+ // this can be 1 (gray), 2 (gray + alpha), 3 (rgb) or 4 (rgb + alpha)
+ // numberOfInterleavedComponents = (cm.hasAlpha() ? 1 : 0) + cm.getNumColorComponents();
+ numberOfInterleavedComponents = cm.getNumComponents();
+ }
+
+ // set up image compression for non-alpha channel
+ FlateFilter flate;
+ try {
+ flate = new FlateFilter();
+ flate.setApplied(true);
+ flate.setPredictor(FlateFilter.PREDICTION_PNG_OPT);
+ if (numberOfInterleavedComponents < 3) {
+ // means palette (1) or gray (1) or gray + alpha (2)
+ flate.setColors(1);
+ } else {
+ // means rgb (3) or rgb + alpha (4)
+ flate.setColors(3);
+ }
+ flate.setColumns(image.getSize().getWidthPx());
+ flate.setBitsPerComponent(this.getBitsPerComponent());
+ } catch (PDFFilterException e) {
+ throw new RuntimeException("FlateFilter configuration error", e);
+ }
+ this.pdfFilter = flate;
+ this.disallowMultipleFilters();
+
+ // Handle transparency channel if applicable; note that for palette images the transparency is
+ // not TRANSLUCENT
+ if (cm.hasAlpha() && cm.getTransparency() == ColorModel.TRANSLUCENT) {
+ doc.getProfile().verifyTransparencyAllowed(image.getInfo().getOriginalURI());
+ // TODO: Implement code to combine image with background color if transparency is not allowed
+ // here we need to inflate the PNG pixel data, which includes alpha, separate the alpha channel
+ // and then deflate it back again
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater());
+ InputStream in = ((ImageRawStream) image).createInputStream();
+ try {
+ InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
+ DataInputStream dataStream = new DataInputStream(infStream);
+ // offset is the byte offset of the alpha component
+ int offset = numberOfInterleavedComponents - 1; // 1 for GA, 3 for RGBA
+ int numColumns = image.getSize().getWidthPx();
+ int bytesPerRow = numberOfInterleavedComponents * numColumns;
+ int filter;
+ // read line by line; the first byte holds the filter
+ while ((filter = dataStream.read()) != -1) {
+ byte[] bytes = new byte[bytesPerRow];
+ dataStream.readFully(bytes, 0, bytesPerRow);
+ dos.write((byte) filter);
+ for (int j = 0; j < numColumns; j++) {
+ dos.write(bytes, offset, 1);
+ offset += numberOfInterleavedComponents;
+ }
+ offset = numberOfInterleavedComponents - 1;
+ }
+ dos.close();
+ } catch (IOException e) {
+ throw new RuntimeException("Error processing transparency channel:", e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ // set up alpha channel compression
+ FlateFilter transFlate;
+ try {
+ transFlate = new FlateFilter();
+ transFlate.setApplied(true);
+ transFlate.setPredictor(FlateFilter.PREDICTION_PNG_OPT);
+ transFlate.setColors(1);
+ transFlate.setColumns(image.getSize().getWidthPx());
+ transFlate.setBitsPerComponent(this.getBitsPerComponent());
+ } catch (PDFFilterException e) {
+ throw new RuntimeException("FlateFilter configuration error", e);
+ }
+ BitmapImage alphaMask = new BitmapImage("Mask:" + this.getKey(), image.getSize().getWidthPx(),
+ image.getSize().getHeightPx(), baos.toByteArray(), null);
+ alphaMask.setPDFFilter(transFlate);
+ alphaMask.disallowMultipleFilters();
+ alphaMask.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
+ softMask = doc.addImage(null, alphaMask).makeReference();
+ }
+ }
+
+ /** {@inheritDoc} */
+ public PDFDeviceColorSpace getColorSpace() {
+ // DeviceGray, DeviceRGB, or DeviceCMYK
+ return toPDFColorSpace(image.getColorSpace());
+ }
+
+ /** {@inheritDoc} */
+ public int getBitsPerComponent() {
+ return ((ImageRawPNG) this.image).getBitDepth();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isTransparent() {
+ return ((ImageRawPNG) this.image).isTransparent();
+ }
+
+ /** {@inheritDoc} */
+ public PDFColor getTransparentColor() {
+ return new PDFColor(((ImageRawPNG) this.image).getTransparentColor());
+ }
+
+ /** {@inheritDoc} */
+ public String getMask() {
+ return maskRef;
+ }
+
+ /** {@inheritDoc} */
+ public String getSoftMask() {
+ return softMask.toString();
+ }
+
+ /** {@inheritDoc} */
+ public PDFReference getSoftMaskReference() {
+ return softMask;
+ }
+
+ /** {@inheritDoc} */
+ public PDFFilter getPDFFilter() {
+ return pdfFilter;
+ }
+
+ /** {@inheritDoc} */
+ public void outputContents(OutputStream out) throws IOException {
+ InputStream in = ((ImageRawStream) image).createInputStream();
+
+ try {
+ if (numberOfInterleavedComponents == 1 || numberOfInterleavedComponents == 3) {
+ // means we have Gray, RGB, or Palette
+ IOUtils.copy(in, out);
+ } else {
+ // means we have Gray + alpha or RGB + alpha
+ // TODO: since we have alpha here do this when the alpha channel is extracted
+ int numBytes = numberOfInterleavedComponents - 1; // 1 for Gray, 3 for RGB
+ int numColumns = image.getSize().getWidthPx();
+ InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
+ DataInputStream dataStream = new DataInputStream(infStream);
+ int offset = 0;
+ int bytesPerRow = numberOfInterleavedComponents * numColumns;
+ int filter;
+ // here we need to inflate the PNG pixel data, which includes alpha, separate the alpha
+ // channel and then deflate the RGB channels back again
+ DeflaterOutputStream dos = new DeflaterOutputStream(out, new Deflater());
+ while ((filter = dataStream.read()) != -1) {
+ byte[] bytes = new byte[bytesPerRow];
+ dataStream.readFully(bytes, 0, bytesPerRow);
+ dos.write((byte) filter);
+ for (int j = 0; j < numColumns; j++) {
+ dos.write(bytes, offset, numBytes);
+ offset += numberOfInterleavedComponents;
+ }
+ offset = 0;
+ }
+ dos.close();
+ }
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public PDFICCStream getICCStream() {
+ return pdfICCStream;
+ }
+
+ /** {@inheritDoc} */
+ public String getFilterHint() {
+ return PDFFilterList.PRECOMPRESSED_FILTER;
+ }
+
+ public void populateXObjectDictionary(PDFDictionary dict) {
+ ColorModel cm = ((ImageRawPNG) image).getColorModel();
+ if (cm instanceof IndexColorModel) {
+ IndexColorModel icm = (IndexColorModel) cm;
+ super.populateXObjectDictionaryForIndexColorModel(dict, icm);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java b/src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java
index c38a2edaf..b0b7b79d1 100644
--- a/src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/ImageRenderedAdapter.java
@@ -27,8 +27,6 @@ import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -36,14 +34,12 @@ import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.fop.pdf.AlphaRasterImage;
-import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.pdf.PDFDeviceColorSpace;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFFilter;
import org.apache.fop.pdf.PDFFilterList;
-import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFReference;
/**
@@ -162,30 +158,6 @@ public class ImageRenderedAdapter extends AbstractImageAdapter {
return (getImage().getTransparentColor() != null);
}
- private static Integer getIndexOfFirstTransparentColorInPalette(RenderedImage image) {
- ColorModel cm = image.getColorModel();
- if (cm instanceof IndexColorModel) {
- IndexColorModel icm = (IndexColorModel)cm;
- //Identify the transparent color in the palette
- byte[] alphas = new byte[icm.getMapSize()];
- byte[] reds = new byte[icm.getMapSize()];
- byte[] greens = new byte[icm.getMapSize()];
- byte[] blues = new byte[icm.getMapSize()];
- icm.getAlphas(alphas);
- icm.getReds(reds);
- icm.getGreens(greens);
- icm.getBlues(blues);
- for (int i = 0;
- i < ((IndexColorModel) cm).getMapSize();
- i++) {
- if ((alphas[i] & 0xFF) == 0) {
- return Integer.valueOf(i);
- }
- }
- }
- return null;
- }
-
/** {@inheritDoc} */
@Override
public PDFColor getTransparentColor() {
@@ -230,54 +202,13 @@ public class ImageRenderedAdapter extends AbstractImageAdapter {
}
}
- private static final int MAX_HIVAL = 255;
-
/** {@inheritDoc} */
@Override
public void populateXObjectDictionary(PDFDictionary dict) {
ColorModel cm = getEffectiveColorModel();
if (cm instanceof IndexColorModel) {
- IndexColorModel icm = (IndexColorModel)cm;
- PDFArray indexed = new PDFArray(dict);
- indexed.add(new PDFName("Indexed"));
-
- if (icm.getColorSpace().getType() != ColorSpace.TYPE_RGB) {
- log.warn("Indexed color space is not using RGB as base color space."
- + " The image may not be handled correctly."
- + " Base color space: " + icm.getColorSpace()
- + " Image: " + image.getInfo());
- }
- indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
- int c = icm.getMapSize();
- int hival = c - 1;
- if (hival > MAX_HIVAL) {
- throw new UnsupportedOperationException("hival must not go beyond " + MAX_HIVAL);
- }
- indexed.add(Integer.valueOf(hival));
- int[] palette = new int[c];
- icm.getRGBs(palette);
- ByteArrayOutputStream baout = new ByteArrayOutputStream();
- for (int i = 0; i < c; i++) {
- //TODO Probably doesn't work for non RGB based color spaces
- //See log warning above
- int entry = palette[i];
- baout.write((entry & 0xFF0000) >> 16);
- baout.write((entry & 0xFF00) >> 8);
- baout.write(entry & 0xFF);
- }
- indexed.add(baout.toByteArray());
- IOUtils.closeQuietly(baout);
-
- dict.put("ColorSpace", indexed);
- dict.put("BitsPerComponent", icm.getPixelSize());
-
- Integer index = getIndexOfFirstTransparentColorInPalette(getImage().getRenderedImage());
- if (index != null) {
- PDFArray mask = new PDFArray(dict);
- mask.add(index);
- mask.add(index);
- dict.put("Mask", mask);
- }
+ IndexColorModel icm = (IndexColorModel) cm;
+ super.populateXObjectDictionaryForIndexColorModel(dict, icm);
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java
new file mode 100644
index 000000000..3475954a8
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerRawPNG.java
@@ -0,0 +1,65 @@
+/*
+ * 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$ */
+
+// Original author: Matthias Reichenbacher
+
+package org.apache.fop.render.pdf;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+
+import org.apache.fop.pdf.PDFImage;
+import org.apache.fop.render.RenderingContext;
+
+/**
+ * Image handler implementation which handles CCITT encoded images (CCITT fax group 3/4)
+ * for PDF output.
+ */
+public class PDFImageHandlerRawPNG extends AbstractPDFImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RAW_PNG};
+
+ @Override
+ PDFImage createPDFImage(Image image, String xobjectKey) {
+ return new ImageRawPNGAdapter((ImageRawPNG) image, xobjectKey);
+ }
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 100;
+ }
+
+ /** {@inheritDoc} */
+ public Class<ImageRawPNG> getSupportedImageClass() {
+ return ImageRawPNG.class;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCompatible(RenderingContext targetContext, Image image) {
+ return (image == null || image instanceof ImageRawPNG)
+ && targetContext instanceof PDFRenderingContext;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/FontResourceCache.java b/src/java/org/apache/fop/render/ps/FontResourceCache.java
index 9d4090eed..1514d201e 100644
--- a/src/java/org/apache/fop/render/ps/FontResourceCache.java
+++ b/src/java/org/apache/fop/render/ps/FontResourceCache.java
@@ -42,19 +42,20 @@ class FontResourceCache {
}
/**
- * Returns the PSResource for the given font key.
+ * Returns the PSFontResource for the given font key.
* @param key the font key ("F*")
- * @return the matching PSResource
+ * @return the matching PSFontResource instance
*/
- public PSResource getPSResourceForFontKey(String key) {
- PSResource res = null;
+ public PSFontResource getFontResourceForFontKey(String key) {
+ PSFontResource res = null;
if (this.fontResources != null) {
- res = (PSResource)this.fontResources.get(key);
+ res = (PSFontResource)this.fontResources.get(key);
} else {
this.fontResources = new java.util.HashMap();
}
if (res == null) {
- res = new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key));
+ res = PSFontResource.createFontResource(
+ new PSResource(PSResource.TYPE_FONT, getPostScriptNameForFontKey(key)));
this.fontResources.put(key, res);
}
return res;
@@ -76,9 +77,9 @@ class FontResourceCache {
throw new IllegalStateException("Font not available: " + key);
}
if (postFix == null) {
- return tf.getFontName();
+ return tf.getEmbedFontName();
} else {
- return tf.getFontName() + postFix;
+ return tf.getEmbedFontName() + postFix;
}
}
diff --git a/src/java/org/apache/fop/render/ps/ImageEncoderPNG.java b/src/java/org/apache/fop/render/ps/ImageEncoderPNG.java
new file mode 100644
index 000000000..bcda90bda
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/ImageEncoderPNG.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.render.ps;
+
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.ps.ImageEncoder;
+
+/**
+ * ImageEncoder implementation for PNG images.
+ */
+public class ImageEncoderPNG implements ImageEncoder {
+ private final ImageRawPNG image;
+ private int numberOfInterleavedComponents;
+
+ /**
+ * Main constructor
+ * @param image the PNG image
+ */
+ public ImageEncoderPNG(ImageRawPNG image) {
+ this.image = image;
+ ColorModel cm = ((ImageRawPNG) this.image).getColorModel();
+ if (cm instanceof IndexColorModel) {
+ numberOfInterleavedComponents = 1;
+ } else {
+ // this can be 1 (gray), 2 (gray + alpha), 3 (rgb) or 4 (rgb + alpha)
+ // numberOfInterleavedComponents = (cm.hasAlpha() ? 1 : 0) + cm.getNumColorComponents();
+ numberOfInterleavedComponents = cm.getNumComponents();
+ }
+ }
+
+ /** {@inheritDoc} */
+ public void writeTo(OutputStream out) throws IOException {
+ // TODO: refactor this code with equivalent PDF code
+ InputStream in = ((ImageRawStream) image).createInputStream();
+ try {
+ if (numberOfInterleavedComponents == 1 || numberOfInterleavedComponents == 3) {
+ // means we have Gray, RGB, or Palette
+ IOUtils.copy(in, out);
+ } else {
+ // means we have Gray + alpha or RGB + alpha
+ int numBytes = numberOfInterleavedComponents - 1; // 1 for Gray, 3 for RGB
+ int numColumns = image.getSize().getWidthPx();
+ InflaterInputStream infStream = new InflaterInputStream(in, new Inflater());
+ DataInputStream dataStream = new DataInputStream(infStream);
+ int offset = 0;
+ int bytesPerRow = numberOfInterleavedComponents * numColumns;
+ int filter;
+ // here we need to inflate the PNG pixel data, which includes alpha, separate the alpha
+ // channel and then deflate the RGB channels back again
+ // TODO: not using the baos below and using the original out instead (as happens in PDF)
+ // would be preferable but that does not work with the rest of the postscript code; this
+ // needs to be revisited
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DeflaterOutputStream dos = new DeflaterOutputStream(/* out */baos, new Deflater());
+ while ((filter = dataStream.read()) != -1) {
+ byte[] bytes = new byte[bytesPerRow];
+ dataStream.readFully(bytes, 0, bytesPerRow);
+ dos.write((byte) filter);
+ for (int j = 0; j < numColumns; j++) {
+ dos.write(bytes, offset, numBytes);
+ offset += numberOfInterleavedComponents;
+ }
+ offset = 0;
+ }
+ dos.close();
+ IOUtils.copy(new ByteArrayInputStream(baos.toByteArray()), out);
+ }
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getImplicitFilter() {
+ String filter = "<< /Predictor 15 /Columns " + image.getSize().getWidthPx();
+ filter += " /Colors " + (numberOfInterleavedComponents > 2 ? 3 : 1);
+ filter += " /BitsPerComponent " + image.getBitDepth() + " >> /FlateDecode";
+ return filter;
+ }
+}
diff --git a/src/java/org/apache/fop/render/ps/NativeTextHandler.java b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
index 33adcb8d7..e8f123dc5 100644
--- a/src/java/org/apache/fop/render/ps/NativeTextHandler.java
+++ b/src/java/org/apache/fop/render/ps/NativeTextHandler.java
@@ -100,12 +100,6 @@ public class NativeTextHandler implements PSTextHandler {
//nop
}
- /** {@inheritDoc} */
- public void drawString(String text, float x, float y) throws IOException {
- // TODO Remove me after removing the deprecated method in TextHandler.
- throw new UnsupportedOperationException("Deprecated method!");
- }
-
/**
* Draw a string to the PostScript document. The text is painted using
* text operations.
diff --git a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
index 95647d820..0fe564827 100644
--- a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
@@ -50,6 +50,7 @@ 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.render.intermediate.AbstractBinaryWritingIFDocumentHandler;
import org.apache.fop.render.intermediate.IFContext;
@@ -63,7 +64,8 @@ import org.apache.fop.render.ps.extensions.PSSetPageDevice;
import org.apache.fop.render.ps.extensions.PSSetupCode;
/**
- * {@link IFDocumentHandler} implementation that produces PostScript.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that produces PostScript.
*/
public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
@@ -106,6 +108,8 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
private static final int COMMENT_PAGE_TRAILER = 2;
private static final int PAGE_TRAILER_CODE_BEFORE = 3;
+ private PSEventProducer eventProducer;
+
/**
* Default constructor.
*/
@@ -125,7 +129,9 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
/** {@inheritDoc} */
public void setContext(IFContext context) {
super.setContext(context);
- this.psUtil = new PSRenderingUtil(context.getUserAgent());
+ FOUserAgent userAgent = context.getUserAgent();
+ this.psUtil = new PSRenderingUtil(userAgent);
+ eventProducer = PSEventProducer.Provider.get(userAgent.getEventBroadcaster());
}
/** {@inheritDoc} */
@@ -144,7 +150,7 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
try {
OutputStream out;
if (psUtil.isOptimizeResources()) {
- this.tempFile = File.createTempFile("fop", null);
+ this.tempFile = File.createTempFile("fop", ".ps");
out = new java.io.FileOutputStream(this.tempFile);
out = new java.io.BufferedOutputStream(out);
} else {
@@ -202,7 +208,7 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
gen.writeDSCComment(DSCConstants.BEGIN_SETUP);
PSRenderingUtil.writeSetupCodeList(gen, setupCodeList, "SetupCode");
if (!psUtil.isOptimizeResources()) {
- this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo));
+ this.fontResources.addAll(PSFontUtils.writeFontDict(gen, fontInfo, eventProducer));
} else {
gen.commentln("%FOPFontSetup"); //Place-holder, will be replaced in the second pass
}
@@ -257,8 +263,8 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
in = new java.io.BufferedInputStream(in);
try {
try {
- ResourceHandler handler = new ResourceHandler(getUserAgent(), this.fontInfo,
- resTracker, this.formResources);
+ ResourceHandler handler = new ResourceHandler(getUserAgent(), eventProducer,
+ this.fontInfo, resTracker, this.formResources);
handler.process(in, this.outputStream,
this.currentPageNumber, this.documentBoundingBox);
this.outputStream.flush();
@@ -546,8 +552,8 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
* @param key the font key ("F*")
* @return the matching PSResource
*/
- protected PSResource getPSResourceForFontKey(String key) {
- return this.fontResources.getPSResourceForFontKey(key);
+ protected PSFontResource getPSResourceForFontKey(String key) {
+ return this.fontResources.getFontResourceForFontKey(key);
}
/**
diff --git a/src/java/org/apache/fop/render/ps/PSEventProducer.java b/src/java/org/apache/fop/render/ps/PSEventProducer.java
index 702380a4d..bffdf2236 100644
--- a/src/java/org/apache/fop/render/ps/PSEventProducer.java
+++ b/src/java/org/apache/fop/render/ps/PSEventProducer.java
@@ -53,4 +53,11 @@ public interface PSEventProducer extends EventProducer {
*/
void postscriptDictionaryParseError(Object source, String content, Exception e);
+ /**
+ * PostScript Level 3 features are necessary.
+ *
+ * @param source the event source
+ * @event.severity FATAL
+ */
+ void postscriptLevel3Needed(Object source);
}
diff --git a/src/java/org/apache/fop/render/ps/PSEventProducer.xml b/src/java/org/apache/fop/render/ps/PSEventProducer.xml
index bcd89ed07..64b22d1a4 100644
--- a/src/java/org/apache/fop/render/ps/PSEventProducer.xml
+++ b/src/java/org/apache/fop/render/ps/PSEventProducer.xml
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<catalogue xml:lang="en">
<message key="postscriptDictionaryParseError">Failed to parse dictionary string. Reason: {e}, content = "{content}"</message>
+ <message key="postscriptLevel3Needed">PostScript Level 3 features are needed to handle this document.</message>
</catalogue>
diff --git a/src/java/org/apache/fop/render/ps/PSFontResource.java b/src/java/org/apache/fop/render/ps/PSFontResource.java
new file mode 100644
index 000000000..8b7b835ed
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSFontResource.java
@@ -0,0 +1,77 @@
+/*
+ * 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.PSResource;
+import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
+
+/**
+ * A DSC resource corresponding to a font. This class handles the possible other resources
+ * that a font may depend on. For example, a CID-keyed font depends on a CIDFont resource, a
+ * CMap resource, and the ProcSet CIDInit resource.
+ */
+abstract class PSFontResource {
+
+ static PSFontResource createFontResource(final PSResource fontResource) {
+ return new PSFontResource() {
+
+ String getName() {
+ return fontResource.getName();
+ }
+
+ void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
+ resourceTracker.notifyResourceUsageOnPage(fontResource);
+ }
+ };
+ }
+
+ static PSFontResource createFontResource(final PSResource fontResource,
+ final PSResource procsetCIDInitResource, final PSResource cmapResource,
+ final PSResource cidFontResource) {
+ return new PSFontResource() {
+
+ String getName() {
+ return fontResource.getName();
+ }
+
+ void notifyResourceUsageOnPage(ResourceTracker resourceTracker) {
+ resourceTracker.notifyResourceUsageOnPage(fontResource);
+ resourceTracker.notifyResourceUsageOnPage(procsetCIDInitResource);
+ resourceTracker.notifyResourceUsageOnPage(cmapResource);
+ resourceTracker.notifyResourceUsageOnPage(cidFontResource);
+ }
+ };
+ }
+
+ /**
+ * Returns the name of the font resource.
+ *
+ * @return the name of the font
+ */
+ abstract String getName();
+
+ /**
+ * Notifies the given resource tracker of all the resources needed by this font.
+ *
+ * @param resourceTracker
+ */
+ abstract void notifyResourceUsageOnPage(ResourceTracker resourceTracker);
+
+}
diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java
index 5e95b5ded..d0d75744f 100644
--- a/src/java/org/apache/fop/render/ps/PSFontUtils.java
+++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java
@@ -23,7 +23,11 @@ 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;
@@ -38,14 +42,26 @@ import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
import org.apache.fop.fonts.Base14Font;
+import org.apache.fop.fonts.CIDFontType;
+import org.apache.fop.fonts.CIDSubset;
+import org.apache.fop.fonts.CMapSegment;
import org.apache.fop.fonts.CustomFont;
+import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.fonts.SingleByteEncoding;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
+import org.apache.fop.fonts.truetype.FontFileReader;
+import org.apache.fop.fonts.truetype.TTFFile;
+import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
+import org.apache.fop.fonts.truetype.TTFOutputStream;
+import org.apache.fop.fonts.truetype.TTFSubSetFile;
+import org.apache.fop.render.ps.fonts.PSTTFOutputStream;
+import org.apache.fop.util.HexEncoder;
/**
* Utility code for font handling in PostScript.
@@ -54,7 +70,6 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
/** logging instance */
protected static final Log log = LogFactory.getLog(PSFontUtils.class);
-
/**
* Generates the PostScript code for the font dictionary. This method should only be
* used if no "resource optimization" is performed, i.e. when the fonts are not embedded
@@ -66,7 +81,22 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
*/
public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo)
throws IOException {
- return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true);
+ return writeFontDict(gen, fontInfo, null);
+ }
+
+ /**
+ * Generates the PostScript code for the font dictionary. This method should only be
+ * used if no "resource optimization" is performed, i.e. when the fonts are not embedded
+ * in a second pass.
+ * @param gen PostScript generator to use for output
+ * @param fontInfo available fonts
+ * @param eventProducer to report events
+ * @return a Map of PSResource instances representing all defined fonts (key: font key)
+ * @throws IOException in case of an I/O problem
+ */
+ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo,
+ PSEventProducer eventProducer) throws IOException {
+ return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true, eventProducer);
}
/**
@@ -76,13 +106,13 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @param gen PostScript generator to use for output
* @param fontInfo available fonts
* @param fonts the set of fonts to work with
+ * @param eventProducer the event producer
* @return a Map of PSResource instances representing all defined fonts (key: font key)
* @throws IOException in case of an I/O problem
*/
- public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo,
- Map<String, Typeface> fonts)
- throws IOException {
- return writeFontDict(gen, fontInfo, fonts, false);
+ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map<String, Typeface> fonts,
+ PSEventProducer eventProducer) throws IOException {
+ return writeFontDict(gen, fontInfo, fonts, false, eventProducer);
}
/**
@@ -96,15 +126,16 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
* @throws IOException in case of an I/O problem
*/
private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo,
- Map<String, Typeface> fonts, boolean encodeAllCharacters) throws IOException {
+ Map<String, Typeface> fonts, boolean encodeAllCharacters, PSEventProducer eventProducer)
+ throws IOException {
gen.commentln("%FOPBeginFontDict");
- Map fontResources = new java.util.HashMap();
+ Map fontResources = new HashMap();
for (String key : fonts.keySet()) {
Typeface tf = getTypeFace(fontInfo, fonts, key);
- PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getFontName());
- fontResources.put(key, fontRes);
- embedFont(gen, tf, fontRes);
+ PSResource fontRes = new PSResource(PSResource.TYPE_FONT, tf.getEmbedFontName());
+ PSFontResource fontResource = embedFont(gen, tf, fontRes, eventProducer);
+ fontResources.put(key, fontResource);
if (tf instanceof SingleByteFont) {
SingleByteFont sbf = (SingleByteFont)tf;
@@ -117,9 +148,18 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
SingleByteEncoding encoding = sbf.getAdditionalEncoding(i);
defineEncoding(gen, encoding);
String postFix = "_" + (i + 1);
- PSResource derivedFontRes = defineDerivedFont(gen, tf.getFontName(),
- tf.getFontName() + postFix, encoding.getName());
- fontResources.put(key + postFix, derivedFontRes);
+ PSResource derivedFontRes;
+ if (tf.getFontType() == FontType.TRUETYPE
+ && sbf.getTrueTypePostScriptVersion() != PostScriptVersion.V2) {
+ derivedFontRes = defineDerivedTrueTypeFont(gen, eventProducer,
+ tf.getEmbedFontName(), tf.getEmbedFontName() + postFix, encoding,
+ sbf.getCMap());
+ } else {
+ derivedFontRes = defineDerivedFont(gen, tf.getEmbedFontName(),
+ tf.getEmbedFontName() + postFix, encoding.getName());
+ }
+ fontResources.put(key + postFix,
+ PSFontResource.createFontResource(derivedFontRes));
}
}
}
@@ -156,12 +196,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
} else {
if (tf instanceof Base14Font) {
//Our Base 14 fonts don't use the default encoding
- redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName());
+ redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName());
} else if (tf instanceof SingleByteFont) {
SingleByteFont sbf = (SingleByteFont)tf;
if (!sbf.isUsingNativeEncoding()) {
//Font has been configured to use an encoding other than the default one
- redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName());
+ redefineFontEncoding(gen, tf.getEmbedFontName(), tf.getEncodingName());
}
}
}
@@ -184,39 +224,299 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
return tf;
}
- /**
- * Embeds a font in the PostScript file.
- * @param gen the PostScript generator
- * @param tf the font
- * @param fontRes the PSResource associated with the font
- * @throws IOException In case of an I/O error
- */
- public static void embedFont(PSGenerator gen, Typeface tf, PSResource fontRes)
- throws IOException {
- boolean embeddedFont = false;
- if (FontType.TYPE1 == tf.getFontType()) {
- if (tf instanceof CustomFont) {
- CustomFont cf = (CustomFont)tf;
- if (isEmbeddable(cf)) {
- InputStream in = getInputStreamOnFont(gen, cf);
- if (in != null) {
- gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE,
- fontRes);
- embedType1Font(gen, in);
- gen.writeDSCComment(DSCConstants.END_RESOURCE);
- gen.getResourceTracker().registerSuppliedResource(fontRes);
- embeddedFont = true;
- } else {
- gen.commentln("%WARNING: Could not embed font: " + cf.getFontName());
- log.warn("Font " + cf.getFontName() + " is marked as supplied in the"
- + " PostScript file but could not be embedded!");
+ private static PSFontResource embedFont(PSGenerator gen, Typeface tf, PSResource fontRes,
+ PSEventProducer eventProducer) throws IOException {
+ FontType fontType = tf.getFontType();
+ PSFontResource fontResource = null;
+ if (!(fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE
+ || fontType == FontType.TYPE0) || !(tf instanceof CustomFont)) {
+ gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
+ fontResource = PSFontResource.createFontResource(fontRes);
+ return fontResource;
+ }
+ CustomFont cf = (CustomFont)tf;
+ if (isEmbeddable(cf)) {
+ InputStream in = getInputStreamOnFont(gen, cf);
+ if (in == null) {
+ gen.commentln("%WARNING: Could not embed font: " + cf.getEmbedFontName());
+ log.warn("Font " + cf.getEmbedFontName() + " is marked as supplied in the"
+ + " PostScript file but could not be embedded!");
+ gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
+ fontResource = PSFontResource.createFontResource(fontRes);
+ return fontResource;
+ }
+ if (fontType == FontType.TYPE0) {
+ if (gen.embedIdentityH()) {
+ checkPostScriptLevel3(gen, eventProducer);
+ /*
+ * First CID-keyed font to be embedded; add
+ * %%IncludeResource: comment for ProcSet CIDInit.
+ */
+ gen.includeProcsetCIDInitResource();
+ }
+ PSResource cidFontResource = embedType2CIDFont(gen,
+ (MultiByteFont) tf, in);
+ fontResource = PSFontResource.createFontResource(fontRes,
+ gen.getProcsetCIDInitResource(), gen.getIdentityHCMapResource(),
+ cidFontResource);
+ }
+ gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, fontRes);
+ if (fontType == FontType.TYPE1) {
+ embedType1Font(gen, in);
+ fontResource = PSFontResource.createFontResource(fontRes);
+ } else if (fontType == FontType.TRUETYPE) {
+ embedTrueTypeFont(gen, (SingleByteFont) tf, in);
+ fontResource = PSFontResource.createFontResource(fontRes);
+ } else {
+ composeType0Font(gen, (MultiByteFont) tf, in);
+ }
+ gen.writeDSCComment(DSCConstants.END_RESOURCE);
+ gen.getResourceTracker().registerSuppliedResource(fontRes);
+ }
+ return fontResource;
+ }
+
+ private static void checkPostScriptLevel3(PSGenerator gen, PSEventProducer eventProducer) {
+ if (gen.getPSLevel() < 3) {
+ if (eventProducer != null) {
+ eventProducer.postscriptLevel3Needed(gen);
+ } else {
+ throw new IllegalStateException("PostScript Level 3 is"
+ + " required to use TrueType fonts,"
+ + " configured level is "
+ + gen.getPSLevel());
+ }
+ }
+ }
+
+ private static void embedTrueTypeFont(PSGenerator gen,
+ SingleByteFont font, InputStream fontStream) throws IOException {
+ /* See Adobe Technical Note #5012, "The Type 42 Font Format Specification" */
+ gen.commentln("%!PS-TrueTypeFont-65536-65536-1"); // TODO TrueType & font versions
+ gen.writeln("11 dict begin");
+ if (font.getEmbeddingMode() == EmbeddingMode.AUTO) {
+ font.setEmbeddingMode(EmbeddingMode.SUBSET);
+ }
+ FontFileReader reader = new FontFileReader(fontStream);
+ TTFFile ttfFile = new TTFFile();
+ ttfFile.readFont(reader, font.getFullName());
+ createType42DictionaryEntries(gen, font, font.getCMap(), ttfFile);
+ gen.writeln("FontName currentdict end definefont pop");
+ }
+
+ private static void createType42DictionaryEntries(PSGenerator gen, CustomFont font,
+ CMapSegment[] cmap, TTFFile ttfFile) throws IOException {
+ gen.write("/FontName /");
+ gen.write(font.getEmbedFontName());
+ gen.writeln(" def");
+ gen.writeln("/PaintType 0 def");
+ gen.writeln("/FontMatrix [1 0 0 1 0 0] def");
+ writeFontBBox(gen, font);
+ gen.writeln("/FontType 42 def");
+ gen.writeln("/Encoding 256 array");
+ gen.writeln("0 1 255{1 index exch/.notdef put}for");
+ boolean buildCharStrings;
+ Set<String> glyphNames = new HashSet<String>();
+ if (font.getFontType() == FontType.TYPE0 && font.getEmbeddingMode() != EmbeddingMode.FULL) {
+ //"/Encoding" is required but ignored for CID fonts
+ //so we keep it minimal to save space
+ buildCharStrings = false;
+ } else {
+ buildCharStrings = true;
+ for (int i = 0; i < Glyphs.WINANSI_ENCODING.length; i++) {
+ gen.write("dup ");
+ gen.write(i);
+ gen.write(" /");
+ String glyphName = Glyphs.charToGlyphName(Glyphs.WINANSI_ENCODING[i]);
+ if (glyphName.equals("")) {
+ gen.write(Glyphs.NOTDEF);
+ } else {
+ gen.write(glyphName);
+ glyphNames.add(glyphName);
+ }
+ gen.writeln(" put");
+ }
+ }
+ gen.writeln("readonly def");
+ TTFOutputStream ttfOut = new PSTTFOutputStream(gen);
+ ttfFile.stream(ttfOut);
+
+ buildCharStrings(gen, buildCharStrings, cmap, glyphNames, font);
+ }
+
+ private static void buildCharStrings(PSGenerator gen, boolean buildCharStrings,
+ CMapSegment[] cmap, Set<String> glyphNames, CustomFont font) throws IOException {
+ gen.write("/CharStrings ");
+ if (!buildCharStrings) {
+ gen.write(1);
+ } else if (font.getEmbeddingMode() != EmbeddingMode.FULL) {
+ int charCount = 1; //1 for .notdef
+ for (CMapSegment segment : cmap) {
+ charCount += segment.getUnicodeEnd() - segment.getUnicodeStart() + 1;
+ }
+ gen.write(charCount);
+ } else {
+ gen.write(font.getCMap().length);
+ }
+ gen.writeln(" dict dup begin");
+ gen.write("/");
+ gen.write(Glyphs.NOTDEF);
+ gen.writeln(" 0 def"); // .notdef always has to be at index 0
+ if (!buildCharStrings) {
+ // If we're not building the full CharStrings we can end here
+ gen.writeln("end readonly def");
+ return;
+ }
+ if (font.getEmbeddingMode() != EmbeddingMode.FULL) {
+ //Only performed in singly-byte mode, ignored for CID fonts
+ for (CMapSegment segment : cmap) {
+ int glyphIndex = segment.getGlyphStartIndex();
+ for (int ch = segment.getUnicodeStart(); ch <= segment.getUnicodeEnd(); ch++) {
+ char ch16 = (char)ch; //TODO Handle Unicode characters beyond 16bit
+ String glyphName = Glyphs.charToGlyphName(ch16);
+ if ("".equals(glyphName)) {
+ glyphName = "u" + Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
}
+ writeGlyphDefs(gen, glyphName, glyphIndex);
+
+ glyphIndex++;
}
}
+ } else {
+ for (String name : glyphNames) {
+ writeGlyphDefs(gen, name,
+ getGlyphIndex(Glyphs.getUnicodeSequenceForGlyphName(name).charAt(0),
+ font.getCMap()));
+ }
}
- if (!embeddedFont) {
- gen.writeDSCComment(DSCConstants.INCLUDE_RESOURCE, fontRes);
+ gen.writeln("end readonly def");
+ }
+
+ private static void writeGlyphDefs(PSGenerator gen, String glyphName, int glyphIndex)
+ throws IOException {
+ gen.write("/");
+ gen.write(glyphName);
+ gen.write(" ");
+ gen.write(glyphIndex);
+ gen.writeln(" def");
+ }
+
+ private static int getGlyphIndex(char c, CMapSegment[] cmap) {
+ for (CMapSegment segment : cmap) {
+ if (segment.getUnicodeStart() <= c && c <= segment.getUnicodeEnd()) {
+ return segment.getGlyphStartIndex() + c - segment.getUnicodeStart();
+ }
}
+ return 0;
+ }
+
+ private static void composeType0Font(PSGenerator gen, MultiByteFont font,
+ InputStream fontStream) throws IOException {
+ String psName = font.getEmbedFontName();
+ gen.write("/");
+ gen.write(psName);
+ gen.write(" /Identity-H [/");
+ gen.write(psName);
+ gen.writeln("] composefont pop");
+ }
+
+ private static PSResource embedType2CIDFont(PSGenerator gen,
+ MultiByteFont font, InputStream fontStream) throws IOException {
+ assert font.getCIDType() == CIDFontType.CIDTYPE2;
+
+ String psName = font.getEmbedFontName();
+ gen.write("%%BeginResource: CIDFont ");
+ gen.writeln(psName);
+
+ gen.write("%%Title: (");
+ gen.write(psName);
+ gen.writeln(" Adobe Identity 0)");
+
+ gen.writeln("%%Version: 1"); // TODO use font revision?
+ gen.writeln("/CIDInit /ProcSet findresource begin");
+ gen.writeln("20 dict begin");
+
+ gen.write("/CIDFontName /");
+ gen.write(psName);
+ gen.writeln(" def");
+
+ gen.writeln("/CIDFontVersion 1 def"); // TODO same as %%Version above
+
+ gen.write("/CIDFontType ");
+ gen.write(font.getCIDType().getValue());
+ gen.writeln(" def");
+
+ gen.writeln("/CIDSystemInfo 3 dict dup begin");
+ gen.writeln(" /Registry (Adobe) def");
+ gen.writeln(" /Ordering (Identity) def");
+ gen.writeln(" /Supplement 0 def");
+ gen.writeln("end def");
+
+ // TODO UIDBase (and UIDOffset in CMap) necessary if PostScript Level 1 & 2
+ // interpreters are to be supported
+ // (Level 1: with composite font extensions; Level 2: those that do not offer
+ // native mode support for CID-keyed fonts)
+
+ // TODO XUID (optional but strongly recommended)
+
+ // TODO /FontInfo
+
+ gen.write("/CIDCount ");
+ CIDSubset cidSubset = font.getCIDSubset();
+ int subsetSize = cidSubset.getSubsetSize();
+ gen.write(subsetSize);
+ gen.writeln(" def");
+ gen.writeln("/GDBytes 2 def"); // TODO always 2?
+ gen.writeln("/CIDMap [<");
+ int colCount = 0;
+ int lineCount = 1;
+ for (int cid = 0; cid < subsetSize; cid++) {
+ if (colCount++ == 20) {
+ gen.newLine();
+ colCount = 1;
+ if (lineCount++ == 800) {
+ gen.writeln("> <");
+ lineCount = 1;
+ }
+ }
+ String gid;
+ if (font.getEmbeddingMode() != EmbeddingMode.FULL) {
+ gid = HexEncoder.encode(cid, 4);
+ } else {
+ gid = HexEncoder.encode(cidSubset.getGlyphIndexForSubsetIndex(cid), 4);
+ }
+ gen.write(gid);
+ }
+ gen.writeln(">] def");
+ FontFileReader reader = new FontFileReader(fontStream);
+
+ TTFFile ttfFile;
+ if (font.getEmbeddingMode() != EmbeddingMode.FULL) {
+ ttfFile = new TTFSubSetFile();
+ ttfFile.readFont(reader, font.getTTCName(), font.getUsedGlyphs());
+ } else {
+ ttfFile = new TTFFile();
+ ttfFile.readFont(reader, font.getTTCName());
+ }
+
+
+ createType42DictionaryEntries(gen, font, new CMapSegment[0], ttfFile);
+ gen.writeln("CIDFontName currentdict end /CIDFont defineresource pop");
+ gen.writeln("end");
+ gen.writeln("%%EndResource");
+ PSResource cidFontResource = new PSResource(PSResource.TYPE_CIDFONT, psName);
+ gen.getResourceTracker().registerSuppliedResource(cidFontResource);
+ return cidFontResource;
+ }
+
+ private static void writeFontBBox(PSGenerator gen, CustomFont font) throws IOException {
+ int[] bbox = font.getFontBBox();
+ gen.write("/FontBBox[");
+ for (int i = 0; i < 4; i++) {
+ gen.write(" ");
+ gen.write(bbox[i]);
+ }
+ gen.writeln(" ] def");
}
private static boolean isEmbeddable(CustomFont font) {
@@ -273,12 +573,20 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
Map fontResources = new java.util.HashMap();
for (String key : fonts.keySet()) {
Typeface tf = getTypeFace(fontInfo, fonts, key);
- PSResource fontRes = new PSResource("font", tf.getFontName());
+ PSResource fontRes = new PSResource("font", tf.getEmbedFontName());
fontResources.put(key, fontRes);
- if (FontType.TYPE1 == tf.getFontType()) {
+ FontType fontType = tf.getFontType();
+ if (fontType == FontType.TYPE1 || fontType == FontType.TRUETYPE
+ || fontType == FontType.TYPE0) {
if (tf instanceof CustomFont) {
CustomFont cf = (CustomFont)tf;
if (isEmbeddable(cf)) {
+ if (fontType == FontType.TYPE0) {
+ resTracker.registerSuppliedResource(
+ new PSResource(PSResource.TYPE_CIDFONT, tf.getEmbedFontName()));
+ resTracker.registerSuppliedResource(
+ new PSResource(PSResource.TYPE_CMAP, "Identity-H"));
+ }
resTracker.registerSuppliedResource(fontRes);
}
if (tf instanceof SingleByteFont) {
@@ -289,7 +597,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
PSResource.TYPE_ENCODING, encoding.getName());
resTracker.registerSuppliedResource(encodingRes);
PSResource derivedFontRes = new PSResource(
- PSResource.TYPE_FONT, tf.getFontName() + "_" + (i + 1));
+ PSResource.TYPE_FONT, tf.getEmbedFontName() + "_" + (i + 1));
resTracker.registerSuppliedResource(derivedFontRes);
}
}
@@ -366,4 +674,42 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils {
return res;
}
+ private static PSResource defineDerivedTrueTypeFont(PSGenerator gen,
+ PSEventProducer eventProducer, String baseFontName, String fontName,
+ SingleByteEncoding encoding, CMapSegment[] cmap) throws IOException {
+ checkPostScriptLevel3(gen, eventProducer);
+ PSResource res = new PSResource(PSResource.TYPE_FONT, fontName);
+ gen.writeDSCComment(DSCConstants.BEGIN_RESOURCE, res);
+ gen.commentln("%XGCDependencies: font " + baseFontName);
+ gen.commentln("%XGC+ encoding " + encoding.getName());
+ gen.writeln("/" + baseFontName + " findfont");
+ gen.writeln("dup length dict begin");
+ gen.writeln(" {1 index /FID ne {def} {pop pop} ifelse} forall");
+ gen.writeln(" /Encoding " + encoding.getName() + " def");
+
+ gen.writeln(" /CharStrings 256 dict dup begin");
+ String[] charNameMap = encoding.getCharNameMap();
+ char[] unicodeCharMap = encoding.getUnicodeCharMap();
+ assert charNameMap.length == unicodeCharMap.length;
+ for (int i = 0; i < charNameMap.length; i++) {
+ String glyphName = charNameMap[i];
+ gen.write(" /");
+ gen.write(glyphName);
+ gen.write(" ");
+ if (glyphName.equals(".notdef")) {
+ gen.write(0);
+ } else {
+ gen.write(getGlyphIndex(unicodeCharMap[i], cmap));
+ }
+ gen.writeln(" def");
+ }
+ gen.writeln(" end readonly def");
+
+ gen.writeln(" currentdict");
+ gen.writeln("end");
+ gen.writeln("/" + fontName + " exch definefont pop");
+ gen.writeDSCComment(DSCConstants.END_RESOURCE);
+ gen.getResourceTracker().registerSuppliedResource(res);
+ return res;
+ }
}
diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java b/src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java
new file mode 100644
index 000000000..2a283e913
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSImageHandlerRawPNG.java
@@ -0,0 +1,111 @@
+/*
+ * 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.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+import org.apache.xmlgraphics.ps.FormGenerator;
+import org.apache.xmlgraphics.ps.ImageEncoder;
+import org.apache.xmlgraphics.ps.ImageFormGenerator;
+import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.ps.PSImageUtils;
+
+import org.apache.fop.render.RenderingContext;
+
+/**
+ * Image handler implementation which handles raw (not decoded) PNG images for PostScript output.
+ */
+public class PSImageHandlerRawPNG implements PSImageHandler {
+
+ private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {ImageFlavor.RAW_PNG};
+
+ /** {@inheritDoc} */
+ public void handleImage(RenderingContext context, Image image, Rectangle pos) throws IOException {
+ PSRenderingContext psContext = (PSRenderingContext) context;
+ PSGenerator gen = psContext.getGenerator();
+ ImageRawPNG png = (ImageRawPNG) image;
+
+ float x = (float) pos.getX() / 1000f;
+ float y = (float) pos.getY() / 1000f;
+ float w = (float) pos.getWidth() / 1000f;
+ float h = (float) pos.getHeight() / 1000f;
+ Rectangle2D targetRect = new Rectangle2D.Float(x, y, w, h);
+
+ ImageEncoder encoder = new ImageEncoderPNG(png);
+ ImageInfo info = image.getInfo();
+ Dimension imgDim = info.getSize().getDimensionPx();
+ String imgDescription = image.getClass().getName();
+ ColorModel cm = png.getColorModel();
+
+ PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen);
+ }
+
+ /** {@inheritDoc} */
+ public void generateForm(RenderingContext context, Image image, PSImageFormResource form)
+ throws IOException {
+ PSRenderingContext psContext = (PSRenderingContext) context;
+ PSGenerator gen = psContext.getGenerator();
+ ImageRawPNG png = (ImageRawPNG) image;
+ ImageInfo info = image.getInfo();
+ String imageDescription = info.getMimeType() + " " + info.getOriginalURI();
+
+ ImageEncoder encoder = new ImageEncoderPNG(png);
+ FormGenerator formGen = new ImageFormGenerator(form.getName(), imageDescription, info.getSize()
+ .getDimensionPt(), info.getSize().getDimensionPx(), encoder, png.getColorSpace(),
+ false);
+ formGen.generate(gen);
+ }
+
+ /** {@inheritDoc} */
+ public int getPriority() {
+ return 200;
+ }
+
+ /** {@inheritDoc} */
+ public Class<ImageRawPNG> getSupportedImageClass() {
+ return ImageRawPNG.class;
+ }
+
+ /** {@inheritDoc} */
+ public ImageFlavor[] getSupportedImageFlavors() {
+ return FLAVORS;
+ }
+
+ /** {@inheritDoc} */
+ public boolean isCompatible(RenderingContext targetContext, Image image) {
+ if (targetContext instanceof PSRenderingContext) {
+ PSRenderingContext psContext = (PSRenderingContext) targetContext;
+ // The filters required for this implementation need PS level 2 or higher
+ if (psContext.getGenerator().getPSLevel() >= 2) {
+ return (image == null || image instanceof ImageRawPNG);
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java
index 5a13c1c8e..46597e46d 100644
--- a/src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java
+++ b/src/java/org/apache/fop/render/ps/PSImageHandlerRenderedImage.java
@@ -19,7 +19,10 @@
package org.apache.fop.render.ps;
+import java.awt.Dimension;
import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.io.IOException;
@@ -28,6 +31,8 @@ import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
import org.apache.xmlgraphics.ps.FormGenerator;
+import org.apache.xmlgraphics.ps.ImageEncoder;
+import org.apache.xmlgraphics.ps.ImageEncodingHelper;
import org.apache.xmlgraphics.ps.ImageFormGenerator;
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.xmlgraphics.ps.PSImageUtils;
@@ -47,17 +52,24 @@ public class PSImageHandlerRenderedImage implements PSImageHandler {
/** {@inheritDoc} */
public void handleImage(RenderingContext context, Image image, Rectangle pos)
throws IOException {
- PSRenderingContext psContext = (PSRenderingContext)context;
+ PSRenderingContext psContext = (PSRenderingContext) context;
PSGenerator gen = psContext.getGenerator();
- ImageRendered imageRend = (ImageRendered)image;
+ ImageRendered imageRend = (ImageRendered) image;
- float x = (float)pos.getX() / 1000f;
- float y = (float)pos.getY() / 1000f;
- float w = (float)pos.getWidth() / 1000f;
- float h = (float)pos.getHeight() / 1000f;
+ float x = (float) pos.getX() / 1000f;
+ float y = (float) pos.getY() / 1000f;
+ float w = (float) pos.getWidth() / 1000f;
+ float h = (float) pos.getHeight() / 1000f;
+ Rectangle2D targetRect = new Rectangle2D.Double(x, y, w, h);
RenderedImage ri = imageRend.getRenderedImage();
- PSImageUtils.renderBitmapImage(ri, x, y, w, h, gen);
+ ImageEncoder encoder = ImageEncodingHelper.createRenderedImageEncoder(ri);
+ Dimension imgDim = new Dimension(ri.getWidth(), ri.getHeight());
+ String imgDescription = ri.getClass().getName();
+ ImageEncodingHelper helper = new ImageEncodingHelper(ri);
+ ColorModel cm = helper.getEncodedColorModel();
+
+ PSImageUtils.writeImage(encoder, imgDim, imgDescription, targetRect, cm, gen);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/ps/PSPainter.java b/src/java/org/apache/fop/render/ps/PSPainter.java
index 9bed2a432..c2288019a 100644
--- a/src/java/org/apache/fop/render/ps/PSPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSPainter.java
@@ -44,6 +44,7 @@ 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;
import org.apache.fop.fonts.SingleByteFont;
import org.apache.fop.fonts.Typeface;
import org.apache.fop.render.RenderingContext;
@@ -55,6 +56,7 @@ import org.apache.fop.render.intermediate.IFUtil;
import org.apache.fop.traits.BorderProps;
import org.apache.fop.traits.RuleStyle;
import org.apache.fop.util.CharUtilities;
+import org.apache.fop.util.HexEncoder;
/**
* IFPainter implementation that produces PostScript.
@@ -392,7 +394,7 @@ public class PSPainter extends AbstractIFPainter {
if (currentEncoding != encoding) {
if (i > 0) {
writeText(text, start, i - start,
- letterSpacing, wordSpacing, dp, font, tf);
+ letterSpacing, wordSpacing, dp, font, tf, false);
}
if (encoding == 0) {
useFont(fontKey, sizeMillipoints);
@@ -404,19 +406,18 @@ public class PSPainter extends AbstractIFPainter {
}
}
} else {
- //Simple single-font painting
useFont(fontKey, sizeMillipoints);
}
- writeText(text, start, textLen - start, letterSpacing, wordSpacing, dp, font, tf);
+ writeText(text, start, textLen - start, letterSpacing, wordSpacing, dp, font, tf,
+ tf instanceof MultiByteFont);
} catch (IOException ioe) {
throw new IFException("I/O error in drawText()", ioe);
}
}
- private void writeText( // CSOK: ParameterNumber
- String text, int start, int len,
+ private void writeText(String text, int start, int len,
int letterSpacing, int wordSpacing, int[][] dp,
- Font font, Typeface tf) throws IOException {
+ Font font, Typeface tf, boolean multiByte) throws IOException {
PSGenerator generator = getGenerator();
int end = start + len;
int initialSize = len;
@@ -451,8 +452,12 @@ public class PSPainter extends AbstractIFPainter {
if (dx != null && i < dxl - 1) {
glyphAdjust -= dx[i + 1];
}
- char codepoint = (char)(ch % 256);
- PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
+ if (multiByte) {
+ accText.append(HexEncoder.encode(ch));
+ } else {
+ char codepoint = (char)(ch % 256);
+ PSGenerator.escapeChar(codepoint, accText); //add character to accumulated text
+ }
if (glyphAdjust != 0) {
needTJ = true;
if (sb.length() == 0) {
@@ -463,9 +468,8 @@ public class PSPainter extends AbstractIFPainter {
sb.append(PSGenerator.LF);
lineStart = sb.length();
}
- sb.append('(');
- sb.append(accText);
- sb.append(") ");
+ lineStart = writePostScriptString(sb, accText, multiByte, lineStart);
+ sb.append(' ');
accText.setLength(0); //reset accumulated text
}
sb.append(Integer.toString(glyphAdjust)).append(' ');
@@ -473,9 +477,10 @@ public class PSPainter extends AbstractIFPainter {
}
if (needTJ) {
if (accText.length() > 0) {
- sb.append('(');
- sb.append(accText);
- sb.append(')');
+ if ((sb.length() - lineStart + accText.length()) > 200) {
+ sb.append(PSGenerator.LF);
+ }
+ writePostScriptString(sb, accText, multiByte);
}
if (hasLetterSpacing) {
sb.append("] " + formatMptAsPt(generator, letterSpacing) + " ATJ");
@@ -483,7 +488,7 @@ public class PSPainter extends AbstractIFPainter {
sb.append("] TJ");
}
} else {
- sb.append('(').append(accText).append(")");
+ writePostScriptString(sb, accText, multiByte);
if (hasLetterSpacing) {
StringBuffer spb = new StringBuffer();
spb.append(formatMptAsPt(generator, letterSpacing))
@@ -497,12 +502,37 @@ public class PSPainter extends AbstractIFPainter {
generator.writeln(sb.toString());
}
+ private void writePostScriptString(StringBuffer buffer, StringBuffer string,
+ boolean multiByte) {
+ writePostScriptString(buffer, string, multiByte, 0);
+ }
+
+ private int writePostScriptString(StringBuffer buffer, StringBuffer string, boolean multiByte,
+ int lineStart) {
+ buffer.append(multiByte ? '<' : '(');
+ int l = string.length();
+ int index = 0;
+ int maxCol = 200;
+ buffer.append(string.substring(index, Math.min(index + maxCol, l)));
+ index += maxCol;
+ while (index < l) {
+ if (!multiByte) {
+ buffer.append('\\');
+ }
+ buffer.append(PSGenerator.LF);
+ lineStart = buffer.length();
+ buffer.append(string.substring(index, Math.min(index + maxCol, l)));
+ index += maxCol;
+ }
+ buffer.append(multiByte ? '>' : ')');
+ return lineStart;
+ }
+
private void useFont(String key, int size) throws IOException {
- PSResource res = this.documentHandler.getPSResourceForFontKey(key);
+ PSFontResource res = this.documentHandler.getPSResourceForFontKey(key);
PSGenerator generator = getGenerator();
generator.useFont("/" + res.getName(), size / 1000f);
- generator.getResourceTracker().notifyResourceUsageOnPage(res);
+ res.notifyResourceUsageOnPage(generator.getResourceTracker());
}
-
}
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index acc673491..2b3afaec7 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -41,12 +41,15 @@ import org.apache.batik.gvt.text.TextSpanLayout;
import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
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.FontMetrics;
+import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.fonts.MultiByteFont;
import org.apache.fop.svg.NativeTextPainter;
import org.apache.fop.util.CharUtilities;
+import org.apache.fop.util.HexEncoder;
/**
* Renders the attributed character iterator of a text node.
@@ -240,9 +243,9 @@ public class PSTextPainter extends NativeTextPainter {
}
}
- private PSResource getResourceForFont(Font f, String postfix) {
+ private PSFontResource getResourceForFont(Font f, String postfix) {
String key = (postfix != null ? f.getFontName() + '_' + postfix : f.getFontName());
- return this.fontResources.getPSResourceForFontKey(key);
+ return this.fontResources.getFontResourceForFontKey(key);
}
private void clip(PSGraphics2D ps, Shape shape) throws IOException {
@@ -299,9 +302,9 @@ public class PSTextPainter extends NativeTextPainter {
public void selectFont(Font f, char mapped) throws IOException {
int encoding = mapped / 256;
String postfix = (encoding == 0 ? null : Integer.toString(encoding));
- PSResource res = getResourceForFont(f, postfix);
+ PSFontResource res = getResourceForFont(f, postfix);
gen.useFont("/" + res.getName(), f.getFontSize() / 1000f);
- gen.getResourceTracker().notifyResourceUsageOnPage(res);
+ res.notifyResourceUsageOnPage(gen.getResourceTracker());
}
public Font getCurrentFont() {
@@ -427,15 +430,23 @@ public class PSTextPainter extends NativeTextPainter {
textUtil.setCurrentFont(f, mapped);
applyColor(paint, gen);
+ FontMetrics metrics = f.getFontMetrics();
+ boolean multiByte = metrics instanceof MultiByteFont
+ || metrics instanceof LazyFont
+ && ((LazyFont) metrics).getRealFont() instanceof MultiByteFont;
StringBuffer sb = new StringBuffer();
- sb.append('(');
+ sb.append(multiByte ? '<' : '(');
for (int i = 0, c = this.currentChars.length(); i < c; i++) {
char ch = this.currentChars.charAt(i);
mapped = f.mapChar(ch);
- char codepoint = (char) (mapped % 256);
- PSGenerator.escapeChar(codepoint, sb);
+ if (multiByte) {
+ sb.append(HexEncoder.encode(mapped));
+ } else {
+ char codepoint = (char) (mapped % 256);
+ PSGenerator.escapeChar(codepoint, sb);
+ }
}
- sb.append(')');
+ sb.append(multiByte ? '>' : ')');
if (x || y) {
sb.append("\n[");
int idx = 0;
@@ -513,10 +524,20 @@ public class PSTextPainter extends NativeTextPainter {
textUtil.selectFont(f, mapped);
textUtil.setCurrentFont(f, mapped);
}
- mapped = f.mapChar(this.currentChars.charAt(i));
//add glyph outlines to current path
- char codepoint = (char)(mapped % 256);
- gen.write("(" + codepoint + ")");
+ mapped = f.mapChar(this.currentChars.charAt(i));
+ FontMetrics metrics = f.getFontMetrics();
+ boolean multiByte = metrics instanceof MultiByteFont
+ || metrics instanceof LazyFont
+ && ((LazyFont) metrics).getRealFont() instanceof MultiByteFont;
+ if (multiByte) {
+ gen.write('<');
+ gen.write(HexEncoder.encode(mapped));
+ gen.write('>');
+ } else {
+ char codepoint = (char)(mapped % 256);
+ gen.write("(" + codepoint + ")");
+ }
gen.writeln(" false charpath");
if (iter.hasNext()) {
diff --git a/src/java/org/apache/fop/render/ps/ResourceHandler.java b/src/java/org/apache/fop/render/ps/ResourceHandler.java
index 502242c17..5594897ba 100644
--- a/src/java/org/apache/fop/render/ps/ResourceHandler.java
+++ b/src/java/org/apache/fop/render/ps/ResourceHandler.java
@@ -83,6 +83,8 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
private FOUserAgent userAgent;
private FontInfo fontInfo;
+ private PSEventProducer eventProducer;
+
private ResourceTracker resTracker;
//key: URI, values PSImageFormResource
@@ -93,13 +95,15 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
/**
* Main constructor.
* @param userAgent the FO user agent
+ * @param eventProducer the event producer
* @param fontInfo the font information
* @param resTracker the resource tracker to use
* @param formResources Contains all forms used by this document (maintained by PSRenderer)
*/
- public ResourceHandler(FOUserAgent userAgent, FontInfo fontInfo,
- ResourceTracker resTracker, Map formResources) {
+ public ResourceHandler(FOUserAgent userAgent, PSEventProducer eventProducer,
+ FontInfo fontInfo, ResourceTracker resTracker, Map formResources) {
this.userAgent = userAgent;
+ this.eventProducer = eventProducer;
this.fontInfo = fontInfo;
this.resTracker = resTracker;
determineInlineForms(formResources);
@@ -222,7 +226,7 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors {
if (fontSetupPlaceholder == null) {
throw new DSCException("Didn't find %FOPFontSetup comment in stream");
}
- PSFontUtils.writeFontDict(gen, fontInfo, fontInfo.getUsedFonts());
+ PSFontUtils.writeFontDict(gen, fontInfo, fontInfo.getUsedFonts(), eventProducer);
generateForms(globalFormResources, gen);
//Skip the prolog and to the first page
diff --git a/src/java/org/apache/fop/render/ps/fonts/PSTTFGenerator.java b/src/java/org/apache/fop/render/ps/fonts/PSTTFGenerator.java
new file mode 100644
index 000000000..556b62457
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/fonts/PSTTFGenerator.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.ps.fonts;
+
+import java.io.IOException;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream;
+
+/**
+ * This is a wrapper for {@link PSGenerator} that contains some members specific for streaming
+ * TrueType fonts to a PostScript document.
+ */
+public class PSTTFGenerator {
+ private PSGenerator gen;
+ private ASCIIHexOutputStream hexOut;
+
+ /**
+ * The buffer is used to store the font file in an array of hex-encoded strings. Strings are
+ * limited to 65535 characters, string will start with a newline, 2 characters are needed to
+ * hex-encode each byte.
+ */
+ public static final int MAX_BUFFER_SIZE = 32764;
+
+ /**
+ * Creates a new instance wrapping the given generator.
+ * @param gen the PSGenerator to wrap
+ */
+ public PSTTFGenerator(PSGenerator gen) {
+ this.gen = gen;
+ hexOut = new ASCIIHexOutputStream(gen.getOutputStream());
+ }
+
+ /**
+ * Writes the '&lt;' character that starts a string.
+ */
+ public void startString() throws IOException {
+ // We need to reset the streamer so that it starts a new line in the PS document
+ hexOut = new ASCIIHexOutputStream(gen.getOutputStream());
+ gen.writeln("<");
+ }
+
+ /**
+ * Writes the given string to the output.
+ * @param cmd a string
+ */
+ public void write(String cmd) throws IOException {
+ gen.write(cmd);
+ }
+
+ /**
+ * Writes the given string to the output, followed by a newline.
+ * @param cmd a string
+ */
+ public void writeln(String cmd) throws IOException {
+ gen.writeln(cmd);
+ }
+
+ /**
+ * Writes bytes from the given byte array to the output.
+ *
+ * @param byteArray byte[] a byte array
+ * @param offset the position in the byte array where the streaming must start
+ * @param length the number of bytes to stream. This MUST be less than
+ * {@link #MAX_BUFFER_SIZE} - 1 since strings are suffixed by '00' (see Section 4.2 of
+ * Adobe Technical Note #5012, <em>The Type 42 Font Format Specification</em>.).
+ */
+ public void streamBytes(byte[] byteArray, int offset, int length) throws IOException {
+ if (length > MAX_BUFFER_SIZE) {
+ throw new UnsupportedOperationException("Attempting to write a string to a PostScript"
+ + " file that is greater than the buffer size.");
+ }
+ hexOut.write(byteArray, offset, length);
+ }
+
+ /**
+ * Finishes writing a string by appending '00' and '>' to the end.
+ */
+ public void endString() throws IOException {
+ /* Appends a '00' to the end of the string as specified in the spec */
+ gen.write("00\n> ");
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStream.java b/src/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStream.java
new file mode 100644
index 000000000..cc2ae3e82
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStream.java
@@ -0,0 +1,75 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.apache.fop.fonts.truetype.TTFGlyphOutputStream;
+
+/**
+ * Streams glyphs in accordance with the constraints of the PostScript file format.
+ * Mainly, PostScript strings have a limited capacity and the font data may have to be
+ * broken down into several strings; however, this must occur at well-defined places like
+ * table or glyph boundaries. See also Adobe Technical Note #5012, <em>The Type 42 Font
+ * Format Specification</em>.
+ */
+public class PSTTFGlyphOutputStream implements TTFGlyphOutputStream {
+
+ /** Total number of bytes written so far. */
+ private int byteCounter;
+
+ private int lastStringBoundary;
+
+ private PSTTFGenerator ttfGen;
+
+ /**
+ * Constructor
+ * @param ttfGen PSTTFGenerator
+ */
+ public PSTTFGlyphOutputStream(PSTTFGenerator ttfGen) {
+ this.ttfGen = ttfGen;
+ }
+
+ public void startGlyphStream() throws IOException {
+ ttfGen.startString();
+ }
+
+ public void streamGlyph(byte[] glyphData, int offset, int size) throws IOException {
+ if (size > PSTTFGenerator.MAX_BUFFER_SIZE) {
+ throw new UnsupportedOperationException("The glyph is " + size
+ + " bytes. There may be an error in the font file.");
+ }
+
+ if (size + (byteCounter - lastStringBoundary) < PSTTFGenerator.MAX_BUFFER_SIZE) {
+ ttfGen.streamBytes(glyphData, offset, size);
+ } else {
+ ttfGen.endString();
+ lastStringBoundary = byteCounter;
+ ttfGen.startString();
+ ttfGen.streamBytes(glyphData, offset, size);
+ }
+ byteCounter += size;
+ }
+
+ public void endGlyphStream() throws IOException {
+ ttfGen.endString();
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/fonts/PSTTFOutputStream.java b/src/java/org/apache/fop/render/ps/fonts/PSTTFOutputStream.java
new file mode 100644
index 000000000..271d87d1b
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/fonts/PSTTFOutputStream.java
@@ -0,0 +1,62 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.fonts.truetype.TTFGlyphOutputStream;
+import org.apache.fop.fonts.truetype.TTFOutputStream;
+import org.apache.fop.fonts.truetype.TTFTableOutputStream;
+
+/**
+ * Streams a TrueType font according to the PostScript format.
+ */
+public class PSTTFOutputStream implements TTFOutputStream {
+
+ private final PSTTFGenerator ttfGen;
+
+ /**
+ * Creates a new instance wrapping the given generator.
+ *
+ * @param gen the generator to wrap
+ */
+ public PSTTFOutputStream(PSGenerator gen) {
+ this.ttfGen = new PSTTFGenerator(gen);
+ }
+
+ public void startFontStream() throws IOException {
+ ttfGen.write("/sfnts[");
+ }
+
+ public TTFTableOutputStream getTableOutputStream() {
+ return new PSTTFTableOutputStream(ttfGen);
+ }
+
+ public TTFGlyphOutputStream getGlyphOutputStream() {
+ return new PSTTFGlyphOutputStream(ttfGen);
+ }
+
+ public void endFontStream() throws IOException {
+ ttfGen.writeln("] def");
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStream.java b/src/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStream.java
new file mode 100644
index 000000000..2226e11e8
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStream.java
@@ -0,0 +1,59 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.apache.fop.fonts.truetype.TTFTableOutputStream;
+
+/**
+ * Streams a TrueType table according to the PostScript format.
+ */
+public class PSTTFTableOutputStream implements TTFTableOutputStream {
+
+ private PSTTFGenerator ttfGen;
+
+ /**
+ * Constructor.
+ * @param ttfGen the helper object to stream TrueType data
+ */
+ public PSTTFTableOutputStream(PSTTFGenerator ttfGen) {
+ this.ttfGen = ttfGen;
+ }
+
+ public void streamTable(byte[] ttfData, int offset, int size) throws IOException {
+ int offsetPosition = offset;
+ // Need to split the table into MAX_BUFFER_SIZE chunks
+ for (int i = 0; i < size / PSTTFGenerator.MAX_BUFFER_SIZE; i++) {
+ streamString(ttfData, offsetPosition, PSTTFGenerator.MAX_BUFFER_SIZE);
+ offsetPosition += PSTTFGenerator.MAX_BUFFER_SIZE;
+ }
+ if (size % PSTTFGenerator.MAX_BUFFER_SIZE > 0) {
+ streamString(ttfData, offsetPosition, size % PSTTFGenerator.MAX_BUFFER_SIZE);
+ }
+ }
+
+ private void streamString(byte[] byteArray, int offset, int length) throws IOException {
+ ttfGen.startString();
+ ttfGen.streamBytes(byteArray, offset, length);
+ ttfGen.endString();
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/PDFAElementBridge.java b/src/java/org/apache/fop/svg/PDFAElementBridge.java
index cd70bed34..c2a481af9 100644
--- a/src/java/org/apache/fop/svg/PDFAElementBridge.java
+++ b/src/java/org/apache/fop/svg/PDFAElementBridge.java
@@ -64,7 +64,7 @@ public class PDFAElementBridge extends AbstractGraphicsNodeBridge {
}
/**
- * Creates a {@link CompositeGraphicsNode}.
+ * Creates a {@link org.apache.batik.gvt.CompositeGraphicsNode}.
* @return a new PDFANode
*/
protected GraphicsNode instantiateGraphicsNode() {
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index 67fc5d860..87c12d869 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -1201,6 +1201,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
currentStream.write("] ");
float offset = bs.getDashPhase();
currentStream.write(PDFNumber.doubleOut(offset) + " d\n");
+ } else {
+ currentStream.write("[] 0 d\n");
}
int ec = bs.getEndCap();
switch (ec) {
diff --git a/src/java/org/apache/fop/traits/MinOptMax.java b/src/java/org/apache/fop/traits/MinOptMax.java
index 022f3c214..84fb0156a 100644
--- a/src/java/org/apache/fop/traits/MinOptMax.java
+++ b/src/java/org/apache/fop/traits/MinOptMax.java
@@ -22,8 +22,9 @@ package org.apache.fop.traits;
import java.io.Serializable;
/**
- * This class holds the resolved (as mpoints) form of a {@link LengthRangeProperty LengthRange} or
- * {@link SpaceProperty Space} type property value.
+ * This class holds the resolved (as mpoints) form of a
+ * {@link org.apache.fop.fo.properties.LengthRangeProperty} or
+ * {@link org.apache.fop.fo.properties.SpaceProperty} type property value.
* <p/>
* Instances of this class are immutable. All arithmetic methods like {@link #plus(MinOptMax) plus},
* {@link #minus(MinOptMax) minus} or {@link #mult(int) mult} return a different instance. So it is
diff --git a/src/java/org/apache/fop/traits/TraitEnum.java b/src/java/org/apache/fop/traits/TraitEnum.java
index 18fdffaab..0d664a6df 100644
--- a/src/java/org/apache/fop/traits/TraitEnum.java
+++ b/src/java/org/apache/fop/traits/TraitEnum.java
@@ -30,7 +30,7 @@ public abstract class TraitEnum implements Serializable {
/**
* Constructor to add a new named item.
* @param name Name of the item.
- * @param enumValue the {@link Constants}.EN_* value
+ * @param enumValue the {@link org.apache.fop.fo.Constants}.EN_* value
*/
protected TraitEnum(String name, int enumValue) {
this.name = name;
@@ -46,7 +46,7 @@ public abstract class TraitEnum implements Serializable {
}
/**
- * Returns the enumeration value (one of {@link Constants}.EN_*).
+ * Returns the enumeration value (one of {@link org.apache.fop.fo.Constants}.EN_*).
* @return the enumeration value
*/
public int getEnumValue() {
diff --git a/src/java/org/apache/fop/util/ColorExt.java b/src/java/org/apache/fop/util/ColorExt.java
index d0ac6767c..f92e7c2a6 100644
--- a/src/java/org/apache/fop/util/ColorExt.java
+++ b/src/java/org/apache/fop/util/ColorExt.java
@@ -28,7 +28,7 @@ import java.util.Arrays;
* <p>
* This class extends java.awt.Color class keeping track of the original color
* property values specified by the fo user in a rgb-icc call.
- * @deprecated Replaced by {@link ColorWithAlternatives}
+ * @deprecated Replaced by {@link org.apache.xmlgraphics.java2d.color.ColorWithAlternatives}
*/
@Deprecated
public final class ColorExt extends Color {
diff --git a/src/java/org/apache/fop/util/HexEncoder.java b/src/java/org/apache/fop/util/HexEncoder.java
new file mode 100644
index 000000000..9ca91f2d2
--- /dev/null
+++ b/src/java/org/apache/fop/util/HexEncoder.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+/**
+ * A helper class to create hex-encoded representations of numbers.
+ */
+public final class HexEncoder {
+
+ private HexEncoder() { }
+
+ /**
+ * Returns an hex encoding of the given number as a string of the given length,
+ * left-padded with zeros if necessary.
+ *
+ * @param n a number
+ * @param width required length of the string
+ * @return an hex-encoded representation of the number
+ */
+ public static String encode(int n, int width) {
+ char[] digits = new char[width];
+ for (int i = width - 1; i >= 0; i--) {
+ int digit = n & 0xF;
+ digits[i] = (char) (digit < 10 ? '0' + digit : 'A' + digit - 10);
+ n >>= 4;
+ }
+ return new String(digits);
+ }
+
+ /**
+ * Returns an hex encoding of the given character as a four-character string.
+ *
+ * @param c a character
+ * @return an hex-encoded representation of the character
+ */
+ public static String encode(char c) {
+ return encode(c, 4);
+ }
+
+}
diff --git a/src/sandbox/org/apache/fop/render/mif/MIFHandler.java b/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
index cfc86edc7..5ef4c0940 100644
--- a/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
+++ b/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
@@ -29,8 +29,10 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FOEventHandler;
+import org.apache.fop.fo.FOText;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
+import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.FootnoteBody;
@@ -39,6 +41,8 @@ import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
+import org.apache.fop.fo.flow.ListItemBody;
+import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
@@ -51,6 +55,7 @@ import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
import org.apache.fop.fo.pagination.SimplePageMaster;
+import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fonts.FontSetup;
import org.apache.fop.render.DefaultFontResolver;
@@ -267,27 +272,27 @@ public class MIFHandler extends FOEventHandler {
}
/** {@inheritDoc} */
- public void startListLabel() {
+ public void startListLabel(ListItemLabel listItemLabel) {
}
/** {@inheritDoc} */
- public void endListLabel() {
+ public void endListLabel(ListItemLabel listItemLabel) {
}
/** {@inheritDoc} */
- public void startListBody() {
+ public void startListBody(ListItemBody listItemBody) {
}
/** {@inheritDoc} */
- public void endListBody() {
+ public void endListBody(ListItemBody listItemBody) {
}
/** {@inheritDoc} */
- public void startStatic() {
+ public void startStatic(StaticContent staticContent) {
}
/** {@inheritDoc} */
- public void endStatic() {
+ public void endStatic(StaticContent staticContent) {
}
/** {@inheritDoc} */
@@ -303,7 +308,7 @@ public class MIFHandler extends FOEventHandler {
}
/** {@inheritDoc} */
- public void endLink() {
+ public void endLink(BasicLink basicLink) {
}
/** {@inheritDoc} */
@@ -315,7 +320,11 @@ public class MIFHandler extends FOEventHandler {
}
/** {@inheritDoc} */
- public void foreignObject(InstreamForeignObject ifo) {
+ public void startInstreamForeignObject(InstreamForeignObject ifo) {
+ }
+
+ /** {@inheritDoc} */
+ public void endInstreamForeignObject(InstreamForeignObject ifo) {
}
/** {@inheritDoc} */
@@ -335,19 +344,37 @@ public class MIFHandler extends FOEventHandler {
}
/** {@inheritDoc} */
- public void leader(Leader l) {
+ public void startLeader(Leader l) {
+ }
+
+ /** {@inheritDoc} */
+ public void endLeader(Leader l) {
+ }
+
+ public void character(Character c) {
+ appendCharacters ( new String ( new char[] {c.getCharacter()} ) );
+ }
+
+ /** {@inheritDoc} */
+ public void characters(FOText foText) {
+ appendCharacters ( foText.getCharSequence().toString() );
+ }
+
+ /** {@inheritDoc} */
+ public void startPageNumber(PageNumber pagenum) {
}
/** {@inheritDoc} */
- public void characters(char[] data, int start, int length) {
+ public void endPageNumber(PageNumber pagenum) {
+ }
+
+ private void appendCharacters ( String str ) {
if (para != null) {
- String str = new String(data, start, length);
str = str.trim();
// break into nice length chunks
if (str.length() == 0) {
return;
}
-
MIFElement line = new MIFElement("ParaLine");
MIFElement prop = new MIFElement("TextRectID");
prop.setValue("2");
@@ -355,17 +382,8 @@ public class MIFHandler extends FOEventHandler {
prop = new MIFElement("String");
prop.setValue("\"" + str + "\"");
line.addElement(prop);
-
para.addElement(line);
}
}
-
- /** {@inheritDoc} */
- public void startPageNumber(PageNumber pagenum) {
- }
-
- /** {@inheritDoc} */
- public void endPageNumber(PageNumber pagenum) {
- }
}
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
index ef0d9f301..6fd4d3618 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGDocumentHandler.java
@@ -54,7 +54,8 @@ import org.apache.fop.util.GenerationHelperContentHandler;
import org.apache.fop.util.XMLUtil;
/**
- * {@link IFDocumentHandler} implementation that writes SVG 1.1.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that writes SVG 1.1.
*/
public class SVGDocumentHandler extends AbstractSVGDocumentHandler {
diff --git a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
index 10be9588e..8ec374731 100644
--- a/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
+++ b/src/sandbox/org/apache/fop/render/svg/SVGPrintDocumentHandler.java
@@ -32,7 +32,8 @@ import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.util.XMLUtil;
/**
- * {@link IFDocumentHandler} implementation that writes SVG Print.
+ * {@link org.apache.fop.render.intermediate.IFDocumentHandler} implementation
+ * that writes SVG Print.
*/
public class SVGPrintDocumentHandler extends AbstractSVGDocumentHandler {
diff --git a/status.xml b/status.xml
index 23ad7456e..e53dbc8eb 100644
--- a/status.xml
+++ b/status.xml
@@ -61,7 +61,46 @@
users, i.e. when the behaviour changes and could affect the layout of existing
documents. Example: the fix of marks layering will be such a case when it's done.
-->
- <release version="1.1" date="DD Month 2012">
+ <release version="1.1rc1" date="02 July 2012">
+ <action context="Test" dev="GA" type="fix">
+ Fix errors and warnings in example files. Add build.xml for documentation examples.
+ </action>
+ <action context="Code" dev="GA" type="fix" fixes-bug="53458" due-to="Dieter von Holten">
+ Fix incorrect language and country code key generation in hyphenation tree cache.
+ </action>
+ <action context="Images" dev="GA" type="fix" fixes-bug="53431" due-to="Luis Bernardo">
+ Fix incorrect SVG line dash pattern with PDF output format.
+ </action>
+ <action context="Images" dev="GA" type="update" fixes-bug="40676" due-to="Luis Bernardo">
+ Fix interoperability issue with Adobe reader regarding use of multiple filters.
+ </action>
+ <action context="Code" dev="GA" type="fix">
+ Eliminate javadocs warnings.
+ </action>
+ <action context="Renderers" dev="VH" type="add" fixes-bug="52338" importance="high">
+ Added possibility to embed TrueType fonts in PostScript.
+ </action>
+ <action context="Images" dev="GA" type="update" fixes-bug="40676" due-to="Luis Bernardo">
+ Update site documentation about PNG image loading configuration and support.
+ </action>
+ <action context="Images" dev="GA" type="update" fixes-bug="40676" due-to="Luis Bernardo">
+ Fix newly introduced findbugs warnings.
+ </action>
+ <action context="Images" dev="GA" type="fix" fixes-bug="40676" due-to="Luis Bernardo, Matthias Reischenbacher" importance="high">
+ Support use of ImageLoaderRawPNG decoder in order to prevent re-encoding of PNG images (and unnecssary output file bloat).
+ </action>
+ <action context="Code" dev="GA" type="fix" fixes-bug="53412" due-to="Alexios Giotis">
+ Eliminate incorrect use of object identity which produces excessive property cache collisions.
+ </action>
+ <action context="Code" dev="GA" type="fix">
+ Eliminate javadocs warnings.
+ </action>
+ <action context="Code" dev="GA" type="update" fixes-bug="53055">
+ Update xmlgraphics common jar to reflect recent fixes in XGC.
+ </action>
+ <action context="Code" dev="GA" type="update" fixes-bug="43940" due-to="Julien Aymé">
+ Fix handling of NaN, {+,-}Infinity, and other edge cases. Submitted by Julien Aymé.
+ </action>
<action context="Renderers" dev="GA" type="fix" fixes-bug="53304,53306">
Add version attribute to AT and IF intermediate formats. Also eliminate redundant use of reversed attribute in AT format.
</action>
diff --git a/test/java/org/apache/fop/UtilityCodeTestSuite.java b/test/java/org/apache/fop/UtilityCodeTestSuite.java
index cf6b8875d..762b86b14 100644
--- a/test/java/org/apache/fop/UtilityCodeTestSuite.java
+++ b/test/java/org/apache/fop/UtilityCodeTestSuite.java
@@ -28,10 +28,13 @@ import org.apache.fop.pdf.FileIDGeneratorTestCase;
import org.apache.fop.pdf.PDFDocumentGraphics2DTestCase;
import org.apache.fop.pdf.PDFEncryptionJCETestCase;
import org.apache.fop.pdf.PDFFactoryTestCase;
+import org.apache.fop.pdf.PDFNumberTestCase;
+import org.apache.fop.pdf.PDFObjectTestCase;
import org.apache.fop.traits.BorderPropsTestCase;
import org.apache.fop.util.BitmapImageUtilTestCase;
import org.apache.fop.util.ColorUtilTestCase;
import org.apache.fop.util.ElementListUtilsTestCase;
+import org.apache.fop.util.HexEncoderTestCase;
import org.apache.fop.util.XMLResourceBundleTestCase;
/**
@@ -49,7 +52,10 @@ import org.apache.fop.util.XMLResourceBundleTestCase;
PDFFactoryTestCase.class,
PDFEncryptionJCETestCase.class,
BitmapImageUtilTestCase.class,
- PDFDocumentGraphics2DTestCase.class
+ PDFDocumentGraphics2DTestCase.class,
+ PDFNumberTestCase.class,
+ PDFObjectTestCase.class,
+ HexEncoderTestCase.class
})
public class UtilityCodeTestSuite {
}
diff --git a/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
index 9c53bdde3..863bfe797 100644
--- a/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
+++ b/test/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverterTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.accessibility.fo;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -45,6 +43,8 @@ import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.accessibility.StructureTree2SAXEventAdapter;
import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.apps.FOPException;
@@ -102,6 +102,17 @@ public class FO2StructureTreeConverterTestCase {
testConverter();
}
+ @Test
+ public void testArtifact() throws Exception {
+ foLoader = new FOLoader() {
+
+ public InputStream getFoInputStream() {
+ return getResource("artifact.fo");
+ }
+ };
+ testConverter();
+ }
+
private Transformer createTransformer(Source xslt) throws TransformerFactoryConfigurationError,
TransformerConfigurationException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
diff --git a/test/java/org/apache/fop/accessibility/fo/artifact.fo b/test/java/org/apache/fop/accessibility/fo/artifact.fo
new file mode 100644
index 000000000..c3d5fadf3
--- /dev/null
+++ b/test/java/org/apache/fop/accessibility/fo/artifact.fo
@@ -0,0 +1,97 @@
+<?xml version="1.0" standalone="no"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="500pt" page-width="300pt" margin="20pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body" text-align="justify">
+
+ <fo:block>This piece of text is normal content that should be read out loud by a screen
+ reader.</fo:block>
+
+ <fo:block space-before="10pt">The following content will be treated as artifact:</fo:block>
+
+ <fo:wrapper role="artifact">
+ <fo:block-container border="1pt solid black" padding="5pt" background-color="#F0F0F0"
+ space-before="10pt" start-indent="6pt" end-indent="6pt" color="#606060">
+ <fo:block start-indent="0" end-indent="0">
+ <fo:block>A block as artifact.</fo:block>
+ <fo:table space-before="5pt" width="100%" table-layout="fixed">
+ <fo:table-column column-width="proportional-column-width(1)"/>
+ <fo:table-column column-width="proportional-column-width(2)"/>
+ <fo:table-header>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Header 1.1</fo:block></fo:table-cell>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Header 1.2</fo:block></fo:table-cell>
+ </fo:table-header>
+ <fo:table-footer>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Footer 1.1</fo:block></fo:table-cell>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Footer 1.2</fo:block></fo:table-cell>
+ </fo:table-footer>
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Cell 1.1</fo:block></fo:table-cell>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Cell 1.2</fo:block></fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Cell 2.1</fo:block></fo:table-cell>
+ <fo:table-cell border="1pt solid #606060"><fo:block>Cell 2.2</fo:block></fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:list-block space-before="7pt" provisional-distance-between-starts="8pt"
+ provisional-label-separation="5pt">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Item 1.</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Item 2.</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Item 3.</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ <fo:wrapper>
+ <fo:block>A block in a nested wrapper.</fo:block>
+ </fo:wrapper>
+ <fo:wrapper role="artifact">
+ <fo:block>A block in a nested artifact wrapper.</fo:block>
+ </fo:wrapper>
+ <fo:wrapper>
+ <fo:block>Inside a nested wrapper.
+ <fo:wrapper role="artifact">An artifact wrapper inside the nested wrapper.
+ <fo:inline><fo:wrapper>Inside a wrapper inside the artifact wrapper that is inside
+ the nested wrapper.</fo:wrapper> Outside the wrapper inside the artifact
+ wrapper that is inside the nested wrapper.</fo:inline>
+ </fo:wrapper> Outside the artifact wrapper.</fo:block>
+ </fo:wrapper>
+ </fo:block>
+ </fo:block-container>
+ </fo:wrapper>
+
+ <fo:block space-before="10pt">Now we are back to normal content that is part of the logical
+ structure, should appear in the structure tree and should be read out loud by the screen
+ reader.</fo:block>
+
+ </fo:flow>
+ </fo:page-sequence>
+
+</fo:root>
diff --git a/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl
index ce326f3b1..db0dffb14 100644
--- a/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl
+++ b/test/java/org/apache/fop/accessibility/fo/fo2StructureTree.xsl
@@ -105,6 +105,8 @@
<xsl:call-template name="copy"/>
</xsl:template>
+ <xsl:template match="fo:wrapper[translate(normalize-space(@role), 'ARTIFCT', 'artifct') = 'artifact']"/>
+
<!-- Discard descendants of fo:leader -->
<xsl:template match="fo:leader"/>
diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
index 4ac61d893..49c447583 100644
--- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
+++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
@@ -43,7 +43,8 @@ public class DejaVuLGCSerifTestCase {
@Before
public void setUp() throws Exception {
File file = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf");
- font = FontLoader.loadFont(file, "", true, EncodingMode.AUTO, fontResolver);
+ font = FontLoader.loadFont(file, "", true, EmbeddingMode.AUTO, EncodingMode.AUTO,
+ fontResolver);
}
/**
diff --git a/test/java/org/apache/fop/fonts/EncodingModeTestCase.java b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java
index 1ec22e1ef..8cab9eb8b 100644
--- a/test/java/org/apache/fop/fonts/EncodingModeTestCase.java
+++ b/test/java/org/apache/fop/fonts/EncodingModeTestCase.java
@@ -19,10 +19,13 @@
package org.apache.fop.fonts;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests {@link EncodingMode}.
+ */
public class EncodingModeTestCase {
@Test
@@ -34,8 +37,13 @@ public class EncodingModeTestCase {
@Test
public void testGetValue() {
- assertEquals(EncodingMode.AUTO, EncodingMode.getEncodingMode("auto"));
- assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getEncodingMode("single-byte"));
- assertEquals(EncodingMode.CID, EncodingMode.getEncodingMode("cid"));
+ assertEquals(EncodingMode.AUTO, EncodingMode.getValue("auto"));
+ assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getValue("single-byte"));
+ assertEquals(EncodingMode.CID, EncodingMode.getValue("cid"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void getValueMustCheckForIllegalArguments() {
+ EncodingMode.getValue("fail");
}
}
diff --git a/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java b/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java
new file mode 100644
index 000000000..8e1a0040d
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/FOPFontsTestSuite.java
@@ -0,0 +1,42 @@
+/*
+ * 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.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import org.apache.fop.fonts.truetype.FontFileReaderTestCase;
+import org.apache.fop.fonts.truetype.TTFFileTestCase;
+import org.apache.fop.fonts.truetype.TTFSubSetFileTestCase;
+import org.apache.fop.fonts.truetype.TTFTableNameTestCase;
+
+/**
+ * A test suite designed for org.apache.fop.fonts.*
+ */
+@RunWith(Suite.class)
+@SuiteClasses({
+ EncodingModeTestCase.class,
+ FontFileReaderTestCase.class,
+ TTFFileTestCase.class,
+ TTFSubSetFileTestCase.class,
+ TTFTableNameTestCase.class })
+public final class FOPFontsTestSuite {
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java
new file mode 100644
index 000000000..5c1fec175
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/FontFileReaderTestCase.java
@@ -0,0 +1,304 @@
+/*
+ * 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.truetype;
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * A test class for org.apache.fop.truetype.FontFileReader
+ */
+public class FontFileReaderTestCase {
+ private FontFileReader fontReader;
+ private final InputStream in;
+ private final byte[] byteArray;
+
+ /**
+ * Constructor - initialises an array that only needs to be created once. It creates a byte[]
+ * of form { 0x00, 0x01, 0x02, 0x03..., 0xff};
+ */
+ public FontFileReaderTestCase() {
+ byteArray = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ byteArray[i] = (byte) i;
+ }
+ in = new ByteArrayInputStream(byteArray);
+ }
+
+ /**
+ * sets up the test subject object for testing.
+ */
+ @Before
+ public void setUp() {
+ try {
+ fontReader = new FontFileReader(in);
+ } catch (Exception e) {
+ fail("Error: " + e.getMessage());
+ }
+ }
+
+ /**
+ * the "destructor" method.
+ *
+ */
+ public void tearDown() {
+ fontReader = null;
+ }
+
+ /**
+ * Test readTTFByte()
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFByte() throws IOException {
+ for (int i = 0; i < 256; i++) {
+ assertEquals((byte) i, fontReader.readTTFByte());
+ }
+ }
+
+ /**
+ * Test seekSet() - check that it moves to the correct position and enforce a failure case.
+ * @throws IOException exception
+ */
+ @Test
+ public void testSeekSet() throws IOException {
+ fontReader.seekSet(10);
+ assertEquals(10, fontReader.readTTFByte());
+ try {
+ fontReader.seekSet(257);
+ fail("FileFontReaderTest Failed testSeekSet");
+ } catch (IOException e) {
+ // Passed
+ }
+ }
+
+ /**
+ * Test skip() - check that it moves to the correct position and enforce a failure case.
+ * @throws IOException exception
+ */
+ @Test
+ public void testSkip() throws IOException {
+ fontReader.skip(100);
+ assertEquals(100, fontReader.readTTFByte());
+ try {
+ // 100 (seekAdd) + 1 (read() = 1 byte) + 156 = 257
+ fontReader.skip(156);
+ fail("FileFontReaderTest Failed testSkip");
+ } catch (IOException e) {
+ // Passed
+ }
+ }
+
+ /**
+ * Test getCurrentPos() - 3 checks:
+ * 1) test with seekSet(int)
+ * 2) test with skip(int)
+ * 3) test with a readTTFByte() (this moves the position by the size of the data being read)
+ * @throws IOException exception
+ */
+ @Test
+ public void testGetCurrentPos() throws IOException {
+ fontReader.seekSet(10);
+ fontReader.skip(100);
+ assertEquals(110, fontReader.getCurrentPos());
+ fontReader.readTTFByte();
+ assertEquals(111, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test getFileSize()
+ */
+ @Test
+ public void testGetFileSize() {
+ assertEquals(256, fontReader.getFileSize());
+ }
+
+ /**
+ * Test readTTFUByte()
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFUByte() throws IOException {
+ for (int i = 0; i < 256; i++) {
+ assertEquals(i, fontReader.readTTFUByte());
+ }
+ }
+
+ /**
+ * Test readTTFShort() - Test positive and negative numbers (two's compliment).
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFShort() throws IOException {
+ // 0x0001 = 1
+ assertEquals("Should have been 1 (0x0001)", 1, fontReader.readTTFShort());
+ // 0x0203 = 515
+ assertEquals(515, fontReader.readTTFShort());
+ // now test negative numbers
+ fontReader.seekSet(250);
+ // 0xfafb
+ assertEquals(-1285, fontReader.readTTFShort());
+ }
+
+ /**
+ * Test readTTFUShort() - Test positive and potentially negative numbers (two's compliment).
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFUShort() throws IOException {
+ // 0x0001
+ assertEquals(1, fontReader.readTTFUShort());
+ // 0x0203
+ assertEquals(515, fontReader.readTTFUShort());
+ // test potential negatives
+ fontReader.seekSet(250);
+ // 0xfafb
+ assertEquals((250 << 8) + 251, fontReader.readTTFUShort());
+ }
+
+ /**
+ * Test readTTFShort(int) - test reading ahead of current position and behind current position
+ * and in both cases ensure that our current position isn't changed.
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFShortWithArg() throws IOException {
+ // 0x6465
+ assertEquals(25701, fontReader.readTTFShort(100));
+ assertEquals(0, fontReader.getCurrentPos());
+ // read behind current position (and negative)
+ fontReader.seekSet(255);
+ // 0xfafb
+ assertEquals(-1285, fontReader.readTTFShort(250));
+ assertEquals(255, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test readTTFUShort(int arg) - test reading ahead of current position and behind current
+ * position and in both cases ensure that our current position isn't changed.
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFUShortWithArg() throws IOException {
+ // 0x6465
+ assertEquals(25701, fontReader.readTTFUShort(100));
+ assertEquals(0, fontReader.getCurrentPos());
+ // read behind current position (and potential negative)
+ fontReader.seekSet(255);
+ // 0xfafb
+ assertEquals(64251, fontReader.readTTFUShort(250));
+ assertEquals(255, fontReader.getCurrentPos());
+ }
+
+ /**
+ * Test readTTFLong()
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFLong() throws IOException {
+ // 0x00010203
+ assertEquals(66051, fontReader.readTTFLong());
+ // test negative numbers
+ fontReader.seekSet(250);
+ // 0xf0f1f2f3
+ assertEquals(-84148995, fontReader.readTTFLong());
+ }
+
+ /**
+ * Test readTTFULong()
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFULong() throws IOException {
+ // 0x00010203
+ assertEquals(66051, fontReader.readTTFULong());
+ // test negative numbers
+ fontReader.seekSet(250);
+ // 0xfafbfcfd
+ assertEquals(4210818301L, fontReader.readTTFULong());
+ }
+
+ /**
+ * Test readTTFString() - there are two paths to test here:
+ * 1) A null terminated string
+ * 2) A string not terminated with a null (we expect this to throw an EOFException)
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFString() throws IOException {
+ byte[] strByte = {(byte)'t', (byte)'e', (byte)'s', (byte)'t', 0x00};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString());
+ try {
+ // not NUL terminated
+ byte[] strByteNoNull = {(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByteNoNull));
+ assertEquals("test", fontReader.readTTFString());
+ fail("FontFileReaderTest testReadTTFString Fails.");
+ } catch (EOFException e) {
+ // Pass
+ }
+ }
+
+ /**
+ * Test readTTFString(int arg)
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadTTFStringIntArg() throws IOException {
+ byte[] strByte = {(byte)'t', (byte)'e', (byte)'s', (byte)'t'};
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString(4));
+ try {
+ fontReader = new FontFileReader(new ByteArrayInputStream(strByte));
+ assertEquals("test", fontReader.readTTFString(5));
+ fail("FontFileReaderTest testReadTTFStringIntArg Fails.");
+ } catch (EOFException e) {
+ // Pass
+ }
+ }
+
+ /**
+ * Test readTTFString(int arg1, int arg2)
+ */
+ public void testReadTTFString2IntArgs() {
+ // currently the same as above
+ }
+
+ /**
+ * Test getBytes()
+ * @throws IOException exception
+ */
+ @Test
+ public void testGetBytes() throws IOException {
+ byte[] retrievedBytes = fontReader.getBytes(0, 256);
+ assertTrue(Arrays.equals(byteArray, retrievedBytes));
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
index 67191accc..825f71ac1 100644
--- a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.fonts.truetype;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +29,8 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
/**
* Tests {@link GlyfTable}.
*/
@@ -141,7 +141,8 @@ public class GlyfTableTestCase {
private void setupSubsetReader(Map<Integer, Integer> glyphs) throws IOException {
TTFSubSetFile fontFile = new TTFSubSetFile();
- byte[] subsetFont = fontFile.readFont(originalFontReader, "Deja", glyphs);
+ fontFile.readFont(originalFontReader, "Deja", glyphs);
+ byte[] subsetFont = fontFile.getFontSubset();
InputStream intputStream = new ByteArrayInputStream(subsetFont);
subsetReader = new FontFileReader(intputStream);
}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
new file mode 100644
index 000000000..d490a3d5d
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
@@ -0,0 +1,427 @@
+/*
+ * 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.truetype;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.fop.fonts.truetype.TTFFile.PostScriptVersion;
+
+/**
+ * Class for testing org.apache.fop.fonts.truetype.TTFFile
+ */
+public class TTFFileTestCase {
+ // We only want to initialize the FontFileReader once (for performance reasons)
+ /** The truetype font file (DejaVuLGCSerif) */
+ protected final TTFFile dejavuTTFFile;
+ /** The FontFileReader for ttfFile (DejaVuLGCSerif) */
+ protected final FontFileReader dejavuReader;
+ /** The truetype font file (DroidSansMono) */
+ protected final TTFFile droidmonoTTFFile;
+ /** The FontFileReader for ttfFile (DroidSansMono) */
+ protected final FontFileReader droidmonoReader;
+
+
+ /**
+ * Constructor initialises FileFontReader to
+ * @throws IOException exception
+ */
+ public TTFFileTestCase() throws IOException {
+ dejavuTTFFile = new TTFFile();
+ dejavuReader = new FontFileReader("test/resources/fonts/ttf/DejaVuLGCSerif.ttf");
+ dejavuTTFFile.readFont(dejavuReader);
+ droidmonoTTFFile = new TTFFile();
+ droidmonoReader = new FontFileReader("test/resources/fonts/ttf/DroidSansMono.ttf");
+ droidmonoTTFFile.readFont(droidmonoReader);
+ }
+
+ /**
+ * Test convertTTFUnit2PDFUnit() - The units per em retrieved reading the HEAD table from
+ * the font file. (DroidSansMono has the same units per em as DejaVu so no point testing it)
+ */
+ @Test
+ public void testConvertTTFUnit2PDFUnit() {
+ // DejaVu has 2048 units per em (PDF works in millipts, thus the 1000)
+ // test rational number
+ assertEquals(1000, dejavuTTFFile.convertTTFUnit2PDFUnit(2048));
+ // test smallest case, this should = 0.488 (round down to 0)
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(1));
+ // this should round up, but since it's millipts...
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(2));
+ // ensure behaviour is the same for negative numbers
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-0));
+ assertEquals(-1000, dejavuTTFFile.convertTTFUnit2PDFUnit(-2048));
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-1));
+ assertEquals(0, dejavuTTFFile.convertTTFUnit2PDFUnit(-2));
+ }
+
+ /**
+ * Test checkTTC()
+ * @throws IOException exception
+ */
+ @Test
+ public void testCheckTTC() throws IOException {
+ // DejaVu is not a TTC, thus this returns true
+ assertTrue(dejavuTTFFile.checkTTC(""));
+ assertTrue(droidmonoTTFFile.checkTTC(""));
+ /*
+ * Cannot reasonably test the rest of this method without an actual truetype collection
+ * because all methods in FontFileReader are "final" and thus mocking isn't possible.
+ */
+ }
+
+ /**
+ * Test getAnsiKerning() - Tests values retrieved from the kern table in the font file.
+ */
+ @Test
+ public void testGetAnsiKerning() {
+ Map<Integer, Map<Integer, Integer>> ansiKerning = dejavuTTFFile.getKerning();
+ if (ansiKerning.isEmpty()) {
+ fail();
+ }
+ Integer k1 = ansiKerning.get(Integer.valueOf('A')).get(
+ Integer.valueOf('T'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-112), k1.intValue());
+ Integer k2 = ansiKerning.get(Integer.valueOf('Y')).get(Integer.valueOf('u'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-178), k2.intValue());
+
+ // DroidSansMono doens't have kerning (it's mono-spaced)
+ ansiKerning = droidmonoTTFFile.getAnsiKerning();
+ if (!ansiKerning.isEmpty()) {
+ fail("DroidSansMono shouldn't have any kerning data.");
+ }
+ }
+
+ /**
+ * Test getCapHeight - there are several paths to test:
+ * 1) The PCLT table (if present)
+ * 2) The yMax (3rd) value, for the bounding box, for 'H' in the glyf table.
+ * if not the above:
+ * 3) The caps height in the OS/2 table
+ * Tests values retrieved from analysing the font file.
+ */
+ @Test
+ public void testGetCapHeight() {
+ // DejaVu doesn't have the PCLT table and so these have to be guessed
+ // The height is approximated to be the height of the "H" which for
+ // Deja = 1493 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1493), dejavuTTFFile.getCapHeight());
+ // DroidSansMono doesn't have a PCLT table either
+ // height of "H" = 1462
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1462),
+ droidmonoTTFFile.getCapHeight());
+ }
+
+ /**
+ * Test getCharSetName() - check that it returns "WinAnsiEncoding".
+ */
+ @Test
+ public void testGetCharSetName() {
+ assertTrue("WinAnsiEncoding".equals(dejavuTTFFile.getCharSetName()));
+ assertTrue("WinAnsiEncoding".equals(droidmonoTTFFile.getCharSetName()));
+ }
+
+ /**
+ * Test getCharWidth() - Test values retrieved from the metrics in the glyf table in
+ * the font file.
+ */
+ @Test
+ public void testGetCharWidth() {
+ // Arbitrarily test a few values:
+ // The width of "H" (Unicode index 0x0048) is 1786
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1786), dejavuTTFFile.getCharWidth(0x48));
+ // The width of "i" (unicode index 0x0069) is 655 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(655), dejavuTTFFile.getCharWidth(0x69));
+ // final check, "!" (unicode index 0x0021) is 823 TTFunits
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(823), dejavuTTFFile.getCharWidth(0x21));
+
+ // All the glyphs should be the same width in DroidSansMono (mono-spaced)
+ int charWidth = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229);
+ for (int i = 0; i < 255; i++) {
+ assertEquals(charWidth, droidmonoTTFFile.getCharWidth(i));
+ }
+ }
+
+ /**
+ * TODO: add implementation to this test
+ */
+ public void testGetCMaps() {
+ }
+
+ /**
+ * Test getFamilyNames() - Test value retrieved from the name table in the font file.
+ */
+ @Test
+ public void testGetFamilyNames() {
+ assertEquals(1, dejavuTTFFile.getFamilyNames().size());
+ for (String name : dejavuTTFFile.getFamilyNames()) {
+ assertEquals("DejaVu LGC Serif", name);
+ }
+ assertEquals(1, droidmonoTTFFile.getFamilyNames().size());
+ for (String name : droidmonoTTFFile.getFamilyNames()) {
+ assertEquals("Droid Sans Mono", name);
+ }
+ }
+
+ /**
+ * Test getFirstChar() - TODO: implement a more intelligent test here.
+ */
+ @Test
+ public void testGetFirstChar() {
+ // Not really sure how to test this intelligently
+ assertEquals(0, dejavuTTFFile.getFirstChar());
+ assertEquals(0, droidmonoTTFFile.getFirstChar());
+ }
+
+ /**
+ * Test getFlags() - Test values retrieved from the POST table in the font file.
+ */
+ @Test
+ public void testGetFlags() {
+ /* DejaVu flags are:
+ * italic angle = 0
+ * fixed pitch = 0
+ * has serifs = true (default value; this font doesn't have a PCLT table)
+ */
+ int flags = dejavuTTFFile.getFlags();
+ assertEquals(0, flags & 64); // Italics angle = 0
+ assertEquals(32, flags & 32); // Adobe standard charset
+ assertEquals(0, flags & 2); // fixed pitch = 0
+ assertEquals(1, flags & 1); // has serifs = 1 (true)
+ /*
+ * Droid flags are:
+ * italic angle = 0
+ * fixed pitch = 1
+ * has serifs = true (default value; this font doesn't have a PCLT table)
+ */
+ flags = droidmonoTTFFile.getFlags();
+ assertEquals(0, flags & 64);
+ assertEquals(32, flags & 32);
+ assertEquals(2, flags & 2);
+ assertEquals(1, flags & 1);
+ }
+
+ /**
+ * Test getFontBBox() - Test values retrieved from values in the HEAD table in the font file.
+ */
+ @Test
+ public void testGetFontBBox() {
+ int[] bBox = dejavuTTFFile.getFontBBox();
+ /*
+ * The head table has the following values(DejaVu):
+ * xmin = -1576, ymin = -710, xmax = 3439, ymax = 2544
+ */
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-1576), bBox[0]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-710), bBox[1]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(3439), bBox[2]);
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(2544), bBox[3]);
+ /*
+ * The head table has the following values (DroidSansMono):
+ * xmin = -312, ymin= -555, xmax = 1315, ymax = 2163
+ */
+ bBox = droidmonoTTFFile.getFontBBox();
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(-312), bBox[0]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(-555), bBox[1]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1315), bBox[2]);
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(2163), bBox[3]);
+ }
+
+ /**
+ * Test getFullName() - Test value retrieved from the name table in the font file.
+ */
+ @Test
+ public void testGetFullName() {
+ assertEquals("DejaVu LGC Serif", dejavuTTFFile.getFullName());
+ assertEquals("Droid Sans Mono", droidmonoTTFFile.getFullName());
+ }
+
+ /**
+ * Test getGlyphName - Test value retrieved from the POST table in the font file.
+ */
+ @Test
+ public void testGetGlyphName() {
+ assertEquals("H", dejavuTTFFile.getGlyphName(43));
+ assertEquals("H", droidmonoTTFFile.getGlyphName(43));
+ }
+
+ /**
+ * Test getItalicAngle() - Test value retrieved from the POST table in the font file.
+ */
+ @Test
+ public void testGetItalicAngle() {
+ assertEquals("0", dejavuTTFFile.getItalicAngle());
+ assertEquals("0", droidmonoTTFFile.getItalicAngle());
+ }
+
+ /**
+ * Test getKerning() - Test values retrieved from the kern table in the font file.
+ */
+ @Test
+ public void testGetKerning() {
+ Map<Integer, Map<Integer, Integer>> kerning = dejavuTTFFile.getKerning();
+ if (kerning.isEmpty()) {
+ fail();
+ }
+ Integer k1 = kerning.get(Integer.valueOf('A')).get(Integer.valueOf('T'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-112), k1.intValue());
+ Integer k2 = kerning.get(Integer.valueOf('K')).get(Integer.valueOf('u'));
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-45), k2.intValue());
+
+ // DroidSansMono has no kerning data (mono-spaced)
+ kerning = droidmonoTTFFile.getKerning();
+ if (!kerning.isEmpty()) {
+ fail("DroidSansMono shouldn't have any kerning data");
+ }
+ }
+
+ /**
+ * Test lastChar() - TODO: implement a more intelligent test
+ */
+ @Test
+ public void testLastChar() {
+ assertEquals(0xff, dejavuTTFFile.getLastChar());
+ assertEquals(0xff, droidmonoTTFFile.getLastChar());
+ }
+
+ /**
+ * Test getLowerCaseAscent() - There are several paths to test:
+ * 1) The values in the HHEA table (see code)
+ * 2) Fall back to values from the OS/2 table
+ * Test values retrieved from the font file.
+ */
+ @Test
+ public void testGetLowerCaseAscent() {
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1556),
+ dejavuTTFFile.getLowerCaseAscent());
+ // Curiously the same value
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1556),
+ droidmonoTTFFile.getLowerCaseAscent());
+ }
+
+ /**
+ * Test getPostScriptName() - Test values retrieved from the post table in the font file.
+ */
+ @Test
+ public void testGetPostScriptName() {
+ assertEquals(PostScriptVersion.V2, dejavuTTFFile.getPostScriptVersion());
+ assertEquals(PostScriptVersion.V2, droidmonoTTFFile.getPostScriptVersion());
+ }
+
+ /**
+ * Test getStemV() - Undefined.
+ */
+ @Test
+ public void testGetStemV() {
+ // Undefined
+ assertEquals("0", dejavuTTFFile.getStemV());
+ assertEquals("0", droidmonoTTFFile.getStemV());
+ }
+
+ /**
+ * Test getSubFamilyName() - Test values retrieved from the name table in the font file.
+ */
+ @Test
+ public void testGetSubFamilyName() {
+ assertEquals("Book", dejavuTTFFile.getSubFamilyName());
+ assertEquals("Regular", droidmonoTTFFile.getSubFamilyName());
+ }
+
+ /**
+ * Test getTTCnames() - TODO: add implementation with TTC font.
+ */
+ public void testGetTTCnames() {
+ // Can't test with with DejaVu since it's not a TrueType Collection
+ }
+
+ /**
+ * Test getWeightClass() - Test value retrieved from the OS/2 table in the font file.
+ */
+ @Test
+ public void testGetWeightClass() {
+ // Retrieved from OS/2 table
+ assertEquals(400, dejavuTTFFile.getWeightClass());
+ assertEquals(400, droidmonoTTFFile.getWeightClass());
+ }
+
+ /**
+ * Test getWidths() - Test values retrieved from the hmtx table in the font file.
+ */
+ @Test
+ public void testGetWidths() {
+ int[] widths = dejavuTTFFile.getWidths();
+ // using the width of 'A' index = 36
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1479), widths[36]);
+ // using the width of '|' index = 95
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(690), widths[95]);
+ widths = droidmonoTTFFile.getWidths();
+ // DroidSansMono should have all widths the same size (mono-spaced)
+ int width = droidmonoTTFFile.convertTTFUnit2PDFUnit(1229);
+ for (int i = 0; i < 255; i++) {
+ assertEquals(width, widths[i]);
+ }
+ }
+
+ /**
+ * Test getXHeight() - There are several paths to test:
+ * 1) The PCLT table (if available)
+ * 2) The yMax for the bounding box for 'x' in the glyf table.
+ * Fall back:
+ * 3) The xheight in the OS/2 table.
+ */
+ @Test
+ public void testGetXHeight() {
+ // Since there's no PCLT table, the height of 'x' is used for both DejaVu and DroidSansMono
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(1064), dejavuTTFFile.getXHeight());
+ assertEquals(droidmonoTTFFile.convertTTFUnit2PDFUnit(1098), droidmonoTTFFile.getXHeight());
+ }
+
+ /**
+ * Test isCFF() - TODO: add test for a CFF font.
+ */
+ @Test
+ public void testIsCFF() {
+ // Neither DejaVu nor DroidSansMono are a compact format font
+ assertEquals(false, dejavuTTFFile.isCFF());
+ assertEquals(false, droidmonoTTFFile.isCFF());
+ }
+
+ /**
+ * Test isEmbeddable() - Test value retrieved from the OS/2 table in the font file.
+ */
+ @Test
+ public void testIsEmbeddable() {
+ // Dejavu and DroidSansMono are both embeddable
+ assertEquals(true, dejavuTTFFile.isEmbeddable());
+ assertEquals(true, droidmonoTTFFile.isEmbeddable());
+ }
+
+ /**
+ * Test readFont() - Add implementation if necessary.
+ */
+ public void testReadFont() {
+ // I'm pretty sure we've tested this with all the other tests
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
index 35c865cd7..d6555c32e 100644
--- a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
@@ -19,18 +19,19 @@
package org.apache.fop.fonts.truetype;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.io.IOException;
import org.junit.Test;
+import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontResolver;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
/**
* Test case for {@link TTFFontLoader}.
*/
@@ -47,12 +48,12 @@ public class TTFFontLoaderTestCase {
boolean useKerning = true;
TTFFontLoader fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded,
- EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resolver);
+ EmbeddingMode.AUTO, EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resolver);
assertTrue(fontLoader.getFont().hasKerningInfo());
useKerning = false;
- fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, EncodingMode.AUTO,
- useKerning, useComplexScriptFeatures, resolver);
+ fontLoader = new TTFFontLoader(absoluteFilePath, fontName, embedded, EmbeddingMode.AUTO,
+ EncodingMode.AUTO, useKerning, useComplexScriptFeatures, resolver);
assertFalse(fontLoader.getFont().hasKerningInfo());
}
}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.java
new file mode 100644
index 000000000..16bedad8d
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFSubSetFileTestCase.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.fonts.truetype;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * This class tests TTFSubSetFile
+ * TODO: Test with more than just a single font
+ */
+public class TTFSubSetFileTestCase extends TTFFileTestCase {
+ private TTFSubSetFile ttfSubset;
+ private byte[] subset;
+ /**
+ * Constructor
+ * @throws IOException exception
+ */
+ public TTFSubSetFileTestCase() throws IOException {
+ super();
+ }
+
+ /**
+ * setUp()
+ * @exception IOException file read error
+ */
+ @Before
+ public void setUp() throws IOException {
+ ttfSubset = new TTFSubSetFile();
+ Map<Integer, Integer> glyphs = new HashMap<Integer, Integer>();
+ for (int i = 0; i < 255; i++) {
+ glyphs.put(i, i);
+ }
+ ttfSubset.readFont(dejavuReader, "DejaVu", glyphs);
+ subset = ttfSubset.getFontSubset();
+ }
+ /**
+ * Test readFont(FontFileReader, String, Map) - Reads the font and tests the output by injecting
+ * it into a TTFFile object to check the validity of the file as a font. This currently doesn't
+ * create a cmap table, and so the font doesn't contain ALL of the mandatory tables.
+ * @throws IOException exception
+ */
+ @Test
+ public void testReadFont3Args() throws IOException {
+
+ ByteArrayInputStream byteArray = new ByteArrayInputStream(subset);
+ dejavuTTFFile.readFont(new FontFileReader(byteArray));
+ // Test a couple arbitrary values
+ assertEquals(dejavuTTFFile.convertTTFUnit2PDFUnit(-1576), dejavuTTFFile.getFontBBox()[0]);
+ assertEquals(dejavuTTFFile.getFullName(), "DejaVu LGC Serif");
+ }
+}
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.java
new file mode 100644
index 000000000..b9066dc2d
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/truetype/TTFTableNameTestCase.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.fonts.truetype;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This class tests the enum org.apache.fop.fonts.truetype.TTFTableName
+ *
+ */
+public class TTFTableNameTestCase {
+ /**
+ * Test getName() - tests that the getName() method returns the expected String as expected in
+ * the Directory Table.
+ * @exception IllegalAccessException error
+ */
+ @Test
+ public void testGetName() throws IllegalAccessException {
+ assertEquals("tableDirectory", TTFTableName.TABLE_DIRECTORY.getName());
+ assertEquals("EBDT", TTFTableName.EBDT.getName());
+ assertEquals("EBLC", TTFTableName.EBLC.getName());
+ assertEquals("EBSC", TTFTableName.EBSC.getName());
+ assertEquals("FFTM", TTFTableName.FFTM.getName());
+ assertEquals("GDEF", TTFTableName.GDEF.getName());
+ assertEquals("GPOS", TTFTableName.GPOS.getName());
+ assertEquals("GSUB", TTFTableName.GSUB.getName());
+ assertEquals("LTSH", TTFTableName.LTSH.getName());
+ assertEquals("OS/2", TTFTableName.OS2.getName());
+ assertEquals("PCLT", TTFTableName.PCLT.getName());
+ assertEquals("VDMX", TTFTableName.VDMX.getName());
+ assertEquals("cmap", TTFTableName.CMAP.getName());
+ assertEquals("cvt ", TTFTableName.CVT.getName());
+ assertEquals("fpgm", TTFTableName.FPGM.getName());
+ assertEquals("gasp", TTFTableName.GASP.getName());
+ assertEquals("glyf", TTFTableName.GLYF.getName());
+ assertEquals("hdmx", TTFTableName.HDMX.getName());
+ assertEquals("head", TTFTableName.HEAD.getName());
+ assertEquals("hhea", TTFTableName.HHEA.getName());
+ assertEquals("hmtx", TTFTableName.HMTX.getName());
+ assertEquals("kern", TTFTableName.KERN.getName());
+ assertEquals("loca", TTFTableName.LOCA.getName());
+ assertEquals("maxp", TTFTableName.MAXP.getName());
+ assertEquals("name", TTFTableName.NAME.getName());
+ assertEquals("post", TTFTableName.POST.getName());
+ assertEquals("prep", TTFTableName.PREP.getName());
+ assertEquals("vhea", TTFTableName.VHEA.getName());
+ assertEquals("vmtx", TTFTableName.VMTX.getName());
+ // make sure it works with other table names
+ TTFTableName test = TTFTableName.getValue("test");
+ assertEquals("test", test.getName());
+ }
+
+ /**
+ * Test getValue(String) - tests that the getValue(String) method returns the expected
+ * TTFTableNames value when it is given a String (name of a table).
+ * @exception IllegalAccessException error
+ */
+ @Test
+ public void testGetValue() throws IllegalAccessException {
+ assertEquals(TTFTableName.EBDT, TTFTableName.getValue("EBDT"));
+ assertEquals(TTFTableName.EBLC, TTFTableName.getValue("EBLC"));
+ assertEquals(TTFTableName.EBSC, TTFTableName.getValue("EBSC"));
+ assertEquals(TTFTableName.FFTM, TTFTableName.getValue("FFTM"));
+ assertEquals(TTFTableName.LTSH, TTFTableName.getValue("LTSH"));
+ assertEquals(TTFTableName.OS2, TTFTableName.getValue("OS/2"));
+ assertEquals(TTFTableName.PCLT, TTFTableName.getValue("PCLT"));
+ assertEquals(TTFTableName.VDMX, TTFTableName.getValue("VDMX"));
+ assertEquals(TTFTableName.CMAP, TTFTableName.getValue("cmap"));
+ assertEquals(TTFTableName.CVT, TTFTableName.getValue("cvt "));
+ assertEquals(TTFTableName.FPGM, TTFTableName.getValue("fpgm"));
+ assertEquals(TTFTableName.GASP, TTFTableName.getValue("gasp"));
+ assertEquals(TTFTableName.GLYF, TTFTableName.getValue("glyf"));
+ assertEquals(TTFTableName.HDMX, TTFTableName.getValue("hdmx"));
+ assertEquals(TTFTableName.HEAD, TTFTableName.getValue("head"));
+ assertEquals(TTFTableName.HHEA, TTFTableName.getValue("hhea"));
+ assertEquals(TTFTableName.HMTX, TTFTableName.getValue("hmtx"));
+ assertEquals(TTFTableName.KERN, TTFTableName.getValue("kern"));
+ assertEquals(TTFTableName.LOCA, TTFTableName.getValue("loca"));
+ assertEquals(TTFTableName.MAXP, TTFTableName.getValue("maxp"));
+ assertEquals(TTFTableName.NAME, TTFTableName.getValue("name"));
+ assertEquals(TTFTableName.POST, TTFTableName.getValue("post"));
+ assertEquals(TTFTableName.PREP, TTFTableName.getValue("prep"));
+ assertEquals(TTFTableName.VHEA, TTFTableName.getValue("vhea"));
+ assertEquals(TTFTableName.VMTX, TTFTableName.getValue("vmtx"));
+ // Test that we can store a random table name and it will not fail or throw an error.
+ TTFTableName test = TTFTableName.getValue("random");
+ assertTrue(test instanceof TTFTableName);
+ }
+
+ /**
+ * This class overrides hashCode() - we need to ensure it works properly by instantiating two
+ * objects and comparing their hash-codes.
+ * @exception IllegalAccessException error
+ */
+ @Test
+ public void testHashCode() throws IllegalAccessException {
+ TTFTableName a = TTFTableName.getValue("testObject");
+ TTFTableName b = TTFTableName.getValue("testObject");
+ assertTrue(a.hashCode() == b.hashCode());
+ TTFTableName c = TTFTableName.getValue("fail");
+ assertFalse(a.hashCode() == c.hashCode());
+ }
+
+ /**
+ * This class overrides equals(object) - we need to test:
+ * 1) Reflexivity
+ * 2) Symmetry
+ * 3) Transitivity
+ * 4) Consistency
+ * 5) check it fails if you put in a null value
+ * @throws IllegalAccessException error
+ */
+ @Test
+ public void testEquals() throws IllegalAccessException {
+ // Reflexivity
+ TTFTableName a = TTFTableName.getValue("test");
+ assertTrue(a.equals(a));
+ // Symmetry
+ TTFTableName b = TTFTableName.getValue("test");
+ assertTrue(a.equals(b));
+ assertTrue(b.equals(a));
+ // Transitivity (tested with symmetry)
+ // Consistency (test that a == b is true and that a == c fails)
+ TTFTableName c = TTFTableName.getValue("fail");
+ for (int i = 0; i < 100; i++) {
+ assertTrue(a.equals(b));
+ assertFalse(a.equals(c));
+ }
+ // check with null value
+ assertFalse(a.equals(null));
+ }
+}
diff --git a/test/java/org/apache/fop/render/RawPNGTestUtil.java b/test/java/org/apache/fop/render/RawPNGTestUtil.java
new file mode 100644
index 000000000..e6660bb42
--- /dev/null
+++ b/test/java/org/apache/fop/render/RawPNGTestUtil.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import org.apache.xmlgraphics.image.loader.ImageSize;
+
+public final class RawPNGTestUtil {
+
+ private static int NUM_ROWS = 32;
+ private static int NUM_COLUMNS = 32;
+ private static int DPI = 72;
+
+ private RawPNGTestUtil() {
+
+ }
+
+ /**
+ * Builds a PNG IDAT section for a square of a given color and alpha; the filter is fixed.
+ * @param gray the gray color; set to -1 if using RGB
+ * @param red the red color; ignored if gray > -1
+ * @param green the green color; ignored if gray > -1
+ * @param blue the blue color; ignored if gray > -1
+ * @param alpha the alpha color; set to -1 if not present
+ * @return the PNG IDAT byte array
+ * @throws IOException
+ */
+ public static byte[] buildGRGBAData(int gray, int red, int green, int blue, int alpha) throws IOException {
+ // build an image, 32x32, Gray or RGB, with or without alpha, and with filter
+ int filter = 0;
+ int numRows = NUM_ROWS;
+ int numColumns = NUM_COLUMNS;
+ int numComponents = (gray > -1 ? 1 : 3) + (alpha > -1 ? 1 : 0);
+ int numBytesPerRow = numColumns * numComponents + 1; // 1 for filter
+ int numBytes = numRows * numBytesPerRow;
+ byte[] data = new byte[numBytes];
+ for (int r = 0; r < numRows; r++) {
+ data[r * numBytesPerRow] = (byte) filter;
+ for (int c = 0; c < numColumns; c++) {
+ if (numComponents == 1) {
+ data[r * numBytesPerRow + numComponents * c + 1] = (byte) gray;
+ } else if (numComponents == 2) {
+ data[r * numBytesPerRow + numComponents * c + 1] = (byte) gray;
+ data[r * numBytesPerRow + numComponents * c + 2] = (byte) alpha;
+ } else if (numComponents == 3) {
+ data[r * numBytesPerRow + numComponents * c + 1] = (byte) red;
+ data[r * numBytesPerRow + numComponents * c + 2] = (byte) green;
+ data[r * numBytesPerRow + numComponents * c + 3] = (byte) blue;
+ } else if (numComponents == 4) {
+ data[r * numBytesPerRow + numComponents * c + 1] = (byte) red;
+ data[r * numBytesPerRow + numComponents * c + 2] = (byte) green;
+ data[r * numBytesPerRow + numComponents * c + 3] = (byte) blue;
+ data[r * numBytesPerRow + numComponents * c + 4] = (byte) alpha;
+ }
+ }
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater());
+ dos.write(data);
+ dos.close();
+ return baos.toByteArray();
+ }
+
+ /**
+ *
+ * @return a default ImageSize
+ */
+ public static ImageSize getImageSize() {
+ return new ImageSize(NUM_ROWS, NUM_COLUMNS, DPI);
+ }
+}
diff --git a/test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java b/test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java
new file mode 100644
index 000000000..885821f66
--- /dev/null
+++ b/test/java/org/apache/fop/render/pdf/ImageRawPNGAdapterTestCase.java
@@ -0,0 +1,142 @@
+/*
+ * 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.awt.image.ComponentColorModel;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import org.junit.Test;
+
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+
+import org.apache.fop.pdf.FlateFilter;
+import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFProfile;
+import org.apache.fop.render.RawPNGTestUtil;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ImageRawPNGAdapterTestCase {
+
+ @Test
+ public void testSetupWithIndexColorModel() {
+ IndexColorModel cm = mock(IndexColorModel.class);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ PDFDocument doc = mock(PDFDocument.class);
+ PDFProfile profile = mock(PDFProfile.class);
+ ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
+ ImageSize is = RawPNGTestUtil.getImageSize();
+
+ when(irpng.getColorModel()).thenReturn(cm);
+ // when(cm.hasAlpha()).thenReturn(false);
+ when(doc.getProfile()).thenReturn(profile);
+ when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
+ when(irpng.getSize()).thenReturn(is);
+ irpnga.setup(doc);
+ FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
+ assertEquals(1, filter.getColors());
+ }
+
+ @Test
+ public void testSetupWithComponentColorModel() throws IOException {
+ ComponentColorModel cm = mock(ComponentColorModel.class);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ PDFDocument doc = mock(PDFDocument.class);
+ PDFProfile profile = mock(PDFProfile.class);
+ ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
+ ImageSize is = RawPNGTestUtil.getImageSize();
+
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(cm.getNumComponents()).thenReturn(3);
+ // when(cm.hasAlpha()).thenReturn(false);
+ when(doc.getProfile()).thenReturn(profile);
+ when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
+ when(irpng.getSize()).thenReturn(is);
+ irpnga.setup(doc);
+ FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
+ assertEquals(3, filter.getColors());
+ }
+
+ @Test
+ public void testOutputContentsWithRGBPNG() throws IOException {
+ testOutputContentsWithGRGBAPNG(-1, 128, 128, 128, -1);
+ }
+
+ @Test
+ public void testOutputContentsWithRGBAPNG() throws IOException {
+ testOutputContentsWithGRGBAPNG(-1, 128, 128, 128, 128);
+ }
+
+ @Test
+ public void testOutputContentsWithGPNG() throws IOException {
+ testOutputContentsWithGRGBAPNG(128, -1, -1, -1, -1);
+ }
+
+ @Test
+ public void testOutputContentsWithGAPNG() throws IOException {
+ testOutputContentsWithGRGBAPNG(128, -1, -1, -1, 128);
+ }
+
+ private void testOutputContentsWithGRGBAPNG(int gray, int red, int green, int blue, int alpha)
+ throws IOException {
+ int numColorComponents = gray > -1 ? 1 : 3;
+ int numComponents = numColorComponents + (alpha > -1 ? 1 : 0);
+ ComponentColorModel cm = mock(ComponentColorModel.class);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ PDFDocument doc = mock(PDFDocument.class);
+ PDFProfile profile = mock(PDFProfile.class);
+ ImageRawPNGAdapter irpnga = new ImageRawPNGAdapter(irpng, "mock");
+ ImageSize is = RawPNGTestUtil.getImageSize();
+
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(cm.getNumComponents()).thenReturn(numComponents);
+ // when(cm.hasAlpha()).thenReturn(false);
+ when(doc.getProfile()).thenReturn(profile);
+ when(profile.getPDFAMode()).thenReturn(PDFAMode.PDFA_1A);
+ when(irpng.getSize()).thenReturn(is);
+ irpnga.setup(doc);
+ FlateFilter filter = (FlateFilter) irpnga.getPDFFilter();
+ assertEquals(numColorComponents, filter.getColors());
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] data = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, alpha);
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ when(irpng.createInputStream()).thenReturn(bais);
+ irpnga.outputContents(baos);
+ if (alpha > -1) {
+ byte[] expected = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, -1);
+ assertArrayEquals(expected, baos.toByteArray());
+ } else {
+ assertArrayEquals(data, baos.toByteArray());
+ }
+ }
+
+}
diff --git a/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java
new file mode 100644
index 000000000..458033dad
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java
@@ -0,0 +1,133 @@
+/*
+ * 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.awt.image.ComponentColorModel;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+
+import org.apache.fop.render.RawPNGTestUtil;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ImageEncoderPNGTestCase {
+
+ @Test
+ public void testWriteToWithRGBPNG() throws IOException {
+ testWriteToWithGRGBAPNG(-1, 128, 128, 128, -1);
+ }
+
+ @Test
+ public void testWriteToWithGPNG() throws IOException {
+ testWriteToWithGRGBAPNG(128, -1, -1, -1, -1);
+ }
+
+ @Test
+ public void testWriteToWithRGBAPNG() throws IOException {
+ testWriteToWithGRGBAPNG(-1, 128, 128, 128, 128);
+ }
+
+ @Test
+ public void testWriteToWithGAPNG() throws IOException {
+ testWriteToWithGRGBAPNG(128, -1, -1, -1, 128);
+ }
+
+ private void testWriteToWithGRGBAPNG(int gray, int red, int green, int blue, int alpha)
+ throws IOException {
+ int numComponents = (gray > -1 ? 1 : 3) + (alpha > -1 ? 1 : 0);
+ ImageSize is = RawPNGTestUtil.getImageSize();
+ ComponentColorModel cm = mock(ComponentColorModel.class);
+ when(cm.getNumComponents()).thenReturn(numComponents);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(irpng.getSize()).thenReturn(is);
+ ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] data = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, alpha);
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ when(irpng.createInputStream()).thenReturn(bais);
+ iepng.writeTo(baos);
+ if (alpha > -1) {
+ byte[] expected = RawPNGTestUtil.buildGRGBAData(gray, red, green, blue, -1);
+ assertArrayEquals(expected, baos.toByteArray());
+ } else {
+ assertArrayEquals(data, baos.toByteArray());
+ }
+ }
+
+ @Test
+ public void testWriteToWithPalettePNG() throws IOException {
+ ImageSize is = RawPNGTestUtil.getImageSize();
+ IndexColorModel cm = mock(IndexColorModel.class);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(irpng.getSize()).thenReturn(is);
+ ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] data = RawPNGTestUtil.buildGRGBAData(128, -1, -1, -1, -1);
+ ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ when(irpng.createInputStream()).thenReturn(bais);
+ iepng.writeTo(baos);
+ assertArrayEquals(data, baos.toByteArray());
+ }
+
+ @Test
+ public void testGetImplicitFilterWithIndexColorModel() {
+ ImageSize is = RawPNGTestUtil.getImageSize();
+ IndexColorModel cm = mock(IndexColorModel.class);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(irpng.getBitDepth()).thenReturn(8);
+ when(irpng.getSize()).thenReturn(is);
+ ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);
+
+ String expectedFilter = "<< /Predictor 15 /Columns 32 /Colors 1 /BitsPerComponent 8 >> /FlateDecode";
+ assertEquals(expectedFilter, iepng.getImplicitFilter());
+ }
+
+ @Test
+ public void testGetImplicitFilterWithComponentColorModel() {
+ ImageSize is = RawPNGTestUtil.getImageSize();
+ ComponentColorModel cm = mock(ComponentColorModel.class);
+ when(cm.getNumComponents()).thenReturn(3);
+ ImageRawPNG irpng = mock(ImageRawPNG.class);
+ when(irpng.getColorModel()).thenReturn(cm);
+ when(irpng.getBitDepth()).thenReturn(8);
+ when(irpng.getSize()).thenReturn(is);
+ ImageEncoderPNG iepng = new ImageEncoderPNG(irpng);
+
+ String expectedFilter = "<< /Predictor 15 /Columns 32 /Colors 3 /BitsPerComponent 8 >> /FlateDecode";
+ assertEquals(expectedFilter, iepng.getImplicitFilter());
+ }
+
+}
diff --git a/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java b/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java
new file mode 100644
index 000000000..2e15bf91f
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/RenderPSTestSuite.java
@@ -0,0 +1,43 @@
+/*
+ * 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.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import org.apache.fop.render.ps.fonts.PSTTFGeneratorTestCase;
+import org.apache.fop.render.ps.fonts.PSTTFGlyphOutputStreamTestCase;
+import org.apache.fop.render.ps.fonts.PSTTFOutputStreamTestCase;
+import org.apache.fop.render.ps.fonts.PSTTFTableOutputStreamTestCase;
+
+
+/**
+ * A test Suite for org.apache.fop.render.ps.*
+ */
+@RunWith(Suite.class)
+@SuiteClasses({
+ PSTTFGeneratorTestCase.class,
+ PSTTFOutputStreamTestCase.class,
+ PSTTFGlyphOutputStreamTestCase.class,
+ PSTTFTableOutputStreamTestCase.class
+})
+public final class RenderPSTestSuite {
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java
new file mode 100644
index 000000000..f7f311ff8
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGeneratorTestCase.java
@@ -0,0 +1,120 @@
+/*
+ * 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.fonts;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+/**
+ * The test class for org.apache.fop.render.ps.fonts.PSGenerator
+ */
+public class PSTTFGeneratorTestCase {
+ private PSTTFGenerator ttfGen;
+ private ByteArrayOutputStream out = new ByteArrayOutputStream();
+ private PSGenerator gen = new PSGenerator(out);
+ private byte[] byteArray;
+
+ /**
+ * Constructor
+ */
+ public PSTTFGeneratorTestCase() {
+ byteArray = new byte[65536];
+ for (int i = 0; i < 65536; i++) {
+ byteArray[i] = (byte) i;
+ }
+ }
+
+ @Before
+ public void setUp() {
+ ttfGen = new PSTTFGenerator(gen);
+ }
+
+ /**
+ * Tests startString() - starts the string in an appropriate way for a PostScript file.
+ * @exception IOException write error
+ */
+ @Test
+ public void testStartString() throws IOException {
+ ttfGen.startString();
+ assertEquals("<\n", out.toString());
+ }
+
+ /**
+ * Test streamBytes() - tests that strings are written to file in the proper format.
+ * @throws IOException write error.
+ */
+ @Test
+ public void testStreamBytes() throws IOException {
+ ttfGen.streamBytes(byteArray, 0, 16);
+ assertEquals("000102030405060708090A0B0C0D0E0F", out.toString());
+ /*
+ * 65520 is the closes multiple of 80 to 65535 (max string size in PS document) and since
+ * one byte takes up two characters, 65520 / 2 - 16 (16 bytes already written)= 32744.
+ */
+ ttfGen.streamBytes(byteArray, 0, 32744);
+ // Using a regex to ensure that the format is correct
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n){819}"));
+ try {
+ ttfGen.streamBytes(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ fail("Shouldn't be able to write more than MAX_BUFFER_SIZE to a PS document");
+ } catch (UnsupportedOperationException e) {
+ // PASS
+ }
+ }
+
+ /**
+ * Test reset() - reset should reset the line counter such that when reset() is invoked the
+ * following string streamed to the PS document should be 80 chars long.
+ * @throws IOException file write error.
+ */
+ @Test
+ public void testReset() throws IOException {
+ ttfGen.streamBytes(byteArray, 0, 40);
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n)"));
+ ttfGen.streamBytes(byteArray, 0, 40);
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n){2}"));
+
+ }
+
+ /**
+ * Test endString() - ensures strings are ended in the PostScript document in the correct
+ * format, a "00" needs to be appended to the end of a string.
+ * @throws IOException file write error
+ */
+ @Test
+ public void testEndString() throws IOException {
+ ttfGen.endString();
+ assertEquals("00\n> ", out.toString());
+ out.reset();
+ // we need to check that this doesn't write more than 80 chars per line
+ ttfGen.streamBytes(byteArray, 0, 40);
+ ttfGen.endString();
+ assertTrue(out.toString().matches("([0-9A-F]{80}\n)00\n> "));
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java
new file mode 100644
index 000000000..82b4364c3
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFGlyphOutputStreamTestCase.java
@@ -0,0 +1,109 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Test class for PSTTFGlyphOutputStream
+ */
+public class PSTTFGlyphOutputStreamTestCase {
+ private PSTTFGenerator mockGen;
+ private PSTTFGlyphOutputStream glyphOut;
+
+ @Before
+ public void setUp() {
+ mockGen = mock(PSTTFGenerator.class);
+ glyphOut = new PSTTFGlyphOutputStream(mockGen);
+ }
+
+ /**
+ * Test startGlyphStream() - test that startGlyphStream() invokes reset() and startString() in
+ * PSTTFGenerator.
+ * @exception IOException file write error
+ */
+ @Test
+ public void testStartGlyphStream() throws IOException {
+ glyphOut.startGlyphStream();
+ verify(mockGen).startString();
+ }
+
+ /**
+ * Test streamGlyph(byte[],int,int) - tests several paths:
+ * 1) strings are properly appended
+ * 2) when total strings size > PSTTFGenerator.MAX_BUFFER_SIZE, the strings is closed and a new
+ * strings is started.
+ * 3) if a glyph of size > PSTTFGenerator.MAX_BUFFER_SIZE is attempted, an exception is thrown.
+ * @throws IOException file write error.
+ */
+ @Test
+ public void testStreamGlyph() throws IOException {
+ int byteArraySize = 10;
+ byte[] byteArray = new byte[byteArraySize];
+ int runs = 100;
+ for (int i = 0; i < runs; i++) {
+ glyphOut.streamGlyph(byteArray, 0, byteArraySize);
+ }
+ verify(mockGen, times(runs)).streamBytes(byteArray, 0, byteArraySize);
+
+ /*
+ * We want to run this for MAX_BUFFER_SIZE / byteArraySize so that go over the string
+ * boundary and enforce the ending and starting of a new string. Using mockito to ensure
+ * that this behaviour is performed in order (since this is an integral behavioural aspect)
+ */
+ int stringLimit = PSTTFGenerator.MAX_BUFFER_SIZE / byteArraySize;
+ for (int i = 0; i < stringLimit; i++) {
+ glyphOut.streamGlyph(byteArray, 0, byteArraySize);
+ }
+ InOrder inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen, times(stringLimit)).streamBytes(byteArray, 0, byteArraySize);
+ inOrder.verify(mockGen).endString();
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen, times(runs)).streamBytes(byteArray, 0, byteArraySize);
+
+ try {
+ glyphOut.streamGlyph(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ fail("Shouldn't allow a length > PSTTFGenerator.MAX_BUFFER_SIZE");
+ } catch (UnsupportedOperationException e) {
+ // PASS
+ }
+ }
+
+ /**
+ * Test endGlyphStream() - tests that PSTTFGenerator.endString() is invoked when this method
+ * is called.
+ * @throws IOException file write exception
+ */
+ @Test
+ public void testEndGlyphStream() throws IOException {
+ glyphOut.endGlyphStream();
+ verify(mockGen).endString();
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java
new file mode 100644
index 000000000..744f17f64
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFOutputStreamTestCase.java
@@ -0,0 +1,90 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.fonts.truetype.TTFGlyphOutputStream;
+import org.apache.fop.fonts.truetype.TTFTableOutputStream;
+
+/**
+ * Tests PSTTFOuputStream
+ */
+public class PSTTFOutputStreamTestCase {
+ private PSGenerator gen;
+ private PSTTFOutputStream out;
+
+ /**
+ * Assigns an OutputStream to the PSGenerator.
+ */
+ @Before
+ public void setUp() {
+ gen = mock(PSGenerator.class);
+ out = new PSTTFOutputStream(gen);
+ }
+
+ /**
+ * Test startFontStream() - Just tests that the font is properly initiated in the PostScript
+ * document (in this case with "/sfnts[")
+ * @throws IOException write exception.
+ */
+ @Test
+ public void testStartFontStream() throws IOException {
+ out.startFontStream();
+ verify(gen).write("/sfnts[");
+ }
+
+ /**
+ * Test getTableOutputStream() - we need to test that the inheritance model is properly obeyed.
+ */
+ @Test
+ public void testGetTableOutputStream() {
+ TTFTableOutputStream tableOut = out.getTableOutputStream();
+ assertTrue(tableOut instanceof PSTTFTableOutputStream);
+ }
+
+ /**
+ * Test getGlyphOutputStream() - we need to test that the inheritance model is properly obeyed.
+ */
+ @Test
+ public void testGetGlyphOutputStream() {
+ TTFGlyphOutputStream glyphOut = out.getGlyphOutputStream();
+ assertTrue(glyphOut instanceof PSTTFGlyphOutputStream);
+ }
+
+ /**
+ * Test endFontStream()
+ * @exception IOException write error.
+ */
+ @Test
+ public void testEndFontStream() throws IOException {
+ out.endFontStream();
+ verify(gen).writeln("] def");
+ }
+}
diff --git a/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java
new file mode 100644
index 000000000..c20c3d8b1
--- /dev/null
+++ b/test/java/org/apache/fop/render/ps/fonts/PSTTFTableOutputStreamTestCase.java
@@ -0,0 +1,87 @@
+/*
+ * 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.fonts;
+
+import java.io.IOException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InOrder;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Test class for unit testing PSTTFTableOutputStream
+ */
+public class PSTTFTableOutputStreamTestCase {
+ private PSTTFGenerator mockGen;
+ private PSTTFTableOutputStream tableOut;
+
+ @Before
+ public void setUp() {
+ mockGen = mock(PSTTFGenerator.class);
+ tableOut = new PSTTFTableOutputStream(mockGen);
+ }
+
+ /**
+ * Test streamTable() - several paths to test (2. and 3. test corner cases):
+ * 1) that a table of length < PSTTFGenerator.MAX_BUFFER_SIZE invokes the correct methods in
+ * PSTTFGenerator.
+ * 2) that a table of length > PSTTFGenerator.MAX_BUFFER_SIZE and
+ * length == n * PSTTFGenerator.MAX_BUFFER_SIZE is split up and the methods in PSTTFGenerator
+ * are invoked.
+ * 3) that a table of length > PSTTFGenerator.MAX_BUFFER_SIZE but
+ * length != n * PSTTFGenerator.MAX_BUFFER_SIZE is split up and the methods in PSTTFGenerator
+ * are invoked.
+ * @throws IOException file write error.
+ */
+ @Test
+ public void testStreamTable() throws IOException {
+ byte[] byteArray = new byte[PSTTFGenerator.MAX_BUFFER_SIZE * 3];
+ tableOut.streamTable(byteArray, 0, 10);
+ InOrder inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, 0, 10);
+ inOrder.verify(mockGen).endString();
+
+ setUp(); // reset all all the method calls
+ /* We're going to run this 3 times to ensure the proper method calls are invoked and all
+ * the bytes are streamed */
+ tableOut.streamTable(byteArray, 0, byteArray.length);
+ inOrder = inOrder(mockGen);
+ for (int i = 0; i < 3; i++) {
+ int offset = PSTTFGenerator.MAX_BUFFER_SIZE * i;
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, offset, PSTTFGenerator.MAX_BUFFER_SIZE);
+ inOrder.verify(mockGen).endString();
+ }
+
+ setUp(); // reset all the method calls
+ tableOut.streamTable(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE + 1);
+ inOrder = inOrder(mockGen);
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, 0, PSTTFGenerator.MAX_BUFFER_SIZE);
+ inOrder.verify(mockGen).endString();
+ inOrder.verify(mockGen).startString();
+ inOrder.verify(mockGen).streamBytes(byteArray, PSTTFGenerator.MAX_BUFFER_SIZE, 1);
+ inOrder.verify(mockGen).endString();
+ }
+}
diff --git a/test/java/org/apache/fop/svg/PDFGraphics2DTestCase.java b/test/java/org/apache/fop/svg/PDFGraphics2DTestCase.java
new file mode 100644
index 000000000..3f610c56f
--- /dev/null
+++ b/test/java/org/apache/fop/svg/PDFGraphics2DTestCase.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.svg;
+
+import java.awt.BasicStroke;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class PDFGraphics2DTestCase {
+
+ @Test
+ public void testApplyStrokeNullDash() {
+ PDFGraphics2D g2d = new PDFGraphics2D(false);
+ BasicStroke stroke = new BasicStroke();
+ g2d.applyStroke(stroke);
+ assertTrue(g2d.getString().contains("[] 0 d\n"));
+ }
+
+ @Test
+ public void testApplyStrokeNonNullDash() {
+ PDFGraphics2D g2d = new PDFGraphics2D(false);
+ float[] dashArray = {3.0f, 5.0f};
+ BasicStroke stroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
+ dashArray, 0.0f);
+ g2d.applyStroke(stroke);
+ assertTrue(g2d.getString().contains("[3 5] 0 d\n"));
+ }
+
+}
diff --git a/test/java/org/apache/fop/util/HexEncoderTestCase.java b/test/java/org/apache/fop/util/HexEncoderTestCase.java
new file mode 100644
index 000000000..cb366abdf
--- /dev/null
+++ b/test/java/org/apache/fop/util/HexEncoderTestCase.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test case for the conversion of characters into hex-encoded strings.
+ */
+public class HexEncoderTestCase {
+
+ /**
+ * Tests that characters are properly encoded into hex strings.
+ */
+ @Test
+ public void testEncodeChar() {
+ char[] digits = new char[] {'0', '0', '0', '0'};
+ for (int c = 0; c <= 0xFFFF; c++) {
+ assertEquals(new String(digits), HexEncoder.encode((char) c));
+ increment(digits);
+ }
+ }
+
+ private static void increment(char[] digits) {
+ int d = 4;
+ do {
+ d--;
+ digits[d] = successor(digits[d]);
+ } while (digits[d] == '0' && d > 0);
+ }
+
+ private static char successor(char d) {
+ if (d == '9') {
+ return 'A';
+ } else if (d == 'F') {
+ return '0';
+ } else {
+ return (char) (d + 1);
+ }
+ }
+
+}
diff --git a/test/pdf/accessibility/pdf/role.pdf b/test/pdf/accessibility/pdf/role.pdf
index 38fcf1bde..4dfb686c9 100644
--- a/test/pdf/accessibility/pdf/role.pdf
+++ b/test/pdf/accessibility/pdf/role.pdf
Binary files differ
diff --git a/test/pdf/accessibility/role.fo b/test/pdf/accessibility/role.fo
index 885638592..b94c6ab67 100644
--- a/test/pdf/accessibility/role.fo
+++ b/test/pdf/accessibility/role.fo
@@ -24,8 +24,8 @@
<fo:region-after extent="10pt"/>
</fo:simple-page-master>
</fo:layout-master-set>
- <fo:page-sequence master-reference="page" role="Art">
- <fo:static-content flow-name="xsl-region-after" role="NonStruct" font-size="8pt">
+ <fo:page-sequence master-reference="page" language="en" country="GB" role="Art">
+ <fo:static-content flow-name="xsl-region-after" role="artifact" font-size="8pt">
<fo:block text-align="center"><fo:page-number/></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body" role="NonStruct" hyphenate="true"
diff --git a/test/resources/fonts/ttf/DroidSansMono.LICENSE b/test/resources/fonts/ttf/DroidSansMono.LICENSE
new file mode 100644
index 000000000..1a96dfde6
--- /dev/null
+++ b/test/resources/fonts/ttf/DroidSansMono.LICENSE
@@ -0,0 +1,18 @@
+Copyright (C) 2008 The Android Open Source Project
+
+Licensed 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.
+
+##########
+
+This directory contains the fonts for the platform. They are licensed
+under the Apache 2 license.
diff --git a/test/resources/fonts/ttf/DroidSansMono.ttf b/test/resources/fonts/ttf/DroidSansMono.ttf
new file mode 100644
index 000000000..4546611d4
--- /dev/null
+++ b/test/resources/fonts/ttf/DroidSansMono.ttf
Binary files differ