aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml24
-rw-r--r--checkstyle-suppressions.xml3
-rw-r--r--findbugs-exclude.xml561
-rw-r--r--lib/batik-all-1.7.jarbin3318083 -> 0 bytes
-rw-r--r--lib/batik-all-trunk.jarbin0 -> 3313410 bytes
-rw-r--r--lib/fontbox-1.8.4-patched.jar (renamed from lib/fontbox-1.8.3-patched.jar)bin208340 -> 205376 bytes
-rw-r--r--lib/xmlgraphics-commons-svn-trunk.jarbin631241 -> 632370 bytes
-rw-r--r--src/codegen/fonts/Courier.xml501
-rw-r--r--src/codegen/fonts/CourierBold.xml501
-rw-r--r--src/codegen/fonts/CourierBoldOblique.xml499
-rw-r--r--src/codegen/fonts/CourierOblique.xml501
-rw-r--r--src/codegen/fonts/Helvetica.xml465
-rw-r--r--src/codegen/fonts/HelveticaBold.xml465
-rw-r--r--src/codegen/fonts/HelveticaBoldOblique.xml465
-rw-r--r--src/codegen/fonts/HelveticaOblique.xml467
-rw-r--r--src/codegen/fonts/Symbol.xml387
-rw-r--r--src/codegen/fonts/TimesBold.xml465
-rw-r--r--src/codegen/fonts/TimesBoldItalic.xml465
-rw-r--r--src/codegen/fonts/TimesItalic.xml467
-rw-r--r--src/codegen/fonts/TimesRoman.xml465
-rw-r--r--src/codegen/fonts/ZapfDingbats.xml412
-rw-r--r--src/codegen/fonts/font-file.xsl26
-rw-r--r--src/java/org/apache/fop/Version.java5
-rw-r--r--src/java/org/apache/fop/afp/AFPEventProducer.java8
-rw-r--r--src/java/org/apache/fop/afp/fonts/AFPFont.java32
-rw-r--r--src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java60
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java72
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java95
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java124
-rw-r--r--src/java/org/apache/fop/afp/fonts/DoubleByteFont.java34
-rw-r--r--src/java/org/apache/fop/afp/fonts/FopCharacterSet.java50
-rw-r--r--src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java71
-rw-r--r--src/java/org/apache/fop/afp/fonts/OutlineFont.java16
-rw-r--r--src/java/org/apache/fop/afp/fonts/RasterFont.java88
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java6
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPBridgeContext.java42
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java87
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextHandler.java36
-rw-r--r--src/java/org/apache/fop/afp/svg/AFPTextPainter.java21
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java17
-rw-r--r--src/java/org/apache/fop/area/inline/Container.java15
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java6
-rw-r--r--src/java/org/apache/fop/fo/FOText.java94
-rw-r--r--src/java/org/apache/fop/fo/flow/InlineContainer.java180
-rw-r--r--src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java3
-rw-r--r--src/java/org/apache/fop/fonts/Base14Font.java11
-rw-r--r--src/java/org/apache/fop/fonts/CustomFont.java47
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java37
-rw-r--r--src/java/org/apache/fop/fonts/FontMetrics.java44
-rw-r--r--src/java/org/apache/fop/fonts/GlyphMapping.java327
-rw-r--r--src/java/org/apache/fop/fonts/LazyFont.java26
-rw-r--r--src/java/org/apache/fop/fonts/MultiByteFont.java18
-rw-r--r--src/java/org/apache/fop/fonts/SingleByteFont.java40
-rw-r--r--src/java/org/apache/fop/fonts/TextFragment.java31
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OFFontLoader.java19
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OTFFile.java76
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java31
-rw-r--r--src/java/org/apache/fop/fonts/truetype/OpenFont.java46
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java8
-rw-r--r--src/java/org/apache/fop/fonts/type1/Type1FontLoader.java17
-rw-r--r--src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java7
-rw-r--r--src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java28
-rw-r--r--src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java24
-rw-r--r--src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java63
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java62
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java1
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutManager.java19
-rw-r--r--src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java12
-rw-r--r--src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java112
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java54
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java326
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml1
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java22
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java719
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java65
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java84
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java1
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java68
-rw-r--r--src/java/org/apache/fop/pdf/PDFProfile.java23
-rw-r--r--src/java/org/apache/fop/render/AbstractGenericSVGHandler.java4
-rw-r--r--src/java/org/apache/fop/render/afp/AFPSVGHandler.java16
-rw-r--r--src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java21
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java20
-rw-r--r--src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java5
-rw-r--r--src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java21
-rw-r--r--src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java38
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java2
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java31
-rw-r--r--src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java3
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java5
-rw-r--r--src/java/org/apache/fop/render/ps/PSSVGHandler.java3
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java361
-rw-r--r--src/java/org/apache/fop/render/rtf/RTFHandler.java6
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java2
-rw-r--r--src/java/org/apache/fop/svg/ACIUtils.java68
-rw-r--r--src/java/org/apache/fop/svg/AbstractFOPTextPainter.java331
-rw-r--r--src/java/org/apache/fop/svg/AbstractFOPTranscoder.java22
-rw-r--r--src/java/org/apache/fop/svg/NativeTextPainter.java147
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java47
-rw-r--r--src/java/org/apache/fop/svg/PDFTextPainter.java229
-rw-r--r--src/java/org/apache/fop/svg/PDFTextUtil.java41
-rw-r--r--src/java/org/apache/fop/svg/PDFTranscoder.java6
-rw-r--r--src/java/org/apache/fop/svg/SVGEventProducer.java9
-rw-r--r--src/java/org/apache/fop/svg/SVGEventProducer.xml1
-rw-r--r--src/java/org/apache/fop/svg/SVGUserAgent.java11
-rw-r--r--src/java/org/apache/fop/svg/SimpleSVGUserAgent.java12
-rw-r--r--src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java83
-rw-r--r--src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java31
-rw-r--r--src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java80
-rw-r--r--src/java/org/apache/fop/svg/font/FOPGVTFont.java159
-rw-r--r--src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java75
-rw-r--r--src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java339
-rw-r--r--src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java56
-rw-r--r--test/java/org/apache/fop/AbstractBasicTranscoderTest.java6
-rw-r--r--test/java/org/apache/fop/BasicDriverTestCase.java7
-rw-r--r--test/java/org/apache/fop/BasicDriverTestSuite.java2
-rw-r--r--test/java/org/apache/fop/BasicPSTranscoderTestCase.java1
-rw-r--r--test/java/org/apache/fop/DebugHelper.java5
-rw-r--r--test/java/org/apache/fop/DigestFilterTestCase.java7
-rw-r--r--test/java/org/apache/fop/KnuthAlgorithmTestCase.java1
-rw-r--r--test/java/org/apache/fop/URIResolutionTestCase.java5
-rw-r--r--test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java4
-rw-r--r--test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java4
-rw-r--r--test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java6
-rw-r--r--test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java12
-rw-r--r--test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java48
-rw-r--r--test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java9
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java11
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java4
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java3
-rw-r--r--test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java8
-rw-r--r--test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java7
-rw-r--r--test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java10
-rw-r--r--test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java9
-rw-r--r--test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java6
-rw-r--r--test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java9
-rw-r--r--test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java1
-rw-r--r--test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java12
-rw-r--r--test/java/org/apache/fop/apps/FopFactoryTestCase.java9
-rw-r--r--test/java/org/apache/fop/apps/PDFRendererConfBuilder.java2
-rw-r--r--test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java3
-rw-r--r--test/java/org/apache/fop/apps/io/FontURIResolver.java7
-rw-r--r--test/java/org/apache/fop/area/ViewportTest.java4
-rw-r--r--test/java/org/apache/fop/area/ViewportTestSuite.java3
-rw-r--r--test/java/org/apache/fop/area/inline/InlineViewportTestCase.java3
-rw-r--r--test/java/org/apache/fop/check/ChecksFactory.java2
-rw-r--r--test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java9
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java22
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java9
-rw-r--r--test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java2
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java11
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java20
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java20
-rw-r--r--test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java152
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java4
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java30
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java18
-rw-r--r--test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java21
-rw-r--r--test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java68
-rw-r--r--test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java4
-rw-r--r--test/java/org/apache/fop/config/FontAttributesMissingTestCase.java1
-rw-r--r--test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java1
-rw-r--r--test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java1
-rw-r--r--test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java1
-rw-r--r--test/java/org/apache/fop/config/FontsAutoDetectTestCase.java1
-rw-r--r--test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java1
-rw-r--r--test/java/org/apache/fop/datatypes/URISpecificationTestCase.java4
-rw-r--r--test/java/org/apache/fop/events/BasicEventTestCase.java3
-rw-r--r--test/java/org/apache/fop/events/EventChecker.java8
-rw-r--r--test/java/org/apache/fop/events/TestEventProducer.java5
-rw-r--r--test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java4
-rw-r--r--test/java/org/apache/fop/fo/FODocumentParser.java2
-rw-r--r--test/java/org/apache/fop/fo/FONodeMocks.java3
-rw-r--r--test/java/org/apache/fop/fo/flow/MarkersTestCase.java4
-rw-r--r--test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java2
-rw-r--r--test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java6
-rw-r--r--test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java10
-rw-r--r--test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java4
-rw-r--r--test/java/org/apache/fop/fo/flow/table/TableHandler.java1
-rw-r--r--test/java/org/apache/fop/fo/pagination/AllTests.java4
-rw-r--r--test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java6
-rw-r--r--test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java4
-rw-r--r--test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java4
-rw-r--r--test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java8
-rw-r--r--test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java17
-rw-r--r--test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java2
-rw-r--r--test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java9
-rw-r--r--test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java6
-rw-r--r--test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java8
-rw-r--r--test/java/org/apache/fop/fonts/svg-fonts.fo37
-rw-r--r--test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java2
-rw-r--r--test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java7
-rw-r--r--test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java293
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java22
-rw-r--r--test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java6
-rw-r--r--test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java15
-rw-r--r--test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java4
-rw-r--r--test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java8
-rw-r--r--test/java/org/apache/fop/fonts/type1/underline.afm4
-rw-r--r--test/java/org/apache/fop/fotreetest/ext/AssertElement.java6
-rw-r--r--test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java2
-rw-r--r--test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java8
-rw-r--r--test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java6
-rw-r--r--test/java/org/apache/fop/intermediate/AbstractIFTest.java1
-rw-r--r--test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java2
-rw-r--r--test/java/org/apache/fop/intermediate/IFMimickingTestCase.java4
-rw-r--r--test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java2
-rw-r--r--test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java2
-rw-r--r--test/java/org/apache/fop/layoutengine/ElementListCheck.java9
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java107
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java2
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java2
-rw-r--r--test/java/org/apache/fop/layoutengine/LayoutResult.java3
-rw-r--r--test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java8
-rw-r--r--test/java/org/apache/fop/logging/LoggingElementListObserver.java3
-rw-r--r--test/java/org/apache/fop/memory/MemoryEater.java4
-rw-r--r--test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java3
-rw-r--r--test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java10
-rw-r--r--test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/ObjectStreamTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/PDFAModeTestCase.java10
-rw-r--r--test/java/org/apache/fop/pdf/PDFArrayTestCase.java14
-rw-r--r--test/java/org/apache/fop/pdf/PDFDestsTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java11
-rw-r--r--test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/PDFDocumentTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFEncodingTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java8
-rw-r--r--test/java/org/apache/fop/pdf/PDFFactoryTestCase.java2
-rw-r--r--test/java/org/apache/fop/pdf/PDFFilterListTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/PDFNameTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFNullTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFNumberTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/PDFObjectTestCase.java10
-rw-r--r--test/java/org/apache/fop/pdf/PDFRectangleTestCase.java8
-rw-r--r--test/java/org/apache/fop/pdf/PDFReferenceTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/PDFStreamTestCase.java10
-rw-r--r--test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/VersionControllerTestCase.java6
-rw-r--r--test/java/org/apache/fop/pdf/VersionTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java4
-rw-r--r--test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java4
-rw-r--r--test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/AbstractRenderingTest.java1
-rw-r--r--test/java/org/apache/fop/render/RawPNGTestUtil.java8
-rw-r--r--test/java/org/apache/fop/render/RendererFactoryTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java13
-rw-r--r--test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java7
-rw-r--r--test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/afp/NoOperationTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java9
-rw-r--r--test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java9
-rw-r--r--test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java7
-rw-r--r--test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java2
-rw-r--r--test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java2
-rw-r--r--test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java16
-rw-r--r--test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java9
-rw-r--r--test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java22
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java16
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java8
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java7
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java4
-rw-r--r--test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java4
-rw-r--r--test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java11
-rw-r--r--test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/ps/PSPainterTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java10
-rw-r--r--test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java4
-rw-r--r--test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java6
-rw-r--r--test/java/org/apache/fop/render/rtf/Bug39607TestCase.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java10
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java2
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java8
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java8
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java5
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java5
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java3
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java8
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java5
-rw-r--r--test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java3
-rw-r--r--test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java7
-rw-r--r--test/java/org/apache/fop/svg/NativeTextPainterTest.java78
-rw-r--r--test/java/org/apache/fop/svg/OperatorValidator.java108
-rw-r--r--test/java/org/apache/fop/svg/PDFTextPainterTestCase.java148
-rw-r--r--test/java/org/apache/fop/svg/PSTextPainterTestCase.java77
-rw-r--r--test/java/org/apache/fop/svg/baseline-shift.svg9
-rw-r--r--test/java/org/apache/fop/svg/dx-dy.svg8
-rw-r--r--test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java193
-rw-r--r--test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java127
-rw-r--r--test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java71
-rw-r--r--test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java27
-rw-r--r--test/java/org/apache/fop/svg/font/FontInfoBuilder.java102
-rw-r--r--test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java91
-rw-r--r--test/java/org/apache/fop/svg/glyph-orientation.svg10
-rw-r--r--test/java/org/apache/fop/svg/rotated-glyph.svg5
-rw-r--r--test/java/org/apache/fop/svg/spacing.svg21
-rw-r--r--test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java4
-rw-r--r--test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java4
-rw-r--r--test/java/org/apache/fop/threading/FOProcessorImpl.java4
-rw-r--r--test/java/org/apache/fop/threading/Main.java5
-rw-r--r--test/java/org/apache/fop/traits/BorderPropsTestCase.java6
-rw-r--r--test/java/org/apache/fop/traits/MinOptMaxTestCase.java4
-rw-r--r--test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java9
-rw-r--r--test/java/org/apache/fop/util/BitmapImageUtilTestCase.java13
-rw-r--r--test/java/org/apache/fop/util/ColorUtilTestCase.java10
-rw-r--r--test/java/org/apache/fop/util/DigestFilter.java3
-rw-r--r--test/java/org/apache/fop/util/ElementListUtilsTestCase.java7
-rw-r--r--test/java/org/apache/fop/util/LanguageTagsTestCase.java4
-rw-r--r--test/java/org/apache/fop/util/XMLResourceBundleTestCase.java6
-rw-r--r--test/java/org/apache/fop/visual/BitmapComparator.java20
-rw-r--r--test/java/org/apache/fop/visual/ConvertUtils.java5
-rw-r--r--test/layoutengine/disabled-testcases.xml13
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml244
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml74
-rw-r--r--test/layoutengine/standard-testcases/inline-container_alignment.xml154
-rw-r--r--test/layoutengine/standard-testcases/inline-container_basic.xml56
-rw-r--r--test/layoutengine/standard-testcases/inline-container_block_nested.xml65
-rw-r--r--test/layoutengine/standard-testcases/inline-container_bpd.xml72
-rw-r--r--test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml74
-rw-r--r--test/layoutengine/standard-testcases/inline-container_ipd-auto.xml66
-rw-r--r--test/layoutengine/standard-testcases/inline-container_ipd-percent.xml61
-rw-r--r--test/layoutengine/standard-testcases/inline-container_keeps.xml49
-rw-r--r--test/layoutengine/testcase2checks.xsl9
-rw-r--r--test/xml/pdf-a/svg-transparency.fo24
352 files changed, 10664 insertions, 6460 deletions
diff --git a/build.xml b/build.xml
index f25239bc0..ba9f2e09b 100644
--- a/build.xml
+++ b/build.xml
@@ -563,14 +563,17 @@ list of possible build targets.
<include name="org/apache/fop/apps/Fop.class"/>
<include name="org/apache/fop/apps/FOPException.class"/>
<include name="org/apache/fop/apps/io/**"/>
+ <include name="org/apache/fop/area/AreaTreeControl*"/>
<include name="org/apache/fop/complexscripts/fonts/*.class"/>
<include name="org/apache/fop/complexscripts/util/GlyphTester.class"/>
+ <include name="org/apache/fop/events/EventProducer.class"/>
<include name="org/apache/fop/fo/Constants.class"/>
<include name="org/apache/fop/fo/FOTreeBuilder.class"/>
- <include name="org/apache/fop/area/AreaTreeControl*"/>
+ <include name="org/apache/fop/image/loader/batik/BatikImageFlavors*.class"/>
<include name="org/apache/fop/svg/**"/>
<include name="org/apache/fop/fonts/**"/>
- <include name="org/apache/fop/image/loader/batik/BatikImageFlavors*.class"/>
+ <include name="org/apache/fop/render/shading/**"/>
+ <include name="org/apache/fop/traits/MinOptMax.class"/>
<include name="org/apache/fop/util/CMYKColorSpace*.class"/>
<include name="org/apache/fop/util/Color*.class"/>
<include name="org/apache/fop/util/ASCII*.class"/>
@@ -579,7 +582,7 @@ list of possible build targets.
<include name="org/apache/fop/util/Finalizable.class"/>
<include name="org/apache/fop/util/CharUtilities.class"/>
<include name="org/apache/fop/util/DecimalFormatCache*.class"/>
- <include name="org/apache/fop/render/shading/**"/>
+ <include name="org/apache/fop/util/ImageObject.class"/>
</patternset>
<!-- PDF transcoder -->
<patternset>
@@ -648,7 +651,8 @@ list of possible build targets.
<include name="org/apache/xmlgraphics/java2d/**"/>
<include name="org/apache/xmlgraphics/ps/**"/>
<include name="org/apache/xmlgraphics/fonts/**"/>
- <include name="org/apache/xmlgraphics/util/io/**"/>
+ <include name="org/apache/xmlgraphics/util/**"/>
+ <include name="org/apache/xmlgraphics/image/loader/**"/>
</patternset>
<fileset refid="transcoder-lib-files"/>
</unjar>
@@ -710,6 +714,7 @@ list of possible build targets.
<include name="**/*.txt"/>
<include name="**/*.afm"/>
<include name="**/*.fo"/>
+ <include name="**/*.svg"/>
</fileset>
</copy>
</target>
@@ -1042,10 +1047,8 @@ NOTE:
<!-- Checkstyle -->
<!-- =================================================================== -->
<property name="checkstyle.location" value="${lib-tools}/checkstyle-5.5-all.jar" />
- <property name="checkstyle.noframes.xslt" value="${basedir}/checkstyle-noframes.xsl" />
<property name="checkstyle.config" value="${basedir}/checkstyle-5.5.xml" />
<path id="checkstyle-classpath">
- <path refid="libs-build-classpath"/>
<pathelement location="${checkstyle.location}"/>
</path>
<condition property="checkstyle.avail">
@@ -1053,20 +1056,18 @@ NOTE:
<available classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
<classpath refid="checkstyle-classpath"/>
</available>
- <available file="${checkstyle.noframes.xslt}"/>
<available file="${checkstyle.config}"/>
</and>
</condition>
<target name="checkstyle-avail" unless="checkstyle.avail">
<echo message="Checkstyle support NOT present. Please download it from http://checkstyle.sf.net/ and"/>
<echo message="... please provide ${checkstyle.location}"/>
- <echo message="... please provide ${checkstyle.noframes.xslt}"/>
<echo message="... please provide ${checkstyle.config}"/>
</target>
<target name="checkstyle" depends="package, checkstyle-avail" if="checkstyle.avail" description="Runs Checkstyle for a code quality report">
<taskdef name="checkstyle" classname="com.puppycrawl.tools.checkstyle.CheckStyleTask" classpathref="checkstyle-classpath"/>
<mkdir dir="${build.dir}"/>
- <checkstyle config="${checkstyle.config}" failonviolation="false">
+ <checkstyle config="${checkstyle.config}" failonviolation="true" maxWarnings="0">
<classpath>
<path refid="checkstyle-classpath"/>
<pathelement location="${build.classes.dir}"/>
@@ -1074,9 +1075,10 @@ NOTE:
<pathelement location="${build.codegen-classes.dir}"/>
</classpath>
<fileset dir="${src.dir}" includes="**/*.java"/>
+ <fileset dir="${test.dir}" includes="**/*.java"/>
<formatter type="xml" toFile="${build.dir}/report_checkstyle.xml"/>
+ <formatter type="plain"/>
</checkstyle>
- <xslt in="${build.dir}/report_checkstyle.xml" out="${build.dir}/report_checkstyle.html" style="${checkstyle.noframes.xslt}"/>
</target>
<!-- =================================================================== -->
<!-- PMD -->
@@ -1507,7 +1509,7 @@ NOTE:
<!-- Special target for Gump -->
<!-- =================================================================== -->
<target name="gump" depends="package,transcoder-pkg"/>
- <target name="gump-test" depends="junit-all">
+ <target name="gump-test" depends="junit-all,checkstyle">
<fail>
<condition>
<or>
diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml
index 7dc583dbb..050f5dab4 100644
--- a/checkstyle-suppressions.xml
+++ b/checkstyle-suppressions.xml
@@ -6,4 +6,7 @@
<suppress files="org/apache/fop/complexscripts/bidi/GenerateBidiTestData.java" checks="SimplifyBooleanReturn"/>
<suppress files="org/apache/fop/complexscripts/scripts/ArabicScriptProcessor.java" checks="SimplifyBooleanReturn"/>
<suppress files="org/apache/fop/complexscripts/util/CharScript.java" checks="SimplifyBooleanReturn"/>
+ <suppress files="org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java" checks="AvoidNestedBlocks"/>
+ <suppress files="org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java" checks="AvoidNestedBlocks"/>
+ <suppress files="org/apache/fop/fo/flow/MarkersTestCase.java" checks="LocalVariableName"/>
</suppressions>
diff --git a/findbugs-exclude.xml b/findbugs-exclude.xml
index 46e6e1675..4dc4cb10b 100644
--- a/findbugs-exclude.xml
+++ b/findbugs-exclude.xml
@@ -1,6 +1,567 @@
<?xml version="1.0" encoding="utf-8"?>
<FindBugsFilter>
<Match>
+ <Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.afp.AFPStreamer"/>
+ <Method name="close"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.area.Page"/>
+ <Method name="isEmpty"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.area.PageViewport"/>
+ <Method name="getBodyRegion"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.area.inline.InlineArea"/>
+ <Method name="notifyIPDVariation"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.area.inline.TextArea"/>
+ <Method name="getText"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.BlockStackingLayoutManager"/>
+ <Or>
+ <Method name="discardSpace"/>
+ <Method name="negotiateBPDAdjustment"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.FlowLayoutManager"/>
+ <Or>
+ <Method name="discardSpace"/>
+ <Method name="negotiateBPDAdjustment"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.PageBreakingAlgorithm"/>
+ <Or>
+ <Method name="createFootnotePages"/>
+ <Method name="finish"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.PageSequenceLayoutManager"/>
+ <Method name="activateLayout"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.LineLayoutManager"/>
+ <Or>
+ <Method name="getChangedKnuthElements"/>
+ <Method name="negotiateBPDAdjustment"/>
+ <Method name="postProcessLineBreaks"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.TextLayoutManager"/>
+ <Or>
+ <Method name="addALetterSpaceTo"/>
+ <Method name="addAreas"/>
+ <Method name="applyChanges"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.table.RowPainter"/>
+ <Method name="addAreasAndFlushRow"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.table.TableStepper"/>
+ <Method name="activateCells"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.AbstractRenderer"/>
+ <Method name="renderRegionViewport"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPImageHandler"/>
+ <Method name="generateDataObjectInfo"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPImageHandlerGraphics2D"/>
+ <Method name="handleImage"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPImageHandlerRawJPEG"/>
+ <Method name="handleImage"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPImageHandlerRenderedImage"/>
+ <Method name="handleImage"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPImageHandlerSVG"/>
+ <Method name="handleImage"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.intermediate.IFParser"/>
+ <Method name="parse"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.intermediate.IFParser$Handler"/>
+ <Method name="handleIFException"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.intermediate.IFRenderer"/>
+ <Or>
+ <Method name="handleIFExceptionWithIOException"/>
+ <Method name="renderSpace"/>
+ <Method name="renderWord"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.pdf.PDFRenderingUtil"/>
+ <Or>
+ <Method name="populateArray"/>
+ <Method name="populateDictionary"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.pdf.extensions.PDFArrayElement"/>
+ <Method name="getArrayExtension"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.pdf.extensions.PDFDictionaryElement"/>
+ <Method name="getDictionaryExtension"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.pdf.extensions.PDFReferenceElement"/>
+ <Method name="processNode"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.xml.XMLRenderer"/>
+ <Method name="renderRegionViewport"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.svg.PDFGraphics2D"/>
+ <Method name="applyUnknownPaint"/>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="DM_DEFAULT_ENCODING"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.afp.fonts.CharacterSet"/>
+ <Or>
+ <Method name="getNameBytes"/>
+ <Method name="getBytes"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.afp.modca.AbstractNamedAFPObject"/>
+ <Or>
+ <Method name="getNameBytes"/>
+ <Method name="getBytes"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.afp.modca.triplets.AttributeValueTriplet"/>
+ <Or>
+ <Method name="writeToStream"/>
+ <Method name="getBytes"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fonts.autodetect.WindowsFontDirFinder"/>
+ <Or>
+ <Method name="getWinDir"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.hyphenation.HyphenationTree"/>
+ <Or>
+ <Method name="main"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.pdf.PDFDocument"/>
+ <Or>
+ <Method name="encode"/>
+ <Method name="getBytes"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.AFPPainter$AFPBorderPainterAdapter"/>
+ <Or>
+ <Method name="hash"/>
+ <Method name="getBytes"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.rtf.RTFHandler"/>
+ <Or>
+ <Method name="startDocument"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile"/>
+ <Or>
+ <Method name="main"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.tools.anttasks.FileCompare"/>
+ <Or>
+ <Method name="execute"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="FE_FLOATING_POINT_EQUALITY"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.afp.modca.GraphicsObject"/>
+ <Method name="setLineWidth"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fonts.type1.AFMFile"/>
+ <Method name="overridePrimaryEncoding"/>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="BC_BAD_CAST_TO_CONCRETE_COLLECTION"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.area.AreaTreeObject"/>
+ <Or>
+ <Field name="extensionAttachments"/>
+ <Field name="foreignAttributes"/>
+ <Method name="clone"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.complexscripts.fonts.GlyphPositioningTable"/>
+ <Or>
+ <Method name="position"/>
+ <Method name="matchLookups"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable"/>
+ <Or>
+ <Method name="substitute"/>
+ <Method name="matchLookups"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.complexscripts.fonts.OTFAdvancedTypographicTableReader"/>
+ <Or>
+ <Method name="constructGDEF"/>
+ <Method name="constructGDEFSubtables"/>
+ <Method name="constructGPOS"/>
+ <Method name="constructLookups"/>
+ <Method name="constructGPOSSubtables"/>
+ <Method name="constructGSUB"/>
+ <Method name="constructGSUBSubtables"/>
+ <Method name="readChainedContextualPosTableFormat3"/>
+ <Method name="readChainedContextualSubTableFormat3"/>
+ <Method name="readContextualPosTableFormat3"/>
+ <Method name="readContextualSubTableFormat3"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.complexscripts.util.GlyphSequence$CharAssociation"/>
+ <Or>
+ <Field name="predications"/>
+ <Method name="join"/>
+ <Method name="extractIntervals"/>
+ <Method name="mergePredication"/>
+ <Method name="setPredication"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fonts.apps.PFMReader"/>
+ <Or>
+ <Method name="main"/>
+ <Method name="loadPFM"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fonts.substitute.FontQualifier"/>
+ <Or>
+ <Method name="setFontStyle"/>
+ <Method name="valueOf"/>
+ <Method name="setFontWeight"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.hyphenation.Hyphenator"/>
+ <Or>
+ <Method name="getResourceStream"/>
+ <Method name="getMethod"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.hyphenation.PatternParser"/>
+ <Or>
+ <Method name="main"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.pdf.PDFMetadata"/>
+ <Or>
+ <Method name="populateStreamDict"/>
+ <Method name="buildFilterDictEntries"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.AbstractRenderer"/>
+ <Or>
+ <Method name="renderBodyRegion"/>
+ <Method name="getBeforeFloat"/>
+ <Method name="getFootnote"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.extensions.AFPExtensionHandler"/>
+ <Or>
+ <Method name="endElement"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.pdf.extensions.PDFEmbeddedFileElement"/>
+ <Or>
+ <Method name="processNode"/>
+ <Method name="getURL"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.util.ColorUtil"/>
+ <Or>
+ <Method name="parseAsFopRgbIcc"/>
+ <Method name="trim"/>
+ <Method name="parseAsFopRgbNamedColor"/>
+ <Method name="unescapeString"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.util.XMLUtil"/>
+ <Or>
+ <Method name="decodePositionAdjustments"/>
+ <Method name="split"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.complexscripts.fonts.GlyphProcessingState"/>
+ <Field name="classMatchSet"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fo.XMLWhiteSpaceHandler$PendingInline"/>
+ <Field name="fo"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.InlineStackingLayoutManager"/>
+ <Field name="extraBPD"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.table.TableRowIterator"/>
+ <Field name="table"/>
+ </And>
+ <And>
+ <Class name="org.apache.fop.pdf.PDFCMap"/>
+ <Or>
+ <Field name="base"/>
+ <Field name="sysInfo"/>
+ <Field name="wMode"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic"/>
+ <Or>
+ <Field name="heightPercent"/>
+ <Field name="widthPercent"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.fo.XMLObj"/>
+ <Or>
+ <Field name="doc"/>
+ <Field name="element"/>
+ <Method name="characters"/>
+ <Method name="getDimension"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fo.flow.table.TableCellContainer"/>
+ <Or>
+ <Field name="pendingSpans"/>
+ <Method name="addTableCellChild"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fo.pagination.AbstractPageSequence"/>
+ <Or>
+ <Field name="initialPageNumber"/>
+ <Method name="initPageNumber"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.afp.extensions.AbstractAFPExtensionObject"/>
+ <Or>
+ <Field name="extensionAttachment"/>
+ <Method name="processNode"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler"/>
+ <Or>
+ <Field name="outputStream"/>
+ <Method name="rewritePostScriptFile"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.java2d.Java2DSVGHandler$Java2DInfo"/>
+ <Or>
+ <Field name="state"/>
+ <Method name="renderSVGDocument"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="SBSC_USE_STRINGBUFFER_CONCATENATION"/>
+ <And>
+ <Class name="org.apache.fop.fo.properties.GenericShorthandParser"/>
+ <Method name="convertValueForProperty"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="EI_EXPOSE_REP2"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.fonts.GlyphMapping"/>
+ <Or>
+ <Field name="gposAdjustments"/>
+ <Method name="&lt;init&gt;"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.fonts.MultiByteFont"/>
+ <Or>
+ <Field name="boundingBoxes"/>
+ <Method name="setBBoxArray"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="OS_OPEN_STREAM_EXCEPTION_PATH"/>
+ <And>
+ <Class name="org.apache.fop.hyphenation.SerializeHyphPattern"/>
+ <Method name="serializeFile"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="BC_UNCONFIRMED_CAST"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.PageBreakingAlgorithm"/>
+ <Or>
+ <Field name="best"/>
+ <Field name="next"/>
+ <Method name="createNode"/>
+ <Method name="finish"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.ContentLayoutManager"/>
+ <Or>
+ <Field name="holder"/>
+ <Method name="addAreas"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.PageNumberLayoutManager"/>
+ <Or>
+ <Field name="curArea"/>
+ <Method name="getEffectiveArea"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFontTable"/>
+ <Or>
+ <Field name="parent"/>
+ <Method name="writeRtfContent"/>
+ </Or>
+ </And>
+ <And>
+ <Class name="org.apache.fop.svg.PDFGraphics2D"/>
+ <Method name="registerFunction"/>
+ </And>
+ </Or>
+ </Match>
+ <Match>
+ <Bug pattern="PZLA_PREFER_ZERO_LENGTH_ARRAYS"/>
+ <And>
+ <Class name="org.apache.fop.layoutmgr.inline.TextLayoutManager$TextAreaBuilder"/>
+ <Method name="getMappingBidiLevels"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="NP_LOAD_OF_KNOWN_NULL_VALUE"/>
+ <And>
+ <Class name="org.apache.fop.pdf.PDFFactory"/>
+ <Method name="makeFontFile"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="SE_BAD_FIELD"/>
+ <And>
+ <Class name="org.apache.fop.render.awt.viewer.ImageProxyPanel"/>
+ <Field name="imageRef"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="SE_BAD_FIELD_STORE"/>
+ <And>
+ <Class name="org.apache.fop.render.awt.viewer.ImageProxyPanel"/>
+ <Field name="imageRef"/>
+ </And>
+ </Match>
+ <Match>
+ <Bug pattern="RC_REF_COMPARISON_BAD_PRACTICE"/>
+ <Or>
+ <And>
+ <Class name="org.apache.fop.render.xml.XMLRenderer"/>
+ <Or>
+ <Field name="END_INDENT"/>
+ <Field name="FONT"/>
+ <Field name="START_INDENT"/>
+ <Method name="addTraitAttributes"/>
+ </Or>
+ </And>
+ </Or>
+ </Match>
+
+ <Match>
<Class name="org.apache.fop.fonts.truetype.OpenFont$1"/>
<Bug pattern="SIC_INNER_SHOULD_BE_STATIC_ANON"/>
</Match>
diff --git a/lib/batik-all-1.7.jar b/lib/batik-all-1.7.jar
deleted file mode 100644
index 589328581..000000000
--- a/lib/batik-all-1.7.jar
+++ /dev/null
Binary files differ
diff --git a/lib/batik-all-trunk.jar b/lib/batik-all-trunk.jar
new file mode 100644
index 000000000..08c1a383a
--- /dev/null
+++ b/lib/batik-all-trunk.jar
Binary files differ
diff --git a/lib/fontbox-1.8.3-patched.jar b/lib/fontbox-1.8.4-patched.jar
index 57460be06..f608b4409 100644
--- a/lib/fontbox-1.8.3-patched.jar
+++ b/lib/fontbox-1.8.4-patched.jar
Binary files differ
diff --git a/lib/xmlgraphics-commons-svn-trunk.jar b/lib/xmlgraphics-commons-svn-trunk.jar
index b85214c10..64768ff23 100644
--- a/lib/xmlgraphics-commons-svn-trunk.jar
+++ b/lib/xmlgraphics-commons-svn-trunk.jar
Binary files differ
diff --git a/src/codegen/fonts/Courier.xml b/src/codegen/fonts/Courier.xml
index be977e22e..075699427 100644
--- a/src/codegen/fonts/Courier.xml
+++ b/src/codegen/fonts/Courier.xml
@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>Courier</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>426</x-height>
<ascender>629</ascender>
<descender>-157</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="600"/>
- <char name="AE" width="600"/>
- <char name="Aacute" width="600"/>
- <char name="Acircumflex" width="600"/>
- <char name="Adieresis" width="600"/>
- <char name="Agrave" width="600"/>
- <char name="Aring" width="600"/>
- <char name="Atilde" width="600"/>
- <char name="B" width="600"/>
- <char name="C" width="600"/>
- <char name="Ccedilla" width="600"/>
- <char name="D" width="600"/>
- <char name="E" width="600"/>
- <char name="Eacute" width="600"/>
- <char name="Ecircumflex" width="600"/>
- <char name="Edieresis" width="600"/>
- <char name="Egrave" width="600"/>
- <char name="Eth" width="600"/>
- <char name="Euro" width="600"/>
- <char name="F" width="600"/>
- <char name="G" width="600"/>
- <char name="Gcaron" width="600"/>
- <char name="H" width="600"/>
- <char name="I" width="600"/>
- <char name="IJ" width="600"/>
- <char name="Iacute" width="600"/>
- <char name="Icircumflex" width="600"/>
- <char name="Idieresis" width="600"/>
- <char name="Idot" width="600"/>
- <char name="Igrave" width="600"/>
- <char name="J" width="600"/>
- <char name="K" width="600"/>
- <char name="L" width="600"/>
- <char name="LL" width="600"/>
- <char name="Lslash" width="600"/>
- <char name="M" width="600"/>
- <char name="N" width="600"/>
- <char name="Ntilde" width="600"/>
- <char name="O" width="600"/>
- <char name="OE" width="600"/>
- <char name="Oacute" width="600"/>
- <char name="Ocircumflex" width="600"/>
- <char name="Odieresis" width="600"/>
- <char name="Ograve" width="600"/>
- <char name="Oslash" width="600"/>
- <char name="Otilde" width="600"/>
- <char name="P" width="600"/>
- <char name="Q" width="600"/>
- <char name="R" width="600"/>
- <char name="S" width="600"/>
- <char name="Scaron" width="600"/>
- <char name="Scedilla" width="600"/>
- <char name="T" width="600"/>
- <char name="Thorn" width="600"/>
- <char name="U" width="600"/>
- <char name="Uacute" width="600"/>
- <char name="Ucircumflex" width="600"/>
- <char name="Udieresis" width="600"/>
- <char name="Ugrave" width="600"/>
- <char name="V" width="600"/>
- <char name="W" width="600"/>
- <char name="X" width="600"/>
- <char name="Y" width="600"/>
- <char name="Yacute" width="600"/>
- <char name="Ydieresis" width="600"/>
- <char name="Z" width="600"/>
- <char name="Zcaron" width="600"/>
- <char name="a" width="600"/>
- <char name="aacute" width="600"/>
- <char name="acircumflex" width="600"/>
- <char name="acute" width="600"/>
- <char name="adieresis" width="600"/>
- <char name="ae" width="600"/>
- <char name="agrave" width="600"/>
- <char name="ampersand" width="600"/>
- <char name="aring" width="600"/>
- <char name="arrowboth" width="600"/>
- <char name="arrowdown" width="600"/>
- <char name="arrowleft" width="600"/>
- <char name="arrowright" width="600"/>
- <char name="arrowup" width="600"/>
- <char name="asciicircum" width="600"/>
- <char name="asciitilde" width="600"/>
- <char name="asterisk" width="600"/>
- <char name="at" width="600"/>
- <char name="atilde" width="600"/>
- <char name="b" width="600"/>
- <char name="backslash" width="600"/>
- <char name="bar" width="600"/>
- <char name="braceleft" width="600"/>
- <char name="braceright" width="600"/>
- <char name="bracketleft" width="600"/>
- <char name="bracketright" width="600"/>
- <char name="breve" width="600"/>
- <char name="brokenbar" width="600"/>
- <char name="bullet" width="600"/>
- <char name="c" width="600"/>
- <char name="caron" width="600"/>
- <char name="ccedilla" width="600"/>
- <char name="cedilla" width="600"/>
- <char name="cent" width="600"/>
- <char name="center" width="600"/>
- <char name="circumflex" width="600"/>
- <char name="colon" width="600"/>
- <char name="comma" width="600"/>
- <char name="copyright" width="600"/>
- <char name="currency" width="600"/>
- <char name="d" width="600"/>
- <char name="dagger" width="600"/>
- <char name="daggerdbl" width="600"/>
- <char name="dectab" width="600"/>
- <char name="degree" width="600"/>
- <char name="dieresis" width="600"/>
- <char name="divide" width="600"/>
- <char name="dollar" width="600"/>
- <char name="dotaccent" width="600"/>
- <char name="dotlessi" width="600"/>
- <char name="down" width="600"/>
- <char name="e" width="600"/>
- <char name="eacute" width="600"/>
- <char name="ecircumflex" width="600"/>
- <char name="edieresis" width="600"/>
- <char name="egrave" width="600"/>
- <char name="eight" width="600"/>
- <char name="ellipsis" width="600"/>
- <char name="emdash" width="600"/>
- <char name="endash" width="600"/>
- <char name="equal" width="600"/>
- <char name="eth" width="600"/>
- <char name="exclam" width="600"/>
- <char name="exclamdown" width="600"/>
- <char name="f" width="600"/>
- <char name="fi" width="600"/>
- <char name="five" width="600"/>
- <char name="fl" width="600"/>
- <char name="florin" width="600"/>
- <char name="format" width="600"/>
- <char name="four" width="600"/>
- <char name="fraction" width="600"/>
- <char name="g" width="600"/>
- <char name="gcaron" width="600"/>
- <char name="germandbls" width="600"/>
- <char name="grave" width="600"/>
- <char name="graybox" width="600"/>
- <char name="greater" width="600"/>
- <char name="guillemotleft" width="600"/>
- <char name="guillemotright" width="600"/>
- <char name="guilsinglleft" width="600"/>
- <char name="guilsinglright" width="600"/>
- <char name="h" width="600"/>
- <char name="hungarumlaut" width="600"/>
- <char name="hyphen" width="600"/>
- <char name="i" width="600"/>
- <char name="iacute" width="600"/>
- <char name="icircumflex" width="600"/>
- <char name="idieresis" width="600"/>
- <char name="igrave" width="600"/>
- <char name="ij" width="600"/>
- <char name="indent" width="600"/>
- <char name="j" width="600"/>
- <char name="k" width="600"/>
- <char name="l" width="600"/>
- <char name="largebullet" width="600"/>
- <char name="left" width="600"/>
- <char name="less" width="600"/>
- <char name="lira" width="600"/>
- <char name="ll" width="600"/>
- <char name="logicalnot" width="600"/>
- <char name="lslash" width="600"/>
- <char name="m" width="600"/>
- <char name="macron" width="600"/>
- <char name="merge" width="600"/>
- <char name="minus" width="600"/>
- <char name="mu" width="600"/>
- <char name="multiply" width="600"/>
- <char name="n" width="600"/>
- <char name="nine" width="600"/>
- <char name="notegraphic" width="600"/>
- <char name="ntilde" width="600"/>
- <char name="numbersign" width="600"/>
- <char name="o" width="600"/>
- <char name="oacute" width="600"/>
- <char name="ocircumflex" width="600"/>
- <char name="odieresis" width="600"/>
- <char name="oe" width="600"/>
- <char name="ogonek" width="600"/>
- <char name="ograve" width="600"/>
- <char name="one" width="600"/>
- <char name="onehalf" width="600"/>
- <char name="onequarter" width="600"/>
- <char name="onesuperior" width="600"/>
- <char name="ordfeminine" width="600"/>
- <char name="ordmasculine" width="600"/>
- <char name="oslash" width="600"/>
- <char name="otilde" width="600"/>
- <char name="overscore" width="600"/>
- <char name="p" width="600"/>
- <char name="paragraph" width="600"/>
- <char name="parenleft" width="600"/>
- <char name="parenright" width="600"/>
- <char name="percent" width="600"/>
- <char name="period" width="600"/>
- <char name="periodcentered" width="600"/>
- <char name="perthousand" width="600"/>
- <char name="plus" width="600"/>
- <char name="plusminus" width="600"/>
- <char name="prescription" width="600"/>
- <char name="q" width="600"/>
- <char name="question" width="600"/>
- <char name="questiondown" width="600"/>
- <char name="quotedbl" width="600"/>
- <char name="quotedblbase" width="600"/>
- <char name="quotedblleft" width="600"/>
- <char name="quotedblright" width="600"/>
- <char name="quoteleft" width="600"/>
- <char name="quoteright" width="600"/>
- <char name="quotesinglbase" width="600"/>
- <char name="quotesingle" width="600"/>
- <char name="r" width="600"/>
- <char name="registered" width="600"/>
- <char name="return" width="600"/>
- <char name="ring" width="600"/>
- <char name="s" width="600"/>
- <char name="scaron" width="600"/>
- <char name="scedilla" width="600"/>
- <char name="section" width="600"/>
- <char name="semicolon" width="600"/>
- <char name="seven" width="600"/>
- <char name="six" width="600"/>
- <char name="slash" width="600"/>
- <char name="space" width="600"/>
+ <char-metrics>
+ <char name="A" width="600" llx="3" lly="0" urx="597" ury="562"/>
+ <char name="AE" width="600" llx="3" lly="0" urx="550" ury="562"/>
+ <char name="Aacute" width="600" llx="3" lly="0" urx="597" ury="805"/>
+ <char name="Acircumflex" width="600" llx="3" lly="0" urx="597" ury="787"/>
+ <char name="Adieresis" width="600" llx="3" lly="0" urx="597" ury="753"/>
+ <char name="Agrave" width="600" llx="3" lly="0" urx="597" ury="805"/>
+ <char name="Aring" width="600" llx="3" lly="0" urx="597" ury="750"/>
+ <char name="Atilde" width="600" llx="3" lly="0" urx="597" ury="729"/>
+ <char name="B" width="600" llx="43" lly="0" urx="559" ury="562"/>
+ <char name="C" width="600" llx="41" lly="-18" urx="540" ury="580"/>
+ <char name="Ccedilla" width="600" llx="41" lly="-151" urx="540" ury="580"/>
+ <char name="D" width="600" llx="43" lly="0" urx="574" ury="562"/>
+ <char name="E" width="600" llx="53" lly="0" urx="550" ury="562"/>
+ <char name="Eacute" width="600" llx="53" lly="0" urx="550" ury="805"/>
+ <char name="Ecircumflex" width="600" llx="53" lly="0" urx="550" ury="787"/>
+ <char name="Edieresis" width="600" llx="53" lly="0" urx="550" ury="753"/>
+ <char name="Egrave" width="600" llx="53" lly="0" urx="550" ury="805"/>
+ <char name="Eth" width="600" llx="30" lly="0" urx="574" ury="562"/>
+ <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="600" llx="53" lly="0" urx="545" ury="562"/>
+ <char name="G" width="600" llx="31" lly="-18" urx="575" ury="580"/>
+ <char name="H" width="600" llx="32" lly="0" urx="568" ury="562"/>
+ <char name="I" width="600" llx="96" lly="0" urx="504" ury="562"/>
+ <char name="Iacute" width="600" llx="96" lly="0" urx="504" ury="805"/>
+ <char name="Icircumflex" width="600" llx="96" lly="0" urx="504" ury="787"/>
+ <char name="Idieresis" width="600" llx="96" lly="0" urx="504" ury="753"/>
+ <char name="Igrave" width="600" llx="96" lly="0" urx="504" ury="805"/>
+ <char name="J" width="600" llx="34" lly="-18" urx="566" ury="562"/>
+ <char name="K" width="600" llx="38" lly="0" urx="582" ury="562"/>
+ <char name="L" width="600" llx="47" lly="0" urx="554" ury="562"/>
+ <char name="Lslash" width="600" llx="47" lly="0" urx="554" ury="562"/>
+ <char name="M" width="600" llx="4" lly="0" urx="596" ury="562"/>
+ <char name="N" width="600" llx="7" lly="-13" urx="593" ury="562"/>
+ <char name="Ntilde" width="600" llx="7" lly="-13" urx="593" ury="729"/>
+ <char name="O" width="600" llx="43" lly="-18" urx="557" ury="580"/>
+ <char name="OE" width="600" llx="7" lly="0" urx="567" ury="562"/>
+ <char name="Oacute" width="600" llx="43" lly="-18" urx="557" ury="805"/>
+ <char name="Ocircumflex" width="600" llx="43" lly="-18" urx="557" ury="787"/>
+ <char name="Odieresis" width="600" llx="43" lly="-18" urx="557" ury="753"/>
+ <char name="Ograve" width="600" llx="43" lly="-18" urx="557" ury="805"/>
+ <char name="Oslash" width="600" llx="43" lly="-80" urx="557" ury="629"/>
+ <char name="Otilde" width="600" llx="43" lly="-18" urx="557" ury="729"/>
+ <char name="P" width="600" llx="79" lly="0" urx="558" ury="562"/>
+ <char name="Q" width="600" llx="43" lly="-138" urx="557" ury="580"/>
+ <char name="R" width="600" llx="38" lly="0" urx="588" ury="562"/>
+ <char name="S" width="600" llx="72" lly="-20" urx="529" ury="580"/>
+ <char name="Scaron" width="600" llx="72" lly="-20" urx="529" ury="802"/>
+ <char name="Scedilla" width="600" llx="72" lly="-151" urx="529" ury="580"/>
+ <char name="T" width="600" llx="38" lly="0" urx="563" ury="562"/>
+ <char name="Thorn" width="600" llx="79" lly="0" urx="538" ury="562"/>
+ <char name="U" width="600" llx="17" lly="-18" urx="583" ury="562"/>
+ <char name="Uacute" width="600" llx="17" lly="-18" urx="583" ury="805"/>
+ <char name="Ucircumflex" width="600" llx="17" lly="-18" urx="583" ury="787"/>
+ <char name="Udieresis" width="600" llx="17" lly="-18" urx="583" ury="753"/>
+ <char name="Ugrave" width="600" llx="17" lly="-18" urx="583" ury="805"/>
+ <char name="V" width="600" llx="-4" lly="-13" urx="604" ury="562"/>
+ <char name="W" width="600" llx="-3" lly="-13" urx="603" ury="562"/>
+ <char name="X" width="600" llx="23" lly="0" urx="577" ury="562"/>
+ <char name="Y" width="600" llx="24" lly="0" urx="576" ury="562"/>
+ <char name="Yacute" width="600" llx="24" lly="0" urx="576" ury="805"/>
+ <char name="Ydieresis" width="600" llx="24" lly="0" urx="576" ury="753"/>
+ <char name="Z" width="600" llx="86" lly="0" urx="514" ury="562"/>
+ <char name="Zcaron" width="600" llx="86" lly="0" urx="514" ury="802"/>
+ <char name="a" width="600" llx="53" lly="-15" urx="559" ury="441"/>
+ <char name="aacute" width="600" llx="53" lly="-15" urx="559" ury="672"/>
+ <char name="acircumflex" width="600" llx="53" lly="-15" urx="559" ury="654"/>
+ <char name="acute" width="600" llx="242" lly="497" urx="469" ury="672"/>
+ <char name="adieresis" width="600" llx="53" lly="-15" urx="559" ury="620"/>
+ <char name="ae" width="600" llx="19" lly="-15" urx="570" ury="441"/>
+ <char name="agrave" width="600" llx="53" lly="-15" urx="559" ury="672"/>
+ <char name="ampersand" width="600" llx="63" lly="-15" urx="538" ury="543"/>
+ <char name="aring" width="600" llx="53" lly="-15" urx="559" ury="627"/>
+ <char name="asciicircum" width="600" llx="94" lly="354" urx="506" ury="622"/>
+ <char name="asciitilde" width="600" llx="63" lly="197" urx="540" ury="320"/>
+ <char name="asterisk" width="600" llx="116" lly="257" urx="484" ury="607"/>
+ <char name="at" width="600" llx="77" lly="-15" urx="533" ury="622"/>
+ <char name="atilde" width="600" llx="53" lly="-15" urx="559" ury="606"/>
+ <char name="b" width="600" llx="14" lly="-15" urx="575" ury="629"/>
+ <char name="backslash" width="600" llx="118" lly="-80" urx="482" ury="629"/>
+ <char name="bar" width="600" llx="275" lly="-250" urx="326" ury="750"/>
+ <char name="braceleft" width="600" llx="182" lly="-108" urx="437" ury="622"/>
+ <char name="braceright" width="600" llx="163" lly="-108" urx="418" ury="622"/>
+ <char name="bracketleft" width="600" llx="269" lly="-108" urx="442" ury="622"/>
+ <char name="bracketright" width="600" llx="158" lly="-108" urx="331" ury="622"/>
+ <char name="breve" width="600" llx="153" lly="501" urx="447" ury="609"/>
+ <char name="brokenbar" width="600" llx="275" lly="-175" urx="326" ury="675"/>
+ <char name="bullet" width="600" llx="172" lly="130" urx="428" ury="383"/>
+ <char name="c" width="600" llx="66" lly="-15" urx="529" ury="441"/>
+ <char name="caron" width="600" llx="124" lly="492" urx="476" ury="669"/>
+ <char name="ccedilla" width="600" llx="66" lly="-151" urx="529" ury="441"/>
+ <char name="cedilla" width="600" llx="224" lly="-151" urx="362" ury="10"/>
+ <char name="cent" width="600" llx="96" lly="-49" urx="500" ury="614"/>
+ <char name="circumflex" width="600" llx="124" lly="477" urx="476" ury="654"/>
+ <char name="colon" width="600" llx="229" lly="-15" urx="371" ury="385"/>
+ <char name="comma" width="600" llx="181" lly="-112" urx="344" ury="122"/>
+ <char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/>
+ <char name="currency" width="600" llx="73" lly="58" urx="527" ury="506"/>
+ <char name="d" width="600" llx="45" lly="-15" urx="591" ury="629"/>
+ <char name="dagger" width="600" llx="141" lly="-78" urx="459" ury="580"/>
+ <char name="daggerdbl" width="600" llx="141" lly="-78" urx="459" ury="580"/>
+ <char name="degree" width="600" llx="123" lly="269" urx="477" ury="622"/>
+ <char name="dieresis" width="600" llx="148" lly="537" urx="453" ury="640"/>
+ <char name="divide" width="600" llx="87" lly="48" urx="513" ury="467"/>
+ <char name="dollar" width="600" llx="105" lly="-126" urx="496" ury="662"/>
+ <char name="dotaccent" width="600" llx="249" lly="537" urx="352" ury="640"/>
+ <char name="dotlessi" width="600" llx="95" lly="0" urx="505" ury="426"/>
+ <char name="e" width="600" llx="66" lly="-15" urx="548" ury="441"/>
+ <char name="eacute" width="600" llx="66" lly="-15" urx="548" ury="672"/>
+ <char name="ecircumflex" width="600" llx="66" lly="-15" urx="548" ury="654"/>
+ <char name="edieresis" width="600" llx="66" lly="-15" urx="548" ury="620"/>
+ <char name="egrave" width="600" llx="66" lly="-15" urx="548" ury="672"/>
+ <char name="eight" width="600" llx="102" lly="-15" urx="498" ury="622"/>
+ <char name="ellipsis" width="600" llx="37" lly="-15" urx="563" ury="111"/>
+ <char name="emdash" width="600" llx="0" lly="231" urx="600" ury="285"/>
+ <char name="endash" width="600" llx="75" lly="231" urx="525" ury="285"/>
+ <char name="equal" width="600" llx="80" lly="138" urx="520" ury="376"/>
+ <char name="eth" width="600" llx="62" lly="-15" urx="538" ury="629"/>
+ <char name="exclam" width="600" llx="236" lly="-15" urx="364" ury="572"/>
+ <char name="exclamdown" width="600" llx="236" lly="-157" urx="364" ury="430"/>
+ <char name="f" width="600" llx="114" lly="0" urx="531" ury="629"/>
+ <char name="fi" width="600" llx="3" lly="0" urx="597" ury="629"/>
+ <char name="five" width="600" llx="92" lly="-15" urx="497" ury="607"/>
+ <char name="fl" width="600" llx="3" lly="0" urx="597" ury="629"/>
+ <char name="florin" width="600" llx="4" lly="-143" urx="539" ury="622"/>
+ <char name="four" width="600" llx="78" lly="0" urx="500" ury="622"/>
+ <char name="fraction" width="600" llx="92" lly="-57" urx="509" ury="665"/>
+ <char name="g" width="600" llx="45" lly="-157" urx="566" ury="441"/>
+ <char name="germandbls" width="600" llx="48" lly="-15" urx="588" ury="629"/>
+ <char name="grave" width="600" llx="151" lly="497" urx="378" ury="672"/>
+ <char name="greater" width="600" llx="66" lly="42" urx="544" ury="472"/>
+ <char name="guillemotleft" width="600" llx="37" lly="70" urx="563" ury="446"/>
+ <char name="guillemotright" width="600" llx="37" lly="70" urx="563" ury="446"/>
+ <char name="guilsinglleft" width="600" llx="149" lly="70" urx="451" ury="446"/>
+ <char name="guilsinglright" width="600" llx="149" lly="70" urx="451" ury="446"/>
+ <char name="h" width="600" llx="18" lly="0" urx="582" ury="629"/>
+ <char name="hungarumlaut" width="600" llx="133" lly="497" urx="540" ury="672"/>
+ <char name="hyphen" width="600" llx="103" lly="231" urx="497" ury="285"/>
+ <char name="i" width="600" llx="95" lly="0" urx="505" ury="657"/>
+ <char name="iacute" width="600" llx="95" lly="0" urx="505" ury="672"/>
+ <char name="icircumflex" width="600" llx="94" lly="0" urx="505" ury="654"/>
+ <char name="idieresis" width="600" llx="95" lly="0" urx="505" ury="620"/>
+ <char name="igrave" width="600" llx="95" lly="0" urx="505" ury="672"/>
+ <char name="j" width="600" llx="82" lly="-157" urx="410" ury="657"/>
+ <char name="k" width="600" llx="43" lly="0" urx="580" ury="629"/>
+ <char name="l" width="600" llx="95" lly="0" urx="505" ury="629"/>
+ <char name="less" width="600" llx="41" lly="42" urx="519" ury="472"/>
+ <char name="logicalnot" width="600" llx="87" lly="108" urx="513" ury="369"/>
+ <char name="lslash" width="600" llx="95" lly="0" urx="505" ury="629"/>
+ <char name="m" width="600" llx="-5" lly="0" urx="605" ury="441"/>
+ <char name="macron" width="600" llx="120" lly="525" urx="480" ury="565"/>
+ <char name="minus" width="600" llx="80" lly="232" urx="520" ury="283"/>
+ <char name="mu" width="600" llx="21" lly="-157" urx="562" ury="426"/>
+ <char name="multiply" width="600" llx="87" lly="43" urx="515" ury="470"/>
+ <char name="n" width="600" llx="26" lly="0" urx="575" ury="441"/>
+ <char name="nine" width="600" llx="96" lly="-15" urx="489" ury="622"/>
+ <char name="ntilde" width="600" llx="26" lly="0" urx="575" ury="606"/>
+ <char name="numbersign" width="600" llx="93" lly="-32" urx="507" ury="639"/>
+ <char name="o" width="600" llx="62" lly="-15" urx="538" ury="441"/>
+ <char name="oacute" width="600" llx="62" lly="-15" urx="538" ury="672"/>
+ <char name="ocircumflex" width="600" llx="62" lly="-15" urx="538" ury="654"/>
+ <char name="odieresis" width="600" llx="62" lly="-15" urx="538" ury="620"/>
+ <char name="oe" width="600" llx="19" lly="-15" urx="559" ury="441"/>
+ <char name="ogonek" width="600" llx="211" lly="-172" urx="407" ury="4"/>
+ <char name="ograve" width="600" llx="62" lly="-15" urx="538" ury="672"/>
+ <char name="one" width="600" llx="96" lly="0" urx="505" ury="622"/>
+ <char name="onehalf" width="600" llx="0" lly="-57" urx="611" ury="665"/>
+ <char name="onequarter" width="600" llx="0" lly="-57" urx="600" ury="665"/>
+ <char name="onesuperior" width="600" llx="172" lly="249" urx="428" ury="622"/>
+ <char name="ordfeminine" width="600" llx="156" lly="249" urx="442" ury="580"/>
+ <char name="ordmasculine" width="600" llx="157" lly="249" urx="443" ury="580"/>
+ <char name="oslash" width="600" llx="62" lly="-80" urx="538" ury="506"/>
+ <char name="otilde" width="600" llx="62" lly="-15" urx="538" ury="606"/>
+ <char name="p" width="600" llx="9" lly="-157" urx="555" ury="441"/>
+ <char name="paragraph" width="600" llx="50" lly="-78" urx="511" ury="562"/>
+ <char name="parenleft" width="600" llx="269" lly="-108" urx="440" ury="622"/>
+ <char name="parenright" width="600" llx="160" lly="-108" urx="331" ury="622"/>
+ <char name="percent" width="600" llx="81" lly="-15" urx="518" ury="622"/>
+ <char name="period" width="600" llx="229" lly="-15" urx="371" ury="109"/>
+ <char name="periodcentered" width="600" llx="222" lly="189" urx="378" ury="327"/>
+ <char name="perthousand" width="600" llx="3" lly="-15" urx="600" ury="622"/>
+ <char name="plus" width="600" llx="80" lly="44" urx="520" ury="470"/>
+ <char name="plusminus" width="600" llx="87" lly="44" urx="513" ury="558"/>
+ <char name="q" width="600" llx="45" lly="-157" urx="591" ury="441"/>
+ <char name="question" width="600" llx="129" lly="-15" urx="492" ury="572"/>
+ <char name="questiondown" width="600" llx="108" lly="-157" urx="471" ury="430"/>
+ <char name="quotedbl" width="600" llx="187" lly="328" urx="413" ury="562"/>
+ <char name="quotedblbase" width="600" llx="143" lly="-134" urx="457" ury="100"/>
+ <char name="quotedblleft" width="600" llx="143" lly="328" urx="471" ury="562"/>
+ <char name="quotedblright" width="600" llx="143" lly="328" urx="457" ury="562"/>
+ <char name="quoteleft" width="600" llx="224" lly="328" urx="387" ury="562"/>
+ <char name="quoteright" width="600" llx="213" lly="328" urx="376" ury="562"/>
+ <char name="quotesinglbase" width="600" llx="213" lly="-134" urx="376" ury="100"/>
+ <char name="quotesingle" width="600" llx="259" lly="328" urx="341" ury="562"/>
+ <char name="r" width="600" llx="60" lly="0" urx="559" ury="441"/>
+ <char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/>
+ <char name="ring" width="600" llx="218" lly="463" urx="382" ury="627"/>
+ <char name="s" width="600" llx="80" lly="-15" urx="513" ury="441"/>
+ <char name="scaron" width="600" llx="80" lly="-15" urx="513" ury="669"/>
+ <char name="scedilla" width="600" llx="80" lly="-151" urx="513" ury="441"/>
+ <char name="section" width="600" llx="113" lly="-78" urx="488" ury="580"/>
+ <char name="semicolon" width="600" llx="181" lly="-112" urx="371" ury="385"/>
+ <char name="seven" width="600" llx="82" lly="0" urx="483" ury="607"/>
+ <char name="six" width="600" llx="111" lly="-15" urx="497" ury="622"/>
+ <char name="slash" width="600" llx="125" lly="-80" urx="475" ury="629"/>
+ <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="600"/>
- <char name="square" width="600"/>
- <char name="sterling" width="600"/>
- <char name="stop" width="600"/>
- <char name="t" width="600"/>
- <char name="tab" width="600"/>
- <char name="thorn" width="600"/>
- <char name="three" width="600"/>
- <char name="threequarters" width="600"/>
- <char name="threesuperior" width="600"/>
- <char name="tilde" width="600"/>
- <char name="trademark" width="600"/>
- <char name="two" width="600"/>
- <char name="twosuperior" width="600"/>
- <char name="u" width="600"/>
- <char name="uacute" width="600"/>
- <char name="ucircumflex" width="600"/>
- <char name="udieresis" width="600"/>
- <char name="ugrave" width="600"/>
- <char name="underscore" width="600"/>
- <char name="up" width="600"/>
- <char name="v" width="600"/>
- <char name="w" width="600"/>
- <char name="x" width="600"/>
- <char name="y" width="600"/>
- <char name="yacute" width="600"/>
- <char name="ydieresis" width="600"/>
- <char name="yen" width="600"/>
- <char name="z" width="600"/>
- <char name="zcaron" width="600"/>
- <char name="zero" width="600"/>
- </widths>
-</font-metrics> \ No newline at end of file
+ <char name="sterling" width="600" llx="84" lly="-21" urx="521" ury="611"/>
+ <char name="t" width="600" llx="87" lly="-15" urx="530" ury="561"/>
+ <char name="thorn" width="600" llx="-6" lly="-157" urx="555" ury="629"/>
+ <char name="three" width="600" llx="75" lly="-15" urx="466" ury="622"/>
+ <char name="threequarters" width="600" llx="8" lly="-56" urx="593" ury="666"/>
+ <char name="threesuperior" width="600" llx="155" lly="240" urx="406" ury="622"/>
+ <char name="tilde" width="600" llx="105" lly="489" urx="503" ury="606"/>
+ <char name="trademark" width="600" llx="-23" lly="263" urx="623" ury="562"/>
+ <char name="two" width="600" llx="70" lly="0" urx="471" ury="622"/>
+ <char name="twosuperior" width="600" llx="177" lly="249" urx="424" ury="622"/>
+ <char name="u" width="600" llx="21" lly="-15" urx="562" ury="426"/>
+ <char name="uacute" width="600" llx="21" lly="-15" urx="562" ury="672"/>
+ <char name="ucircumflex" width="600" llx="21" lly="-15" urx="562" ury="654"/>
+ <char name="udieresis" width="600" llx="21" lly="-15" urx="562" ury="620"/>
+ <char name="ugrave" width="600" llx="21" lly="-15" urx="562" ury="672"/>
+ <char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/>
+ <char name="v" width="600" llx="10" lly="-10" urx="590" ury="426"/>
+ <char name="w" width="600" llx="-4" lly="-10" urx="604" ury="426"/>
+ <char name="x" width="600" llx="20" lly="0" urx="580" ury="426"/>
+ <char name="y" width="600" llx="7" lly="-157" urx="592" ury="426"/>
+ <char name="yacute" width="600" llx="7" lly="-157" urx="592" ury="672"/>
+ <char name="ydieresis" width="600" llx="7" lly="-157" urx="592" ury="620"/>
+ <char name="yen" width="600" llx="26" lly="0" urx="574" ury="562"/>
+ <char name="z" width="600" llx="99" lly="0" urx="502" ury="426"/>
+ <char name="zcaron" width="600" llx="99" lly="0" urx="502" ury="669"/>
+ <char name="zero" width="600" llx="106" lly="-15" urx="494" ury="622"/>
+ </char-metrics>
+</font-metrics>
diff --git a/src/codegen/fonts/CourierBold.xml b/src/codegen/fonts/CourierBold.xml
index fa8bed196..c06ef5f23 100644
--- a/src/codegen/fonts/CourierBold.xml
+++ b/src/codegen/fonts/CourierBold.xml
@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierBold</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>439</x-height>
<ascender>626</ascender>
<descender>-142</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="600"/>
- <char name="AE" width="600"/>
- <char name="Aacute" width="600"/>
- <char name="Acircumflex" width="600"/>
- <char name="Adieresis" width="600"/>
- <char name="Agrave" width="600"/>
- <char name="Aring" width="600"/>
- <char name="Atilde" width="600"/>
- <char name="B" width="600"/>
- <char name="C" width="600"/>
- <char name="Ccedilla" width="600"/>
- <char name="D" width="600"/>
- <char name="E" width="600"/>
- <char name="Eacute" width="600"/>
- <char name="Ecircumflex" width="600"/>
- <char name="Edieresis" width="600"/>
- <char name="Egrave" width="600"/>
- <char name="Eth" width="600"/>
- <char name="Euro" width="600"/>
- <char name="F" width="600"/>
- <char name="G" width="600"/>
- <char name="Gcaron" width="600"/>
- <char name="H" width="600"/>
- <char name="I" width="600"/>
- <char name="IJ" width="600"/>
- <char name="Iacute" width="600"/>
- <char name="Icircumflex" width="600"/>
- <char name="Idieresis" width="600"/>
- <char name="Idot" width="600"/>
- <char name="Igrave" width="600"/>
- <char name="J" width="600"/>
- <char name="K" width="600"/>
- <char name="L" width="600"/>
- <char name="LL" width="600"/>
- <char name="Lslash" width="600"/>
- <char name="M" width="600"/>
- <char name="N" width="600"/>
- <char name="Ntilde" width="600"/>
- <char name="O" width="600"/>
- <char name="OE" width="600"/>
- <char name="Oacute" width="600"/>
- <char name="Ocircumflex" width="600"/>
- <char name="Odieresis" width="600"/>
- <char name="Ograve" width="600"/>
- <char name="Oslash" width="600"/>
- <char name="Otilde" width="600"/>
- <char name="P" width="600"/>
- <char name="Q" width="600"/>
- <char name="R" width="600"/>
- <char name="S" width="600"/>
- <char name="Scaron" width="600"/>
- <char name="Scedilla" width="600"/>
- <char name="T" width="600"/>
- <char name="Thorn" width="600"/>
- <char name="U" width="600"/>
- <char name="Uacute" width="600"/>
- <char name="Ucircumflex" width="600"/>
- <char name="Udieresis" width="600"/>
- <char name="Ugrave" width="600"/>
- <char name="V" width="600"/>
- <char name="W" width="600"/>
- <char name="X" width="600"/>
- <char name="Y" width="600"/>
- <char name="Yacute" width="600"/>
- <char name="Ydieresis" width="600"/>
- <char name="Z" width="600"/>
- <char name="Zcaron" width="600"/>
- <char name="a" width="600"/>
- <char name="aacute" width="600"/>
- <char name="acircumflex" width="600"/>
- <char name="acute" width="600"/>
- <char name="adieresis" width="600"/>
- <char name="ae" width="600"/>
- <char name="agrave" width="600"/>
- <char name="ampersand" width="600"/>
- <char name="aring" width="600"/>
- <char name="arrowboth" width="600"/>
- <char name="arrowdown" width="600"/>
- <char name="arrowleft" width="600"/>
- <char name="arrowright" width="600"/>
- <char name="arrowup" width="600"/>
- <char name="asciicircum" width="600"/>
- <char name="asciitilde" width="600"/>
- <char name="asterisk" width="600"/>
- <char name="at" width="600"/>
- <char name="atilde" width="600"/>
- <char name="b" width="600"/>
- <char name="backslash" width="600"/>
- <char name="bar" width="600"/>
- <char name="braceleft" width="600"/>
- <char name="braceright" width="600"/>
- <char name="bracketleft" width="600"/>
- <char name="bracketright" width="600"/>
- <char name="breve" width="600"/>
- <char name="brokenbar" width="600"/>
- <char name="bullet" width="600"/>
- <char name="c" width="600"/>
- <char name="caron" width="600"/>
- <char name="ccedilla" width="600"/>
- <char name="cedilla" width="600"/>
- <char name="cent" width="600"/>
- <char name="center" width="600"/>
- <char name="circumflex" width="600"/>
- <char name="colon" width="600"/>
- <char name="comma" width="600"/>
- <char name="copyright" width="600"/>
- <char name="currency" width="600"/>
- <char name="d" width="600"/>
- <char name="dagger" width="600"/>
- <char name="daggerdbl" width="600"/>
- <char name="dectab" width="600"/>
- <char name="degree" width="600"/>
- <char name="dieresis" width="600"/>
- <char name="divide" width="600"/>
- <char name="dollar" width="600"/>
- <char name="dotaccent" width="600"/>
- <char name="dotlessi" width="600"/>
- <char name="down" width="600"/>
- <char name="e" width="600"/>
- <char name="eacute" width="600"/>
- <char name="ecircumflex" width="600"/>
- <char name="edieresis" width="600"/>
- <char name="egrave" width="600"/>
- <char name="eight" width="600"/>
- <char name="ellipsis" width="600"/>
- <char name="emdash" width="600"/>
- <char name="endash" width="600"/>
- <char name="equal" width="600"/>
- <char name="eth" width="600"/>
- <char name="exclam" width="600"/>
- <char name="exclamdown" width="600"/>
- <char name="f" width="600"/>
- <char name="fi" width="600"/>
- <char name="five" width="600"/>
- <char name="fl" width="600"/>
- <char name="florin" width="600"/>
- <char name="format" width="600"/>
- <char name="four" width="600"/>
- <char name="fraction" width="600"/>
- <char name="g" width="600"/>
- <char name="gcaron" width="600"/>
- <char name="germandbls" width="600"/>
- <char name="grave" width="600"/>
- <char name="graybox" width="600"/>
- <char name="greater" width="600"/>
- <char name="guillemotleft" width="600"/>
- <char name="guillemotright" width="600"/>
- <char name="guilsinglleft" width="600"/>
- <char name="guilsinglright" width="600"/>
- <char name="h" width="600"/>
- <char name="hungarumlaut" width="600"/>
- <char name="hyphen" width="600"/>
- <char name="i" width="600"/>
- <char name="iacute" width="600"/>
- <char name="icircumflex" width="600"/>
- <char name="idieresis" width="600"/>
- <char name="igrave" width="600"/>
- <char name="ij" width="600"/>
- <char name="indent" width="600"/>
- <char name="j" width="600"/>
- <char name="k" width="600"/>
- <char name="l" width="600"/>
- <char name="largebullet" width="600"/>
- <char name="left" width="600"/>
- <char name="less" width="600"/>
- <char name="lira" width="600"/>
- <char name="ll" width="600"/>
- <char name="logicalnot" width="600"/>
- <char name="lslash" width="600"/>
- <char name="m" width="600"/>
- <char name="macron" width="600"/>
- <char name="merge" width="600"/>
- <char name="minus" width="600"/>
- <char name="mu" width="600"/>
- <char name="multiply" width="600"/>
- <char name="n" width="600"/>
- <char name="nine" width="600"/>
- <char name="notegraphic" width="600"/>
- <char name="ntilde" width="600"/>
- <char name="numbersign" width="600"/>
- <char name="o" width="600"/>
- <char name="oacute" width="600"/>
- <char name="ocircumflex" width="600"/>
- <char name="odieresis" width="600"/>
- <char name="oe" width="600"/>
- <char name="ogonek" width="600"/>
- <char name="ograve" width="600"/>
- <char name="one" width="600"/>
- <char name="onehalf" width="600"/>
- <char name="onequarter" width="600"/>
- <char name="onesuperior" width="600"/>
- <char name="ordfeminine" width="600"/>
- <char name="ordmasculine" width="600"/>
- <char name="oslash" width="600"/>
- <char name="otilde" width="600"/>
- <char name="overscore" width="600"/>
- <char name="p" width="600"/>
- <char name="paragraph" width="600"/>
- <char name="parenleft" width="600"/>
- <char name="parenright" width="600"/>
- <char name="percent" width="600"/>
- <char name="period" width="600"/>
- <char name="periodcentered" width="600"/>
- <char name="perthousand" width="600"/>
- <char name="plus" width="600"/>
- <char name="plusminus" width="600"/>
- <char name="prescription" width="600"/>
- <char name="q" width="600"/>
- <char name="question" width="600"/>
- <char name="questiondown" width="600"/>
- <char name="quotedbl" width="600"/>
- <char name="quotedblbase" width="600"/>
- <char name="quotedblleft" width="600"/>
- <char name="quotedblright" width="600"/>
- <char name="quoteleft" width="600"/>
- <char name="quoteright" width="600"/>
- <char name="quotesinglbase" width="600"/>
- <char name="quotesingle" width="600"/>
- <char name="r" width="600"/>
- <char name="registered" width="600"/>
- <char name="return" width="600"/>
- <char name="ring" width="600"/>
- <char name="s" width="600"/>
- <char name="scaron" width="600"/>
- <char name="scedilla" width="600"/>
- <char name="section" width="600"/>
- <char name="semicolon" width="600"/>
- <char name="seven" width="600"/>
- <char name="six" width="600"/>
- <char name="slash" width="600"/>
- <char name="space" width="600"/>
+ <char-metrics>
+ <char name="A" width="600" llx="-9" lly="0" urx="609" ury="562"/>
+ <char name="AE" width="600" llx="-29" lly="0" urx="602" ury="562"/>
+ <char name="Aacute" width="600" llx="-9" lly="0" urx="609" ury="784"/>
+ <char name="Acircumflex" width="600" llx="-9" lly="0" urx="609" ury="780"/>
+ <char name="Adieresis" width="600" llx="-9" lly="0" urx="609" ury="761"/>
+ <char name="Agrave" width="600" llx="-9" lly="0" urx="609" ury="784"/>
+ <char name="Aring" width="600" llx="-9" lly="0" urx="609" ury="801"/>
+ <char name="Atilde" width="600" llx="-9" lly="0" urx="609" ury="759"/>
+ <char name="B" width="600" llx="30" lly="0" urx="573" ury="562"/>
+ <char name="C" width="600" llx="22" lly="-18" urx="560" ury="580"/>
+ <char name="Ccedilla" width="600" llx="22" lly="-206" urx="560" ury="580"/>
+ <char name="D" width="600" llx="30" lly="0" urx="594" ury="562"/>
+ <char name="E" width="600" llx="25" lly="0" urx="560" ury="562"/>
+ <char name="Eacute" width="600" llx="25" lly="0" urx="560" ury="784"/>
+ <char name="Ecircumflex" width="600" llx="25" lly="0" urx="560" ury="780"/>
+ <char name="Edieresis" width="600" llx="25" lly="0" urx="560" ury="761"/>
+ <char name="Egrave" width="600" llx="25" lly="0" urx="560" ury="784"/>
+ <char name="Eth" width="600" llx="30" lly="0" urx="594" ury="562"/>
+ <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="600" llx="39" lly="0" urx="570" ury="562"/>
+ <char name="G" width="600" llx="22" lly="-18" urx="594" ury="580"/>
+ <char name="H" width="600" llx="20" lly="0" urx="580" ury="562"/>
+ <char name="I" width="600" llx="77" lly="0" urx="523" ury="562"/>
+ <char name="Iacute" width="600" llx="77" lly="0" urx="523" ury="784"/>
+ <char name="Icircumflex" width="600" llx="77" lly="0" urx="523" ury="780"/>
+ <char name="Idieresis" width="600" llx="77" lly="0" urx="523" ury="761"/>
+ <char name="Igrave" width="600" llx="77" lly="0" urx="523" ury="784"/>
+ <char name="J" width="600" llx="37" lly="-18" urx="601" ury="562"/>
+ <char name="K" width="600" llx="21" lly="0" urx="599" ury="562"/>
+ <char name="L" width="600" llx="39" lly="0" urx="578" ury="562"/>
+ <char name="Lslash" width="600" llx="39" lly="0" urx="578" ury="562"/>
+ <char name="M" width="600" llx="-2" lly="0" urx="602" ury="562"/>
+ <char name="N" width="600" llx="8" lly="-12" urx="610" ury="562"/>
+ <char name="Ntilde" width="600" llx="8" lly="-12" urx="610" ury="759"/>
+ <char name="O" width="600" llx="22" lly="-18" urx="578" ury="580"/>
+ <char name="OE" width="600" llx="-25" lly="0" urx="595" ury="562"/>
+ <char name="Oacute" width="600" llx="22" lly="-18" urx="578" ury="784"/>
+ <char name="Ocircumflex" width="600" llx="22" lly="-18" urx="578" ury="780"/>
+ <char name="Odieresis" width="600" llx="22" lly="-18" urx="578" ury="761"/>
+ <char name="Ograve" width="600" llx="22" lly="-18" urx="578" ury="784"/>
+ <char name="Oslash" width="600" llx="22" lly="-22" urx="578" ury="584"/>
+ <char name="Otilde" width="600" llx="22" lly="-18" urx="578" ury="759"/>
+ <char name="P" width="600" llx="48" lly="0" urx="559" ury="562"/>
+ <char name="Q" width="600" llx="32" lly="-138" urx="578" ury="580"/>
+ <char name="R" width="600" llx="24" lly="0" urx="599" ury="562"/>
+ <char name="S" width="600" llx="47" lly="-22" urx="553" ury="582"/>
+ <char name="Scaron" width="600" llx="47" lly="-22" urx="553" ury="790"/>
+ <char name="Scedilla" width="600" llx="47" lly="-206" urx="553" ury="582"/>
+ <char name="T" width="600" llx="21" lly="0" urx="579" ury="562"/>
+ <char name="Thorn" width="600" llx="48" lly="0" urx="557" ury="562"/>
+ <char name="U" width="600" llx="4" lly="-18" urx="596" ury="562"/>
+ <char name="Uacute" width="600" llx="4" lly="-18" urx="596" ury="784"/>
+ <char name="Ucircumflex" width="600" llx="4" lly="-18" urx="596" ury="780"/>
+ <char name="Udieresis" width="600" llx="4" lly="-18" urx="596" ury="761"/>
+ <char name="Ugrave" width="600" llx="4" lly="-18" urx="596" ury="784"/>
+ <char name="V" width="600" llx="-13" lly="0" urx="613" ury="562"/>
+ <char name="W" width="600" llx="-18" lly="0" urx="618" ury="562"/>
+ <char name="X" width="600" llx="12" lly="0" urx="588" ury="562"/>
+ <char name="Y" width="600" llx="12" lly="0" urx="589" ury="562"/>
+ <char name="Yacute" width="600" llx="12" lly="0" urx="589" ury="784"/>
+ <char name="Ydieresis" width="600" llx="12" lly="0" urx="589" ury="761"/>
+ <char name="Z" width="600" llx="62" lly="0" urx="539" ury="562"/>
+ <char name="Zcaron" width="600" llx="62" lly="0" urx="539" ury="790"/>
+ <char name="a" width="600" llx="35" lly="-15" urx="570" ury="454"/>
+ <char name="aacute" width="600" llx="35" lly="-15" urx="570" ury="661"/>
+ <char name="acircumflex" width="600" llx="35" lly="-15" urx="570" ury="657"/>
+ <char name="acute" width="600" llx="205" lly="508" urx="468" ury="661"/>
+ <char name="adieresis" width="600" llx="35" lly="-15" urx="570" ury="638"/>
+ <char name="ae" width="600" llx="-4" lly="-15" urx="601" ury="454"/>
+ <char name="agrave" width="600" llx="35" lly="-15" urx="570" ury="661"/>
+ <char name="ampersand" width="600" llx="36" lly="-15" urx="546" ury="543"/>
+ <char name="aring" width="600" llx="35" lly="-15" urx="570" ury="678"/>
+ <char name="asciicircum" width="600" llx="108" lly="250" urx="492" ury="616"/>
+ <char name="asciitilde" width="600" llx="71" lly="153" urx="530" ury="356"/>
+ <char name="asterisk" width="600" llx="91" lly="219" urx="509" ury="601"/>
+ <char name="at" width="600" llx="16" lly="-15" urx="584" ury="616"/>
+ <char name="atilde" width="600" llx="35" lly="-15" urx="570" ury="636"/>
+ <char name="b" width="600" llx="0" lly="-15" urx="584" ury="626"/>
+ <char name="backslash" width="600" llx="99" lly="-77" urx="503" ury="626"/>
+ <char name="bar" width="600" llx="255" lly="-250" urx="345" ury="750"/>
+ <char name="braceleft" width="600" llx="160" lly="-102" urx="464" ury="616"/>
+ <char name="braceright" width="600" llx="136" lly="-102" urx="440" ury="616"/>
+ <char name="bracketleft" width="600" llx="245" lly="-102" urx="475" ury="616"/>
+ <char name="bracketright" width="600" llx="125" lly="-102" urx="355" ury="616"/>
+ <char name="breve" width="600" llx="83" lly="468" urx="517" ury="631"/>
+ <char name="brokenbar" width="600" llx="255" lly="-175" urx="345" ury="675"/>
+ <char name="bullet" width="600" llx="140" lly="132" urx="460" ury="430"/>
+ <char name="c" width="600" llx="40" lly="-15" urx="545" ury="459"/>
+ <char name="caron" width="600" llx="103" lly="493" urx="497" ury="667"/>
+ <char name="ccedilla" width="600" llx="40" lly="-206" urx="545" ury="459"/>
+ <char name="cedilla" width="600" llx="205" lly="-206" urx="387" ury="0"/>
+ <char name="cent" width="600" llx="66" lly="-49" urx="518" ury="614"/>
+ <char name="circumflex" width="600" llx="103" lly="483" urx="497" ury="657"/>
+ <char name="colon" width="600" llx="191" lly="-15" urx="407" ury="425"/>
+ <char name="comma" width="600" llx="123" lly="-111" urx="393" ury="174"/>
+ <char name="copyright" width="600" llx="0" lly="-18" urx="600" ury="580"/>
+ <char name="currency" width="600" llx="54" lly="49" urx="546" ury="517"/>
+ <char name="d" width="600" llx="20" lly="-15" urx="591" ury="626"/>
+ <char name="dagger" width="600" llx="106" lly="-70" urx="494" ury="580"/>
+ <char name="daggerdbl" width="600" llx="106" lly="-70" urx="494" ury="580"/>
+ <char name="degree" width="600" llx="86" lly="243" urx="474" ury="616"/>
+ <char name="dieresis" width="600" llx="128" lly="498" urx="472" ury="638"/>
+ <char name="divide" width="600" llx="71" lly="16" urx="529" ury="500"/>
+ <char name="dollar" width="600" llx="82" lly="-126" urx="519" ury="666"/>
+ <char name="dotaccent" width="600" llx="230" lly="498" urx="370" ury="638"/>
+ <char name="dotlessi" width="600" llx="77" lly="0" urx="523" ury="439"/>
+ <char name="e" width="600" llx="40" lly="-15" urx="563" ury="454"/>
+ <char name="eacute" width="600" llx="40" lly="-15" urx="563" ury="661"/>
+ <char name="ecircumflex" width="600" llx="40" lly="-15" urx="563" ury="657"/>
+ <char name="edieresis" width="600" llx="40" lly="-15" urx="563" ury="638"/>
+ <char name="egrave" width="600" llx="40" lly="-15" urx="563" ury="661"/>
+ <char name="eight" width="600" llx="83" lly="-15" urx="517" ury="616"/>
+ <char name="ellipsis" width="600" llx="26" lly="-15" urx="574" ury="116"/>
+ <char name="emdash" width="600" llx="-10" lly="203" urx="610" ury="313"/>
+ <char name="endash" width="600" llx="65" lly="203" urx="535" ury="313"/>
+ <char name="equal" width="600" llx="71" lly="118" urx="529" ury="398"/>
+ <char name="eth" width="600" llx="58" lly="-27" urx="543" ury="626"/>
+ <char name="exclam" width="600" llx="202" lly="-15" urx="398" ury="572"/>
+ <char name="exclamdown" width="600" llx="202" lly="-146" urx="398" ury="449"/>
+ <char name="f" width="600" llx="83" lly="0" urx="547" ury="626"/>
+ <char name="fi" width="600" llx="12" lly="0" urx="593" ury="626"/>
+ <char name="five" width="600" llx="70" lly="-15" urx="521" ury="601"/>
+ <char name="fl" width="600" llx="12" lly="0" urx="593" ury="626"/>
+ <char name="florin" width="600" llx="-30" lly="-131" urx="572" ury="616"/>
+ <char name="four" width="600" llx="53" lly="0" urx="507" ury="616"/>
+ <char name="fraction" width="600" llx="25" lly="-60" urx="576" ury="661"/>
+ <char name="g" width="600" llx="30" lly="-146" urx="580" ury="454"/>
+ <char name="germandbls" width="600" llx="22" lly="-15" urx="596" ury="626"/>
+ <char name="grave" width="600" llx="132" lly="508" urx="395" ury="661"/>
+ <char name="greater" width="600" llx="77" lly="15" urx="534" ury="501"/>
+ <char name="guillemotleft" width="600" llx="8" lly="70" urx="553" ury="446"/>
+ <char name="guillemotright" width="600" llx="47" lly="70" urx="592" ury="446"/>
+ <char name="guilsinglleft" width="600" llx="141" lly="70" urx="459" ury="446"/>
+ <char name="guilsinglright" width="600" llx="141" lly="70" urx="459" ury="446"/>
+ <char name="h" width="600" llx="5" lly="0" urx="592" ury="626"/>
+ <char name="hungarumlaut" width="600" llx="68" lly="488" urx="588" ury="661"/>
+ <char name="hyphen" width="600" llx="100" lly="203" urx="500" ury="313"/>
+ <char name="i" width="600" llx="77" lly="0" urx="523" ury="658"/>
+ <char name="iacute" width="600" llx="77" lly="0" urx="523" ury="661"/>
+ <char name="icircumflex" width="600" llx="73" lly="0" urx="523" ury="657"/>
+ <char name="idieresis" width="600" llx="77" lly="0" urx="523" ury="618"/>
+ <char name="igrave" width="600" llx="77" lly="0" urx="523" ury="661"/>
+ <char name="j" width="600" llx="63" lly="-146" urx="440" ury="658"/>
+ <char name="k" width="600" llx="20" lly="0" urx="585" ury="626"/>
+ <char name="l" width="600" llx="77" lly="0" urx="523" ury="626"/>
+ <char name="less" width="600" llx="66" lly="15" urx="523" ury="501"/>
+ <char name="logicalnot" width="600" llx="71" lly="103" urx="529" ury="413"/>
+ <char name="lslash" width="600" llx="77" lly="0" urx="523" ury="626"/>
+ <char name="m" width="600" llx="-22" lly="0" urx="626" ury="454"/>
+ <char name="macron" width="600" llx="88" lly="505" urx="512" ury="585"/>
+ <char name="minus" width="600" llx="71" lly="203" urx="529" ury="313"/>
+ <char name="mu" width="600" llx="-1" lly="-142" urx="569" ury="439"/>
+ <char name="multiply" width="600" llx="81" lly="39" urx="520" ury="478"/>
+ <char name="n" width="600" llx="18" lly="0" urx="592" ury="454"/>
+ <char name="nine" width="600" llx="79" lly="-15" urx="510" ury="616"/>
+ <char name="ntilde" width="600" llx="18" lly="0" urx="592" ury="636"/>
+ <char name="numbersign" width="600" llx="56" lly="-45" urx="544" ury="651"/>
+ <char name="o" width="600" llx="30" lly="-15" urx="570" ury="454"/>
+ <char name="oacute" width="600" llx="30" lly="-15" urx="570" ury="661"/>
+ <char name="ocircumflex" width="600" llx="30" lly="-15" urx="570" ury="657"/>
+ <char name="odieresis" width="600" llx="30" lly="-15" urx="570" ury="638"/>
+ <char name="oe" width="600" llx="-18" lly="-15" urx="611" ury="454"/>
+ <char name="ogonek" width="600" llx="169" lly="-199" urx="400" ury="0"/>
+ <char name="ograve" width="600" llx="30" lly="-15" urx="570" ury="661"/>
+ <char name="one" width="600" llx="81" lly="0" urx="539" ury="616"/>
+ <char name="onehalf" width="600" llx="-47" lly="-60" urx="648" ury="661"/>
+ <char name="onequarter" width="600" llx="-56" lly="-60" urx="656" ury="661"/>
+ <char name="onesuperior" width="600" llx="153" lly="230" urx="447" ury="616"/>
+ <char name="ordfeminine" width="600" llx="147" lly="196" urx="453" ury="580"/>
+ <char name="ordmasculine" width="600" llx="147" lly="196" urx="453" ury="580"/>
+ <char name="oslash" width="600" llx="30" lly="-24" urx="570" ury="463"/>
+ <char name="otilde" width="600" llx="30" lly="-15" urx="570" ury="636"/>
+ <char name="p" width="600" llx="-1" lly="-142" urx="570" ury="454"/>
+ <char name="paragraph" width="600" llx="6" lly="-70" urx="576" ury="580"/>
+ <char name="parenleft" width="600" llx="219" lly="-102" urx="461" ury="616"/>
+ <char name="parenright" width="600" llx="139" lly="-102" urx="381" ury="616"/>
+ <char name="percent" width="600" llx="5" lly="-15" urx="595" ury="616"/>
+ <char name="period" width="600" llx="192" lly="-15" urx="408" ury="171"/>
+ <char name="periodcentered" width="600" llx="196" lly="165" urx="404" ury="351"/>
+ <char name="perthousand" width="600" llx="-113" lly="-15" urx="713" ury="616"/>
+ <char name="plus" width="600" llx="71" lly="39" urx="529" ury="478"/>
+ <char name="plusminus" width="600" llx="71" lly="24" urx="529" ury="515"/>
+ <char name="q" width="600" llx="20" lly="-142" urx="591" ury="454"/>
+ <char name="question" width="600" llx="98" lly="-14" urx="501" ury="580"/>
+ <char name="questiondown" width="600" llx="99" lly="-146" urx="502" ury="449"/>
+ <char name="quotedbl" width="600" llx="135" lly="277" urx="465" ury="562"/>
+ <char name="quotedblbase" width="600" llx="65" lly="-142" urx="529" ury="143"/>
+ <char name="quotedblleft" width="600" llx="71" lly="277" urx="535" ury="562"/>
+ <char name="quotedblright" width="600" llx="61" lly="277" urx="525" ury="562"/>
+ <char name="quoteleft" width="600" llx="178" lly="277" urx="428" ury="562"/>
+ <char name="quoteright" width="600" llx="171" lly="277" urx="423" ury="562"/>
+ <char name="quotesinglbase" width="600" llx="175" lly="-142" urx="427" ury="143"/>
+ <char name="quotesingle" width="600" llx="227" lly="277" urx="373" ury="562"/>
+ <char name="r" width="600" llx="47" lly="0" urx="580" ury="454"/>
+ <char name="registered" width="600" llx="0" lly="-18" urx="600" ury="580"/>
+ <char name="ring" width="600" llx="198" lly="481" urx="402" ury="678"/>
+ <char name="s" width="600" llx="68" lly="-17" urx="535" ury="459"/>
+ <char name="scaron" width="600" llx="68" lly="-17" urx="535" ury="667"/>
+ <char name="scedilla" width="600" llx="68" lly="-206" urx="535" ury="459"/>
+ <char name="section" width="600" llx="83" lly="-70" urx="517" ury="580"/>
+ <char name="semicolon" width="600" llx="123" lly="-111" urx="408" ury="425"/>
+ <char name="seven" width="600" llx="55" lly="0" urx="494" ury="601"/>
+ <char name="six" width="600" llx="90" lly="-15" urx="521" ury="616"/>
+ <char name="slash" width="600" llx="98" lly="-77" urx="502" ury="626"/>
+ <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="600"/>
- <char name="square" width="600"/>
- <char name="sterling" width="600"/>
- <char name="stop" width="600"/>
- <char name="t" width="600"/>
- <char name="tab" width="600"/>
- <char name="thorn" width="600"/>
- <char name="three" width="600"/>
- <char name="threequarters" width="600"/>
- <char name="threesuperior" width="600"/>
- <char name="tilde" width="600"/>
- <char name="trademark" width="600"/>
- <char name="two" width="600"/>
- <char name="twosuperior" width="600"/>
- <char name="u" width="600"/>
- <char name="uacute" width="600"/>
- <char name="ucircumflex" width="600"/>
- <char name="udieresis" width="600"/>
- <char name="ugrave" width="600"/>
- <char name="underscore" width="600"/>
- <char name="up" width="600"/>
- <char name="v" width="600"/>
- <char name="w" width="600"/>
- <char name="x" width="600"/>
- <char name="y" width="600"/>
- <char name="yacute" width="600"/>
- <char name="ydieresis" width="600"/>
- <char name="yen" width="600"/>
- <char name="z" width="600"/>
- <char name="zcaron" width="600"/>
- <char name="zero" width="600"/>
- </widths>
-</font-metrics> \ No newline at end of file
+ <char name="sterling" width="600" llx="72" lly="-28" urx="558" ury="611"/>
+ <char name="t" width="600" llx="47" lly="-15" urx="532" ury="562"/>
+ <char name="thorn" width="600" llx="-14" lly="-142" urx="570" ury="626"/>
+ <char name="three" width="600" llx="63" lly="-15" urx="501" ury="616"/>
+ <char name="threequarters" width="600" llx="-47" lly="-60" urx="648" ury="661"/>
+ <char name="threesuperior" width="600" llx="138" lly="222" urx="433" ury="616"/>
+ <char name="tilde" width="600" llx="89" lly="493" urx="512" ury="636"/>
+ <char name="trademark" width="600" llx="-9" lly="230" urx="749" ury="562"/>
+ <char name="two" width="600" llx="61" lly="0" urx="499" ury="616"/>
+ <char name="twosuperior" width="600" llx="143" lly="230" urx="436" ury="616"/>
+ <char name="u" width="600" llx="-1" lly="-15" urx="569" ury="439"/>
+ <char name="uacute" width="600" llx="-1" lly="-15" urx="569" ury="661"/>
+ <char name="ucircumflex" width="600" llx="-1" lly="-15" urx="569" ury="657"/>
+ <char name="udieresis" width="600" llx="-1" lly="-15" urx="569" ury="638"/>
+ <char name="ugrave" width="600" llx="-1" lly="-15" urx="569" ury="661"/>
+ <char name="underscore" width="600" llx="0" lly="-125" urx="600" ury="-75"/>
+ <char name="v" width="600" llx="-1" lly="0" urx="601" ury="439"/>
+ <char name="w" width="600" llx="-18" lly="0" urx="618" ury="439"/>
+ <char name="x" width="600" llx="6" lly="0" urx="594" ury="439"/>
+ <char name="y" width="600" llx="-4" lly="-142" urx="601" ury="439"/>
+ <char name="yacute" width="600" llx="-4" lly="-142" urx="601" ury="661"/>
+ <char name="ydieresis" width="600" llx="-4" lly="-142" urx="601" ury="638"/>
+ <char name="yen" width="600" llx="10" lly="0" urx="590" ury="562"/>
+ <char name="z" width="600" llx="81" lly="0" urx="520" ury="439"/>
+ <char name="zcaron" width="600" llx="81" lly="0" urx="520" ury="667"/>
+ <char name="zero" width="600" llx="87" lly="-15" urx="513" ury="616"/>
+ </char-metrics>
+</font-metrics>
diff --git a/src/codegen/fonts/CourierBoldOblique.xml b/src/codegen/fonts/CourierBoldOblique.xml
index 5bd26092e..a82a75ad2 100644
--- a/src/codegen/fonts/CourierBoldOblique.xml
+++ b/src/codegen/fonts/CourierBoldOblique.xml
@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierBoldOblique</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>439</x-height>
<ascender>626</ascender>
<descender>-142</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="600"/>
- <char name="AE" width="600"/>
- <char name="Aacute" width="600"/>
- <char name="Acircumflex" width="600"/>
- <char name="Adieresis" width="600"/>
- <char name="Agrave" width="600"/>
- <char name="Aring" width="600"/>
- <char name="Atilde" width="600"/>
- <char name="B" width="600"/>
- <char name="C" width="600"/>
- <char name="Ccedilla" width="600"/>
- <char name="D" width="600"/>
- <char name="E" width="600"/>
- <char name="Eacute" width="600"/>
- <char name="Ecircumflex" width="600"/>
- <char name="Edieresis" width="600"/>
- <char name="Egrave" width="600"/>
- <char name="Eth" width="600"/>
- <char name="Euro" width="600"/>
- <char name="F" width="600"/>
- <char name="G" width="600"/>
- <char name="Gcaron" width="600"/>
- <char name="H" width="600"/>
- <char name="I" width="600"/>
- <char name="IJ" width="600"/>
- <char name="Iacute" width="600"/>
- <char name="Icircumflex" width="600"/>
- <char name="Idieresis" width="600"/>
- <char name="Idot" width="600"/>
- <char name="Igrave" width="600"/>
- <char name="J" width="600"/>
- <char name="K" width="600"/>
- <char name="L" width="600"/>
- <char name="LL" width="600"/>
- <char name="Lslash" width="600"/>
- <char name="M" width="600"/>
- <char name="N" width="600"/>
- <char name="Ntilde" width="600"/>
- <char name="O" width="600"/>
- <char name="OE" width="600"/>
- <char name="Oacute" width="600"/>
- <char name="Ocircumflex" width="600"/>
- <char name="Odieresis" width="600"/>
- <char name="Ograve" width="600"/>
- <char name="Oslash" width="600"/>
- <char name="Otilde" width="600"/>
- <char name="P" width="600"/>
- <char name="Q" width="600"/>
- <char name="R" width="600"/>
- <char name="S" width="600"/>
- <char name="Scaron" width="600"/>
- <char name="Scedilla" width="600"/>
- <char name="T" width="600"/>
- <char name="Thorn" width="600"/>
- <char name="U" width="600"/>
- <char name="Uacute" width="600"/>
- <char name="Ucircumflex" width="600"/>
- <char name="Udieresis" width="600"/>
- <char name="Ugrave" width="600"/>
- <char name="V" width="600"/>
- <char name="W" width="600"/>
- <char name="X" width="600"/>
- <char name="Y" width="600"/>
- <char name="Yacute" width="600"/>
- <char name="Ydieresis" width="600"/>
- <char name="Z" width="600"/>
- <char name="Zcaron" width="600"/>
- <char name="a" width="600"/>
- <char name="aacute" width="600"/>
- <char name="acircumflex" width="600"/>
- <char name="acute" width="600"/>
- <char name="adieresis" width="600"/>
- <char name="ae" width="600"/>
- <char name="agrave" width="600"/>
- <char name="ampersand" width="600"/>
- <char name="aring" width="600"/>
- <char name="arrowboth" width="600"/>
- <char name="arrowdown" width="600"/>
- <char name="arrowleft" width="600"/>
- <char name="arrowright" width="600"/>
- <char name="arrowup" width="600"/>
- <char name="asciicircum" width="600"/>
- <char name="asciitilde" width="600"/>
- <char name="asterisk" width="600"/>
- <char name="at" width="600"/>
- <char name="atilde" width="600"/>
- <char name="b" width="600"/>
- <char name="backslash" width="600"/>
- <char name="bar" width="600"/>
- <char name="braceleft" width="600"/>
- <char name="braceright" width="600"/>
- <char name="bracketleft" width="600"/>
- <char name="bracketright" width="600"/>
- <char name="breve" width="600"/>
- <char name="brokenbar" width="600"/>
- <char name="bullet" width="600"/>
- <char name="c" width="600"/>
- <char name="caron" width="600"/>
- <char name="ccedilla" width="600"/>
- <char name="cedilla" width="600"/>
- <char name="cent" width="600"/>
- <char name="center" width="600"/>
- <char name="circumflex" width="600"/>
- <char name="colon" width="600"/>
- <char name="comma" width="600"/>
- <char name="copyright" width="600"/>
- <char name="currency" width="600"/>
- <char name="d" width="600"/>
- <char name="dagger" width="600"/>
- <char name="daggerdbl" width="600"/>
- <char name="dectab" width="600"/>
- <char name="degree" width="600"/>
- <char name="dieresis" width="600"/>
- <char name="divide" width="600"/>
- <char name="dollar" width="600"/>
- <char name="dotaccent" width="600"/>
- <char name="dotlessi" width="600"/>
- <char name="down" width="600"/>
- <char name="e" width="600"/>
- <char name="eacute" width="600"/>
- <char name="ecircumflex" width="600"/>
- <char name="edieresis" width="600"/>
- <char name="egrave" width="600"/>
- <char name="eight" width="600"/>
- <char name="ellipsis" width="600"/>
- <char name="emdash" width="600"/>
- <char name="endash" width="600"/>
- <char name="equal" width="600"/>
- <char name="eth" width="600"/>
- <char name="exclam" width="600"/>
- <char name="exclamdown" width="600"/>
- <char name="f" width="600"/>
- <char name="fi" width="600"/>
- <char name="five" width="600"/>
- <char name="fl" width="600"/>
- <char name="florin" width="600"/>
- <char name="format" width="600"/>
- <char name="four" width="600"/>
- <char name="fraction" width="600"/>
- <char name="g" width="600"/>
- <char name="gcaron" width="600"/>
- <char name="germandbls" width="600"/>
- <char name="grave" width="600"/>
- <char name="graybox" width="600"/>
- <char name="greater" width="600"/>
- <char name="guillemotleft" width="600"/>
- <char name="guillemotright" width="600"/>
- <char name="guilsinglleft" width="600"/>
- <char name="guilsinglright" width="600"/>
- <char name="h" width="600"/>
- <char name="hungarumlaut" width="600"/>
- <char name="hyphen" width="600"/>
- <char name="i" width="600"/>
- <char name="iacute" width="600"/>
- <char name="icircumflex" width="600"/>
- <char name="idieresis" width="600"/>
- <char name="igrave" width="600"/>
- <char name="ij" width="600"/>
- <char name="indent" width="600"/>
- <char name="j" width="600"/>
- <char name="k" width="600"/>
- <char name="l" width="600"/>
- <char name="largebullet" width="600"/>
- <char name="left" width="600"/>
- <char name="less" width="600"/>
- <char name="lira" width="600"/>
- <char name="ll" width="600"/>
- <char name="logicalnot" width="600"/>
- <char name="lslash" width="600"/>
- <char name="m" width="600"/>
- <char name="macron" width="600"/>
- <char name="merge" width="600"/>
- <char name="minus" width="600"/>
- <char name="mu" width="600"/>
- <char name="multiply" width="600"/>
- <char name="n" width="600"/>
- <char name="nine" width="600"/>
- <char name="notegraphic" width="600"/>
- <char name="ntilde" width="600"/>
- <char name="numbersign" width="600"/>
- <char name="o" width="600"/>
- <char name="oacute" width="600"/>
- <char name="ocircumflex" width="600"/>
- <char name="odieresis" width="600"/>
- <char name="oe" width="600"/>
- <char name="ogonek" width="600"/>
- <char name="ograve" width="600"/>
- <char name="one" width="600"/>
- <char name="onehalf" width="600"/>
- <char name="onequarter" width="600"/>
- <char name="onesuperior" width="600"/>
- <char name="ordfeminine" width="600"/>
- <char name="ordmasculine" width="600"/>
- <char name="oslash" width="600"/>
- <char name="otilde" width="600"/>
- <char name="overscore" width="600"/>
- <char name="p" width="600"/>
- <char name="paragraph" width="600"/>
- <char name="parenleft" width="600"/>
- <char name="parenright" width="600"/>
- <char name="percent" width="600"/>
- <char name="period" width="600"/>
- <char name="periodcentered" width="600"/>
- <char name="perthousand" width="600"/>
- <char name="plus" width="600"/>
- <char name="plusminus" width="600"/>
- <char name="prescription" width="600"/>
- <char name="q" width="600"/>
- <char name="question" width="600"/>
- <char name="questiondown" width="600"/>
- <char name="quotedbl" width="600"/>
- <char name="quotedblbase" width="600"/>
- <char name="quotedblleft" width="600"/>
- <char name="quotedblright" width="600"/>
- <char name="quoteleft" width="600"/>
- <char name="quoteright" width="600"/>
- <char name="quotesinglbase" width="600"/>
- <char name="quotesingle" width="600"/>
- <char name="r" width="600"/>
- <char name="registered" width="600"/>
- <char name="return" width="600"/>
- <char name="ring" width="600"/>
- <char name="s" width="600"/>
- <char name="scaron" width="600"/>
- <char name="scedilla" width="600"/>
- <char name="section" width="600"/>
- <char name="semicolon" width="600"/>
- <char name="seven" width="600"/>
- <char name="six" width="600"/>
- <char name="slash" width="600"/>
- <char name="space" width="600"/>
+ <char-metrics>
+ <char name="A" width="600" llx="-9" lly="0" urx="632" ury="562"/>
+ <char name="AE" width="600" llx="-29" lly="0" urx="708" ury="562"/>
+ <char name="Aacute" width="600" llx="-9" lly="0" urx="655" ury="784"/>
+ <char name="Acircumflex" width="600" llx="-9" lly="0" urx="632" ury="780"/>
+ <char name="Adieresis" width="600" llx="-9" lly="0" urx="632" ury="761"/>
+ <char name="Agrave" width="600" llx="-9" lly="0" urx="632" ury="784"/>
+ <char name="Aring" width="600" llx="-9" lly="0" urx="632" ury="801"/>
+ <char name="Atilde" width="600" llx="-9" lly="0" urx="669" ury="759"/>
+ <char name="B" width="600" llx="30" lly="0" urx="630" ury="562"/>
+ <char name="C" width="600" llx="74" lly="-18" urx="675" ury="580"/>
+ <char name="Ccedilla" width="600" llx="74" lly="-206" urx="675" ury="580"/>
+ <char name="D" width="600" llx="30" lly="0" urx="664" ury="562"/>
+ <char name="E" width="600" llx="25" lly="0" urx="670" ury="562"/>
+ <char name="Eacute" width="600" llx="25" lly="0" urx="670" ury="784"/>
+ <char name="Ecircumflex" width="600" llx="25" lly="0" urx="670" ury="780"/>
+ <char name="Edieresis" width="600" llx="25" lly="0" urx="670" ury="761"/>
+ <char name="Egrave" width="600" llx="25" lly="0" urx="670" ury="784"/>
+ <char name="Eth" width="600" llx="30" lly="0" urx="664" ury="562"/>
+ <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="600" llx="39" lly="0" urx="684" ury="562"/>
+ <char name="G" width="600" llx="74" lly="-18" urx="675" ury="580"/>
+ <char name="H" width="600" llx="20" lly="0" urx="700" ury="562"/>
+ <char name="I" width="600" llx="77" lly="0" urx="643" ury="562"/>
+ <char name="Iacute" width="600" llx="77" lly="0" urx="643" ury="784"/>
+ <char name="Icircumflex" width="600" llx="77" lly="0" urx="643" ury="780"/>
+ <char name="Idieresis" width="600" llx="77" lly="0" urx="643" ury="761"/>
+ <char name="Igrave" width="600" llx="77" lly="0" urx="643" ury="784"/>
+ <char name="J" width="600" llx="58" lly="-18" urx="721" ury="562"/>
+ <char name="K" width="600" llx="21" lly="0" urx="692" ury="562"/>
+ <char name="L" width="600" llx="39" lly="0" urx="636" ury="562"/>
+ <char name="Lslash" width="600" llx="39" lly="0" urx="636" ury="562"/>
+ <char name="M" width="600" llx="-2" lly="0" urx="722" ury="562"/>
+ <char name="N" width="600" llx="8" lly="-12" urx="730" ury="562"/>
+ <char name="Ntilde" width="600" llx="8" lly="-12" urx="730" ury="759"/>
+ <char name="O" width="600" llx="74" lly="-18" urx="645" ury="580"/>
+ <char name="OE" width="600" llx="26" lly="0" urx="701" ury="562"/>
+ <char name="Oacute" width="600" llx="74" lly="-18" urx="645" ury="784"/>
+ <char name="Ocircumflex" width="600" llx="74" lly="-18" urx="645" ury="780"/>
+ <char name="Odieresis" width="600" llx="74" lly="-18" urx="645" ury="761"/>
+ <char name="Ograve" width="600" llx="74" lly="-18" urx="645" ury="784"/>
+ <char name="Oslash" width="600" llx="48" lly="-22" urx="673" ury="584"/>
+ <char name="Otilde" width="600" llx="74" lly="-18" urx="669" ury="759"/>
+ <char name="P" width="600" llx="48" lly="0" urx="643" ury="562"/>
+ <char name="Q" width="600" llx="83" lly="-138" urx="636" ury="580"/>
+ <char name="R" width="600" llx="24" lly="0" urx="617" ury="562"/>
+ <char name="S" width="600" llx="54" lly="-22" urx="673" ury="582"/>
+ <char name="Scaron" width="600" llx="54" lly="-22" urx="689" ury="790"/>
+ <char name="Scedilla" width="600" llx="54" lly="-206" urx="673" ury="582"/>
+ <char name="T" width="600" llx="86" lly="0" urx="679" ury="562"/>
+ <char name="Thorn" width="600" llx="48" lly="0" urx="620" ury="562"/>
+ <char name="U" width="600" llx="101" lly="-18" urx="716" ury="562"/>
+ <char name="Uacute" width="600" llx="101" lly="-18" urx="716" ury="784"/>
+ <char name="Ucircumflex" width="600" llx="101" lly="-18" urx="716" ury="780"/>
+ <char name="Udieresis" width="600" llx="101" lly="-18" urx="716" ury="761"/>
+ <char name="Ugrave" width="600" llx="101" lly="-18" urx="716" ury="784"/>
+ <char name="V" width="600" llx="84" lly="0" urx="733" ury="562"/>
+ <char name="W" width="600" llx="79" lly="0" urx="738" ury="562"/>
+ <char name="X" width="600" llx="12" lly="0" urx="690" ury="562"/>
+ <char name="Y" width="600" llx="109" lly="0" urx="709" ury="562"/>
+ <char name="Yacute" width="600" llx="109" lly="0" urx="709" ury="784"/>
+ <char name="Ydieresis" width="600" llx="109" lly="0" urx="709" ury="761"/>
+ <char name="Z" width="600" llx="62" lly="0" urx="637" ury="562"/>
+ <char name="Zcaron" width="600" llx="62" lly="0" urx="659" ury="790"/>
+ <char name="a" width="600" llx="61" lly="-15" urx="593" ury="454"/>
+ <char name="aacute" width="600" llx="61" lly="-15" urx="609" ury="661"/>
+ <char name="acircumflex" width="600" llx="61" lly="-15" urx="607" ury="657"/>
+ <char name="acute" width="600" llx="312" lly="508" urx="609" ury="661"/>
+ <char name="adieresis" width="600" llx="61" lly="-15" urx="595" ury="638"/>
+ <char name="ae" width="600" llx="21" lly="-15" urx="652" ury="454"/>
+ <char name="agrave" width="600" llx="61" lly="-15" urx="593" ury="661"/>
+ <char name="ampersand" width="600" llx="61" lly="-15" urx="595" ury="543"/>
+ <char name="aring" width="600" llx="61" lly="-15" urx="593" ury="678"/>
+ <char name="asciicircum" width="600" llx="171" lly="250" urx="556" ury="616"/>
+ <char name="asciitilde" width="600" llx="120" lly="153" urx="590" ury="356"/>
+ <char name="asterisk" width="600" llx="179" lly="219" urx="598" ury="601"/>
+ <char name="at" width="600" llx="65" lly="-15" urx="642" ury="616"/>
+ <char name="atilde" width="600" llx="61" lly="-15" urx="643" ury="636"/>
+ <char name="b" width="600" llx="13" lly="-15" urx="636" ury="626"/>
+ <char name="backslash" width="600" llx="222" lly="-77" urx="496" ury="626"/>
+ <char name="bar" width="600" llx="201" lly="-250" urx="505" ury="750"/>
+ <char name="braceleft" width="600" llx="203" lly="-102" urx="595" ury="616"/>
+ <char name="braceright" width="600" llx="114" lly="-102" urx="506" ury="616"/>
+ <char name="bracketleft" width="600" llx="223" lly="-102" urx="606" ury="616"/>
+ <char name="bracketright" width="600" llx="103" lly="-102" urx="486" ury="616"/>
+ <char name="breve" width="600" llx="217" lly="468" urx="652" ury="631"/>
+ <char name="brokenbar" width="600" llx="217" lly="-175" urx="489" ury="675"/>
+ <char name="bullet" width="600" llx="196" lly="132" urx="523" ury="430"/>
+ <char name="c" width="600" llx="81" lly="-15" urx="631" ury="459"/>
+ <char name="caron" width="600" llx="238" lly="493" urx="633" ury="667"/>
+ <char name="ccedilla" width="600" llx="81" lly="-206" urx="631" ury="459"/>
+ <char name="cedilla" width="600" llx="168" lly="-206" urx="368" ury="0"/>
+ <char name="cent" width="600" llx="121" lly="-49" urx="605" ury="614"/>
+ <char name="circumflex" width="600" llx="212" lly="483" urx="607" ury="657"/>
+ <char name="colon" width="600" llx="205" lly="-15" urx="480" ury="425"/>
+ <char name="comma" width="600" llx="99" lly="-111" urx="430" ury="174"/>
+ <char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/>
+ <char name="currency" width="600" llx="77" lly="49" urx="644" ury="517"/>
+ <char name="d" width="600" llx="60" lly="-15" urx="645" ury="626"/>
+ <char name="dagger" width="600" llx="175" lly="-70" urx="586" ury="580"/>
+ <char name="daggerdbl" width="600" llx="121" lly="-70" urx="587" ury="580"/>
+ <char name="degree" width="600" llx="173" lly="243" urx="570" ury="616"/>
+ <char name="dieresis" width="600" llx="246" lly="498" urx="595" ury="638"/>
+ <char name="divide" width="600" llx="114" lly="16" urx="596" ury="500"/>
+ <char name="dollar" width="600" llx="87" lly="-126" urx="630" ury="666"/>
+ <char name="dotaccent" width="600" llx="348" lly="498" urx="493" ury="638"/>
+ <char name="dotlessi" width="600" llx="77" lly="0" urx="546" ury="439"/>
+ <char name="e" width="600" llx="81" lly="-15" urx="605" ury="454"/>
+ <char name="eacute" width="600" llx="81" lly="-15" urx="609" ury="661"/>
+ <char name="ecircumflex" width="600" llx="81" lly="-15" urx="607" ury="657"/>
+ <char name="edieresis" width="600" llx="81" lly="-15" urx="605" ury="638"/>
+ <char name="egrave" width="600" llx="81" lly="-15" urx="605" ury="661"/>
+ <char name="eight" width="600" llx="115" lly="-15" urx="604" ury="616"/>
+ <char name="ellipsis" width="600" llx="35" lly="-15" urx="587" ury="116"/>
+ <char name="emdash" width="600" llx="33" lly="203" urx="677" ury="313"/>
+ <char name="endash" width="600" llx="108" lly="203" urx="602" ury="313"/>
+ <char name="equal" width="600" llx="96" lly="118" urx="614" ury="398"/>
+ <char name="eth" width="600" llx="93" lly="-27" urx="661" ury="626"/>
+ <char name="exclam" width="600" llx="215" lly="-15" urx="495" ury="572"/>
+ <char name="exclamdown" width="600" llx="196" lly="-146" urx="477" ury="449"/>
+ <char name="f" width="600" llx="83" lly="0" urx="677" ury="626"/>
+ <char name="fi" width="600" llx="12" lly="0" urx="644" ury="626"/>
+ <char name="five" width="600" llx="77" lly="-15" urx="621" ury="601"/>
+ <char name="fl" width="600" llx="12" lly="0" urx="644" ury="626"/>
+ <char name="florin" width="600" llx="-57" lly="-131" urx="702" ury="616"/>
+ <char name="four" width="600" llx="81" lly="0" urx="559" ury="616"/>
+ <char name="fraction" width="600" llx="22" lly="-60" urx="708" ury="661"/>
+ <char name="g" width="600" llx="40" lly="-146" urx="674" ury="454"/>
+ <char name="germandbls" width="600" llx="22" lly="-15" urx="629" ury="626"/>
+ <char name="grave" width="600" llx="272" lly="508" urx="503" ury="661"/>
+ <char name="greater" width="600" llx="97" lly="15" urx="589" ury="501"/>
+ <char name="guillemotleft" width="600" llx="62" lly="70" urx="639" ury="446"/>
+ <char name="guillemotright" width="600" llx="71" lly="70" urx="647" ury="446"/>
+ <char name="guilsinglleft" width="600" llx="195" lly="70" urx="545" ury="446"/>
+ <char name="guilsinglright" width="600" llx="165" lly="70" urx="514" ury="446"/>
+ <char name="h" width="600" llx="18" lly="0" urx="615" ury="626"/>
+ <char name="hungarumlaut" width="600" llx="171" lly="488" urx="729" ury="661"/>
+ <char name="hyphen" width="600" llx="143" lly="203" urx="567" ury="313"/>
+ <char name="i" width="600" llx="77" lly="0" urx="546" ury="658"/>
+ <char name="iacute" width="600" llx="77" lly="0" urx="609" ury="661"/>
+ <char name="icircumflex" width="600" llx="77" lly="0" urx="577" ury="657"/>
+ <char name="idieresis" width="600" llx="77" lly="0" urx="561" ury="618"/>
+ <char name="igrave" width="600" llx="77" lly="0" urx="546" ury="661"/>
+ <char name="j" width="600" llx="36" lly="-146" urx="580" ury="658"/>
+ <char name="k" width="600" llx="33" lly="0" urx="643" ury="626"/>
+ <char name="l" width="600" llx="77" lly="0" urx="546" ury="626"/>
+ <char name="less" width="600" llx="120" lly="15" urx="613" ury="501"/>
+ <char name="logicalnot" width="600" llx="135" lly="103" urx="617" ury="413"/>
+ <char name="lslash" width="600" llx="77" lly="0" urx="587" ury="626"/>
+ <char name="m" width="600" llx="-22" lly="0" urx="649" ury="454"/>
+ <char name="macron" width="600" llx="195" lly="505" urx="637" ury="585"/>
+ <char name="minus" width="600" llx="114" lly="203" urx="596" ury="313"/>
+ <char name="mu" width="600" llx="49" lly="-142" urx="592" ury="439"/>
+ <char name="multiply" width="600" llx="104" lly="39" urx="606" ury="478"/>
+ <char name="n" width="600" llx="18" lly="0" urx="615" ury="454"/>
+ <char name="nine" width="600" llx="75" lly="-15" urx="592" ury="616"/>
+ <char name="ntilde" width="600" llx="18" lly="0" urx="643" ury="636"/>
+ <char name="numbersign" width="600" llx="88" lly="-45" urx="641" ury="651"/>
+ <char name="o" width="600" llx="71" lly="-15" urx="622" ury="454"/>
+ <char name="oacute" width="600" llx="71" lly="-15" urx="649" ury="661"/>
+ <char name="ocircumflex" width="600" llx="71" lly="-15" urx="622" ury="657"/>
+ <char name="odieresis" width="600" llx="71" lly="-15" urx="622" ury="638"/>
+ <char name="oe" width="600" llx="18" lly="-15" urx="662" ury="454"/>
+ <char name="ogonek" width="600" llx="143" lly="-199" urx="367" ury="0"/>
+ <char name="ograve" width="600" llx="71" lly="-15" urx="622" ury="661"/>
+ <char name="one" width="600" llx="93" lly="0" urx="562" ury="616"/>
+ <char name="onehalf" width="600" llx="22" lly="-60" urx="716" ury="661"/>
+ <char name="onequarter" width="600" llx="13" lly="-60" urx="707" ury="661"/>
+ <char name="onesuperior" width="600" llx="212" lly="230" urx="514" ury="616"/>
+ <char name="ordfeminine" width="600" llx="188" lly="196" urx="526" ury="580"/>
+ <char name="ordmasculine" width="600" llx="188" lly="196" urx="543" ury="580"/>
+ <char name="oslash" width="600" llx="54" lly="-24" urx="638" ury="463"/>
+ <char name="otilde" width="600" llx="71" lly="-15" urx="643" ury="636"/>
+ <char name="p" width="600" llx="-32" lly="-142" urx="622" ury="454"/>
+ <char name="paragraph" width="600" llx="61" lly="-70" urx="700" ury="580"/>
+ <char name="parenleft" width="600" llx="265" lly="-102" urx="592" ury="616"/>
+ <char name="parenright" width="600" llx="117" lly="-102" urx="444" ury="616"/>
+ <char name="percent" width="600" llx="101" lly="-15" urx="625" ury="616"/>
+ <char name="period" width="600" llx="206" lly="-15" urx="427" ury="171"/>
+ <char name="periodcentered" width="600" llx="248" lly="165" urx="461" ury="351"/>
+ <char name="perthousand" width="600" llx="-45" lly="-15" urx="743" ury="616"/>
+ <char name="plus" width="600" llx="114" lly="39" urx="596" ury="478"/>
+ <char name="plusminus" width="600" llx="76" lly="24" urx="614" ury="515"/>
+ <char name="q" width="600" llx="60" lly="-142" urx="685" ury="454"/>
+ <char name="question" width="600" llx="183" lly="-14" urx="592" ury="580"/>
+ <char name="questiondown" width="600" llx="100" lly="-146" urx="509" ury="449"/>
+ <char name="quotedbl" width="600" llx="211" lly="277" urx="585" ury="562"/>
+ <char name="quotedblbase" width="600" llx="34" lly="-142" urx="560" ury="143"/>
+ <char name="quotedblleft" width="600" llx="190" lly="277" urx="594" ury="562"/>
+ <char name="quotedblright" width="600" llx="119" lly="277" urx="645" ury="562"/>
+ <char name="quoteleft" width="600" llx="297" lly="277" urx="487" ury="562"/>
+ <char name="quoteright" width="600" llx="229" lly="277" urx="543" ury="562"/>
+ <char name="quotesinglbase" width="600" llx="144" lly="-142" urx="458" ury="143"/>
+ <char name="quotesingle" width="600" llx="303" lly="277" urx="493" ury="562"/>
+ <char name="r" width="600" llx="47" lly="0" urx="655" ury="454"/>
+ <char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/>
+ <char name="ring" width="600" llx="319" lly="481" urx="528" ury="678"/>
+ <char name="s" width="600" llx="66" lly="-17" urx="608" ury="459"/>
+ <char name="scaron" width="600" llx="66" lly="-17" urx="633" ury="667"/>
+ <char name="scedilla" width="600" llx="66" lly="-206" urx="608" ury="459"/>
+ <char name="section" width="600" llx="74" lly="-70" urx="620" ury="580"/>
+ <char name="semicolon" width="600" llx="99" lly="-111" urx="481" ury="425"/>
+ <char name="seven" width="600" llx="147" lly="0" urx="622" ury="601"/>
+ <char name="six" width="600" llx="135" lly="-15" urx="652" ury="616"/>
+ <char name="slash" width="600" llx="90" lly="-77" urx="626" ury="626"/>
+ <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="600"/>
- <char name="square" width="600"/>
- <char name="sterling" width="600"/>
- <char name="stop" width="600"/>
- <char name="t" width="600"/>
- <char name="tab" width="600"/>
- <char name="thorn" width="600"/>
- <char name="three" width="600"/>
- <char name="threequarters" width="600"/>
- <char name="threesuperior" width="600"/>
- <char name="tilde" width="600"/>
- <char name="trademark" width="600"/>
- <char name="two" width="600"/>
- <char name="twosuperior" width="600"/>
- <char name="u" width="600"/>
- <char name="uacute" width="600"/>
- <char name="ucircumflex" width="600"/>
- <char name="udieresis" width="600"/>
- <char name="ugrave" width="600"/>
- <char name="underscore" width="600"/>
- <char name="up" width="600"/>
- <char name="v" width="600"/>
- <char name="w" width="600"/>
- <char name="x" width="600"/>
- <char name="y" width="600"/>
- <char name="yacute" width="600"/>
- <char name="ydieresis" width="600"/>
- <char name="yen" width="600"/>
- <char name="z" width="600"/>
- <char name="zcaron" width="600"/>
- <char name="zero" width="600"/>
- </widths>
+ <char name="sterling" width="600" llx="106" lly="-28" urx="650" ury="611"/>
+ <char name="t" width="600" llx="118" lly="-15" urx="567" ury="562"/>
+ <char name="thorn" width="600" llx="-32" lly="-142" urx="622" ury="626"/>
+ <char name="three" width="600" llx="71" lly="-15" urx="571" ury="616"/>
+ <char name="threequarters" width="600" llx="8" lly="-60" urx="699" ury="661"/>
+ <char name="threesuperior" width="600" llx="193" lly="222" urx="526" ury="616"/>
+ <char name="tilde" width="600" llx="199" lly="493" urx="643" ury="636"/>
+ <char name="trademark" width="600" llx="86" lly="230" urx="869" ury="562"/>
+ <char name="two" width="600" llx="61" lly="0" urx="594" ury="616"/>
+ <char name="twosuperior" width="600" llx="191" lly="230" urx="542" ury="616"/>
+ <char name="u" width="600" llx="70" lly="-15" urx="592" ury="439"/>
+ <char name="uacute" width="600" llx="70" lly="-15" urx="599" ury="661"/>
+ <char name="ucircumflex" width="600" llx="70" lly="-15" urx="597" ury="657"/>
+ <char name="udieresis" width="600" llx="70" lly="-15" urx="595" ury="638"/>
+ <char name="ugrave" width="600" llx="70" lly="-15" urx="592" ury="661"/>
+ <char name="underscore" width="600" llx="-27" lly="-125" urx="585" ury="-75"/>
+ <char name="v" width="600" llx="70" lly="0" urx="695" ury="439"/>
+ <char name="w" width="600" llx="53" lly="0" urx="712" ury="439"/>
+ <char name="x" width="600" llx="6" lly="0" urx="671" ury="439"/>
+ <char name="y" width="600" llx="-21" lly="-142" urx="695" ury="439"/>
+ <char name="yacute" width="600" llx="-21" lly="-142" urx="695" ury="661"/>
+ <char name="ydieresis" width="600" llx="-21" lly="-142" urx="695" ury="638"/>
+ <char name="yen" width="600" llx="98" lly="0" urx="710" ury="562"/>
+ <char name="z" width="600" llx="81" lly="0" urx="614" ury="439"/>
+ <char name="zcaron" width="600" llx="81" lly="0" urx="643" ury="667"/>
+ <char name="zero" width="600" llx="135" lly="-15" urx="593" ury="616"/>
+ </char-metrics>
</font-metrics>
diff --git a/src/codegen/fonts/CourierOblique.xml b/src/codegen/fonts/CourierOblique.xml
index 2dc300645..e08fa9b9b 100644
--- a/src/codegen/fonts/CourierOblique.xml
+++ b/src/codegen/fonts/CourierOblique.xml
@@ -22,275 +22,246 @@
<family-name>Courier</family-name>
<class-name>CourierOblique</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>562</cap-height>
<x-height>426</x-height>
<ascender>629</ascender>
<descender>-157</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="600"/>
- <char name="AE" width="600"/>
- <char name="Aacute" width="600"/>
- <char name="Acircumflex" width="600"/>
- <char name="Adieresis" width="600"/>
- <char name="Agrave" width="600"/>
- <char name="Aring" width="600"/>
- <char name="Atilde" width="600"/>
- <char name="B" width="600"/>
- <char name="C" width="600"/>
- <char name="Ccedilla" width="600"/>
- <char name="D" width="600"/>
- <char name="E" width="600"/>
- <char name="Eacute" width="600"/>
- <char name="Ecircumflex" width="600"/>
- <char name="Edieresis" width="600"/>
- <char name="Egrave" width="600"/>
- <char name="Eth" width="600"/>
- <char name="Euro" width="600"/>
- <char name="F" width="600"/>
- <char name="G" width="600"/>
- <char name="Gcaron" width="600"/>
- <char name="H" width="600"/>
- <char name="I" width="600"/>
- <char name="IJ" width="600"/>
- <char name="Iacute" width="600"/>
- <char name="Icircumflex" width="600"/>
- <char name="Idieresis" width="600"/>
- <char name="Idot" width="600"/>
- <char name="Igrave" width="600"/>
- <char name="J" width="600"/>
- <char name="K" width="600"/>
- <char name="L" width="600"/>
- <char name="LL" width="600"/>
- <char name="Lslash" width="600"/>
- <char name="M" width="600"/>
- <char name="N" width="600"/>
- <char name="Ntilde" width="600"/>
- <char name="O" width="600"/>
- <char name="OE" width="600"/>
- <char name="Oacute" width="600"/>
- <char name="Ocircumflex" width="600"/>
- <char name="Odieresis" width="600"/>
- <char name="Ograve" width="600"/>
- <char name="Oslash" width="600"/>
- <char name="Otilde" width="600"/>
- <char name="P" width="600"/>
- <char name="Q" width="600"/>
- <char name="R" width="600"/>
- <char name="S" width="600"/>
- <char name="Scaron" width="600"/>
- <char name="Scedilla" width="600"/>
- <char name="T" width="600"/>
- <char name="Thorn" width="600"/>
- <char name="U" width="600"/>
- <char name="Uacute" width="600"/>
- <char name="Ucircumflex" width="600"/>
- <char name="Udieresis" width="600"/>
- <char name="Ugrave" width="600"/>
- <char name="V" width="600"/>
- <char name="W" width="600"/>
- <char name="X" width="600"/>
- <char name="Y" width="600"/>
- <char name="Yacute" width="600"/>
- <char name="Ydieresis" width="600"/>
- <char name="Z" width="600"/>
- <char name="Zcaron" width="600"/>
- <char name="a" width="600"/>
- <char name="aacute" width="600"/>
- <char name="acircumflex" width="600"/>
- <char name="acute" width="600"/>
- <char name="adieresis" width="600"/>
- <char name="ae" width="600"/>
- <char name="agrave" width="600"/>
- <char name="ampersand" width="600"/>
- <char name="aring" width="600"/>
- <char name="arrowboth" width="600"/>
- <char name="arrowdown" width="600"/>
- <char name="arrowleft" width="600"/>
- <char name="arrowright" width="600"/>
- <char name="arrowup" width="600"/>
- <char name="asciicircum" width="600"/>
- <char name="asciitilde" width="600"/>
- <char name="asterisk" width="600"/>
- <char name="at" width="600"/>
- <char name="atilde" width="600"/>
- <char name="b" width="600"/>
- <char name="backslash" width="600"/>
- <char name="bar" width="600"/>
- <char name="braceleft" width="600"/>
- <char name="braceright" width="600"/>
- <char name="bracketleft" width="600"/>
- <char name="bracketright" width="600"/>
- <char name="breve" width="600"/>
- <char name="brokenbar" width="600"/>
- <char name="bullet" width="600"/>
- <char name="c" width="600"/>
- <char name="caron" width="600"/>
- <char name="ccedilla" width="600"/>
- <char name="cedilla" width="600"/>
- <char name="cent" width="600"/>
- <char name="center" width="600"/>
- <char name="circumflex" width="600"/>
- <char name="colon" width="600"/>
- <char name="comma" width="600"/>
- <char name="copyright" width="600"/>
- <char name="currency" width="600"/>
- <char name="d" width="600"/>
- <char name="dagger" width="600"/>
- <char name="daggerdbl" width="600"/>
- <char name="dectab" width="600"/>
- <char name="degree" width="600"/>
- <char name="dieresis" width="600"/>
- <char name="divide" width="600"/>
- <char name="dollar" width="600"/>
- <char name="dotaccent" width="600"/>
- <char name="dotlessi" width="600"/>
- <char name="down" width="600"/>
- <char name="e" width="600"/>
- <char name="eacute" width="600"/>
- <char name="ecircumflex" width="600"/>
- <char name="edieresis" width="600"/>
- <char name="egrave" width="600"/>
- <char name="eight" width="600"/>
- <char name="ellipsis" width="600"/>
- <char name="emdash" width="600"/>
- <char name="endash" width="600"/>
- <char name="equal" width="600"/>
- <char name="eth" width="600"/>
- <char name="exclam" width="600"/>
- <char name="exclamdown" width="600"/>
- <char name="f" width="600"/>
- <char name="fi" width="600"/>
- <char name="five" width="600"/>
- <char name="fl" width="600"/>
- <char name="florin" width="600"/>
- <char name="format" width="600"/>
- <char name="four" width="600"/>
- <char name="fraction" width="600"/>
- <char name="g" width="600"/>
- <char name="gcaron" width="600"/>
- <char name="germandbls" width="600"/>
- <char name="grave" width="600"/>
- <char name="graybox" width="600"/>
- <char name="greater" width="600"/>
- <char name="guillemotleft" width="600"/>
- <char name="guillemotright" width="600"/>
- <char name="guilsinglleft" width="600"/>
- <char name="guilsinglright" width="600"/>
- <char name="h" width="600"/>
- <char name="hungarumlaut" width="600"/>
- <char name="hyphen" width="600"/>
- <char name="i" width="600"/>
- <char name="iacute" width="600"/>
- <char name="icircumflex" width="600"/>
- <char name="idieresis" width="600"/>
- <char name="igrave" width="600"/>
- <char name="ij" width="600"/>
- <char name="indent" width="600"/>
- <char name="j" width="600"/>
- <char name="k" width="600"/>
- <char name="l" width="600"/>
- <char name="largebullet" width="600"/>
- <char name="left" width="600"/>
- <char name="less" width="600"/>
- <char name="lira" width="600"/>
- <char name="ll" width="600"/>
- <char name="logicalnot" width="600"/>
- <char name="lslash" width="600"/>
- <char name="m" width="600"/>
- <char name="macron" width="600"/>
- <char name="merge" width="600"/>
- <char name="minus" width="600"/>
- <char name="mu" width="600"/>
- <char name="multiply" width="600"/>
- <char name="n" width="600"/>
- <char name="nine" width="600"/>
- <char name="notegraphic" width="600"/>
- <char name="ntilde" width="600"/>
- <char name="numbersign" width="600"/>
- <char name="o" width="600"/>
- <char name="oacute" width="600"/>
- <char name="ocircumflex" width="600"/>
- <char name="odieresis" width="600"/>
- <char name="oe" width="600"/>
- <char name="ogonek" width="600"/>
- <char name="ograve" width="600"/>
- <char name="one" width="600"/>
- <char name="onehalf" width="600"/>
- <char name="onequarter" width="600"/>
- <char name="onesuperior" width="600"/>
- <char name="ordfeminine" width="600"/>
- <char name="ordmasculine" width="600"/>
- <char name="oslash" width="600"/>
- <char name="otilde" width="600"/>
- <char name="overscore" width="600"/>
- <char name="p" width="600"/>
- <char name="paragraph" width="600"/>
- <char name="parenleft" width="600"/>
- <char name="parenright" width="600"/>
- <char name="percent" width="600"/>
- <char name="period" width="600"/>
- <char name="periodcentered" width="600"/>
- <char name="perthousand" width="600"/>
- <char name="plus" width="600"/>
- <char name="plusminus" width="600"/>
- <char name="prescription" width="600"/>
- <char name="q" width="600"/>
- <char name="question" width="600"/>
- <char name="questiondown" width="600"/>
- <char name="quotedbl" width="600"/>
- <char name="quotedblbase" width="600"/>
- <char name="quotedblleft" width="600"/>
- <char name="quotedblright" width="600"/>
- <char name="quoteleft" width="600"/>
- <char name="quoteright" width="600"/>
- <char name="quotesinglbase" width="600"/>
- <char name="quotesingle" width="600"/>
- <char name="r" width="600"/>
- <char name="registered" width="600"/>
- <char name="return" width="600"/>
- <char name="ring" width="600"/>
- <char name="s" width="600"/>
- <char name="scaron" width="600"/>
- <char name="scedilla" width="600"/>
- <char name="section" width="600"/>
- <char name="semicolon" width="600"/>
- <char name="seven" width="600"/>
- <char name="six" width="600"/>
- <char name="slash" width="600"/>
- <char name="space" width="600"/>
+ <char-metrics>
+ <char name="A" width="600" llx="3" lly="0" urx="607" ury="562"/>
+ <char name="AE" width="600" llx="3" lly="0" urx="655" ury="562"/>
+ <char name="Aacute" width="600" llx="3" lly="0" urx="660" ury="805"/>
+ <char name="Acircumflex" width="600" llx="3" lly="0" urx="607" ury="787"/>
+ <char name="Adieresis" width="600" llx="3" lly="0" urx="607" ury="753"/>
+ <char name="Agrave" width="600" llx="3" lly="0" urx="607" ury="805"/>
+ <char name="Aring" width="600" llx="3" lly="0" urx="607" ury="750"/>
+ <char name="Atilde" width="600" llx="3" lly="0" urx="655" ury="729"/>
+ <char name="B" width="600" llx="43" lly="0" urx="616" ury="562"/>
+ <char name="C" width="600" llx="93" lly="-18" urx="655" ury="580"/>
+ <char name="Ccedilla" width="600" llx="93" lly="-151" urx="658" ury="580"/>
+ <char name="D" width="600" llx="43" lly="0" urx="645" ury="562"/>
+ <char name="E" width="600" llx="53" lly="0" urx="660" ury="562"/>
+ <char name="Eacute" width="600" llx="53" lly="0" urx="670" ury="805"/>
+ <char name="Ecircumflex" width="600" llx="53" lly="0" urx="660" ury="787"/>
+ <char name="Edieresis" width="600" llx="53" lly="0" urx="660" ury="753"/>
+ <char name="Egrave" width="600" llx="53" lly="0" urx="660" ury="805"/>
+ <char name="Eth" width="600" llx="43" lly="0" urx="645" ury="562"/>
+ <char name="Euro" width="600" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="600" llx="53" lly="0" urx="660" ury="562"/>
+ <char name="G" width="600" llx="83" lly="-18" urx="645" ury="580"/>
+ <char name="H" width="600" llx="32" lly="0" urx="687" ury="562"/>
+ <char name="I" width="600" llx="96" lly="0" urx="623" ury="562"/>
+ <char name="Iacute" width="600" llx="96" lly="0" urx="640" ury="805"/>
+ <char name="Icircumflex" width="600" llx="96" lly="0" urx="623" ury="787"/>
+ <char name="Idieresis" width="600" llx="96" lly="0" urx="623" ury="753"/>
+ <char name="Igrave" width="600" llx="96" lly="0" urx="623" ury="805"/>
+ <char name="J" width="600" llx="52" lly="-18" urx="685" ury="562"/>
+ <char name="K" width="600" llx="38" lly="0" urx="671" ury="562"/>
+ <char name="L" width="600" llx="47" lly="0" urx="607" ury="562"/>
+ <char name="Lslash" width="600" llx="47" lly="0" urx="607" ury="562"/>
+ <char name="M" width="600" llx="4" lly="0" urx="715" ury="562"/>
+ <char name="N" width="600" llx="7" lly="-13" urx="712" ury="562"/>
+ <char name="Ntilde" width="600" llx="7" lly="-13" urx="712" ury="729"/>
+ <char name="O" width="600" llx="94" lly="-18" urx="625" ury="580"/>
+ <char name="OE" width="600" llx="59" lly="0" urx="672" ury="562"/>
+ <char name="Oacute" width="600" llx="94" lly="-18" urx="640" ury="805"/>
+ <char name="Ocircumflex" width="600" llx="94" lly="-18" urx="625" ury="787"/>
+ <char name="Odieresis" width="600" llx="94" lly="-18" urx="625" ury="753"/>
+ <char name="Ograve" width="600" llx="94" lly="-18" urx="625" ury="805"/>
+ <char name="Oslash" width="600" llx="94" lly="-80" urx="625" ury="629"/>
+ <char name="Otilde" width="600" llx="94" lly="-18" urx="655" ury="729"/>
+ <char name="P" width="600" llx="79" lly="0" urx="644" ury="562"/>
+ <char name="Q" width="600" llx="95" lly="-138" urx="625" ury="580"/>
+ <char name="R" width="600" llx="38" lly="0" urx="598" ury="562"/>
+ <char name="S" width="600" llx="76" lly="-20" urx="650" ury="580"/>
+ <char name="Scaron" width="600" llx="76" lly="-20" urx="672" ury="802"/>
+ <char name="Scedilla" width="600" llx="76" lly="-151" urx="650" ury="580"/>
+ <char name="T" width="600" llx="108" lly="0" urx="665" ury="562"/>
+ <char name="Thorn" width="600" llx="79" lly="0" urx="606" ury="562"/>
+ <char name="U" width="600" llx="125" lly="-18" urx="702" ury="562"/>
+ <char name="Uacute" width="600" llx="125" lly="-18" urx="702" ury="805"/>
+ <char name="Ucircumflex" width="600" llx="125" lly="-18" urx="702" ury="787"/>
+ <char name="Udieresis" width="600" llx="125" lly="-18" urx="702" ury="753"/>
+ <char name="Ugrave" width="600" llx="125" lly="-18" urx="702" ury="805"/>
+ <char name="V" width="600" llx="105" lly="-13" urx="723" ury="562"/>
+ <char name="W" width="600" llx="106" lly="-13" urx="722" ury="562"/>
+ <char name="X" width="600" llx="23" lly="0" urx="675" ury="562"/>
+ <char name="Y" width="600" llx="133" lly="0" urx="695" ury="562"/>
+ <char name="Yacute" width="600" llx="133" lly="0" urx="695" ury="805"/>
+ <char name="Ydieresis" width="600" llx="133" lly="0" urx="695" ury="753"/>
+ <char name="Z" width="600" llx="86" lly="0" urx="610" ury="562"/>
+ <char name="Zcaron" width="600" llx="86" lly="0" urx="642" ury="802"/>
+ <char name="a" width="600" llx="76" lly="-15" urx="569" ury="441"/>
+ <char name="aacute" width="600" llx="76" lly="-15" urx="612" ury="672"/>
+ <char name="acircumflex" width="600" llx="76" lly="-15" urx="581" ury="654"/>
+ <char name="acute" width="600" llx="348" lly="497" urx="612" ury="672"/>
+ <char name="adieresis" width="600" llx="76" lly="-15" urx="575" ury="620"/>
+ <char name="ae" width="600" llx="41" lly="-15" urx="626" ury="441"/>
+ <char name="agrave" width="600" llx="76" lly="-15" urx="569" ury="672"/>
+ <char name="ampersand" width="600" llx="87" lly="-15" urx="580" ury="543"/>
+ <char name="aring" width="600" llx="76" lly="-15" urx="569" ury="627"/>
+ <char name="asciicircum" width="600" llx="175" lly="354" urx="587" ury="622"/>
+ <char name="asciitilde" width="600" llx="116" lly="197" urx="600" ury="320"/>
+ <char name="asterisk" width="600" llx="212" lly="257" urx="580" ury="607"/>
+ <char name="at" width="600" llx="127" lly="-15" urx="582" ury="622"/>
+ <char name="atilde" width="600" llx="76" lly="-15" urx="629" ury="606"/>
+ <char name="b" width="600" llx="29" lly="-15" urx="625" ury="629"/>
+ <char name="backslash" width="600" llx="249" lly="-80" urx="468" ury="629"/>
+ <char name="bar" width="600" llx="222" lly="-250" urx="485" ury="750"/>
+ <char name="braceleft" width="600" llx="233" lly="-108" urx="569" ury="622"/>
+ <char name="braceright" width="600" llx="140" lly="-108" urx="477" ury="622"/>
+ <char name="bracketleft" width="600" llx="246" lly="-108" urx="574" ury="622"/>
+ <char name="bracketright" width="600" llx="135" lly="-108" urx="463" ury="622"/>
+ <char name="breve" width="600" llx="279" lly="501" urx="576" ury="609"/>
+ <char name="brokenbar" width="600" llx="238" lly="-175" urx="469" ury="675"/>
+ <char name="bullet" width="600" llx="224" lly="130" urx="485" ury="383"/>
+ <char name="c" width="600" llx="106" lly="-15" urx="608" ury="441"/>
+ <char name="caron" width="600" llx="262" lly="492" urx="614" ury="669"/>
+ <char name="ccedilla" width="600" llx="106" lly="-151" urx="614" ury="441"/>
+ <char name="cedilla" width="600" llx="197" lly="-151" urx="344" ury="10"/>
+ <char name="cent" width="600" llx="151" lly="-49" urx="588" ury="614"/>
+ <char name="circumflex" width="600" llx="229" lly="477" urx="581" ury="654"/>
+ <char name="colon" width="600" llx="238" lly="-15" urx="441" ury="385"/>
+ <char name="comma" width="600" llx="157" lly="-112" urx="370" ury="122"/>
+ <char name="copyright" width="600" llx="53" lly="-18" urx="667" ury="580"/>
+ <char name="currency" width="600" llx="94" lly="58" urx="628" ury="506"/>
+ <char name="d" width="600" llx="85" lly="-15" urx="640" ury="629"/>
+ <char name="dagger" width="600" llx="217" lly="-78" urx="546" ury="580"/>
+ <char name="daggerdbl" width="600" llx="163" lly="-78" urx="546" ury="580"/>
+ <char name="degree" width="600" llx="214" lly="269" urx="576" ury="622"/>
+ <char name="dieresis" width="600" llx="272" lly="537" urx="579" ury="640"/>
+ <char name="divide" width="600" llx="136" lly="48" urx="573" ury="467"/>
+ <char name="dollar" width="600" llx="108" lly="-126" urx="596" ury="662"/>
+ <char name="dotaccent" width="600" llx="373" lly="537" urx="478" ury="640"/>
+ <char name="dotlessi" width="600" llx="95" lly="0" urx="515" ury="426"/>
+ <char name="e" width="600" llx="106" lly="-15" urx="598" ury="441"/>
+ <char name="eacute" width="600" llx="106" lly="-15" urx="612" ury="672"/>
+ <char name="ecircumflex" width="600" llx="106" lly="-15" urx="598" ury="654"/>
+ <char name="edieresis" width="600" llx="106" lly="-15" urx="598" ury="620"/>
+ <char name="egrave" width="600" llx="106" lly="-15" urx="598" ury="672"/>
+ <char name="eight" width="600" llx="132" lly="-15" urx="588" ury="622"/>
+ <char name="ellipsis" width="600" llx="46" lly="-15" urx="575" ury="111"/>
+ <char name="emdash" width="600" llx="49" lly="231" urx="661" ury="285"/>
+ <char name="endash" width="600" llx="124" lly="231" urx="586" ury="285"/>
+ <char name="equal" width="600" llx="109" lly="138" urx="600" ury="376"/>
+ <char name="eth" width="600" llx="102" lly="-15" urx="639" ury="629"/>
+ <char name="exclam" width="600" llx="243" lly="-15" urx="464" ury="572"/>
+ <char name="exclamdown" width="600" llx="225" lly="-157" urx="445" ury="430"/>
+ <char name="f" width="600" llx="114" lly="0" urx="662" ury="629"/>
+ <char name="fi" width="600" llx="3" lly="0" urx="619" ury="629"/>
+ <char name="five" width="600" llx="99" lly="-15" urx="589" ury="607"/>
+ <char name="fl" width="600" llx="3" lly="0" urx="619" ury="629"/>
+ <char name="florin" width="600" llx="-26" lly="-143" urx="671" ury="622"/>
+ <char name="four" width="600" llx="108" lly="0" urx="541" ury="622"/>
+ <char name="fraction" width="600" llx="84" lly="-57" urx="646" ury="665"/>
+ <char name="g" width="600" llx="61" lly="-157" urx="657" ury="441"/>
+ <char name="germandbls" width="600" llx="48" lly="-15" urx="617" ury="629"/>
+ <char name="grave" width="600" llx="294" lly="497" urx="484" ury="672"/>
+ <char name="greater" width="600" llx="85" lly="42" urx="599" ury="472"/>
+ <char name="guillemotleft" width="600" llx="92" lly="70" urx="652" ury="446"/>
+ <char name="guillemotright" width="600" llx="58" lly="70" urx="618" ury="446"/>
+ <char name="guilsinglleft" width="600" llx="204" lly="70" urx="540" ury="446"/>
+ <char name="guilsinglright" width="600" llx="170" lly="70" urx="506" ury="446"/>
+ <char name="h" width="600" llx="33" lly="0" urx="592" ury="629"/>
+ <char name="hungarumlaut" width="600" llx="239" lly="497" urx="683" ury="672"/>
+ <char name="hyphen" width="600" llx="152" lly="231" urx="558" ury="285"/>
+ <char name="i" width="600" llx="95" lly="0" urx="515" ury="657"/>
+ <char name="iacute" width="600" llx="95" lly="0" urx="612" ury="672"/>
+ <char name="icircumflex" width="600" llx="95" lly="0" urx="551" ury="654"/>
+ <char name="idieresis" width="600" llx="95" lly="0" urx="545" ury="620"/>
+ <char name="igrave" width="600" llx="95" lly="0" urx="515" ury="672"/>
+ <char name="j" width="600" llx="52" lly="-157" urx="550" ury="657"/>
+ <char name="k" width="600" llx="58" lly="0" urx="633" ury="629"/>
+ <char name="l" width="600" llx="95" lly="0" urx="515" ury="629"/>
+ <char name="less" width="600" llx="96" lly="42" urx="610" ury="472"/>
+ <char name="logicalnot" width="600" llx="155" lly="108" urx="591" ury="369"/>
+ <char name="lslash" width="600" llx="95" lly="0" urx="587" ury="629"/>
+ <char name="m" width="600" llx="-5" lly="0" urx="615" ury="441"/>
+ <char name="macron" width="600" llx="232" lly="525" urx="600" ury="565"/>
+ <char name="minus" width="600" llx="129" lly="232" urx="580" ury="283"/>
+ <char name="mu" width="600" llx="72" lly="-157" urx="572" ury="426"/>
+ <char name="multiply" width="600" llx="103" lly="43" urx="607" ury="470"/>
+ <char name="n" width="600" llx="26" lly="0" urx="585" ury="441"/>
+ <char name="nine" width="600" llx="93" lly="-15" urx="574" ury="622"/>
+ <char name="ntilde" width="600" llx="26" lly="0" urx="629" ury="606"/>
+ <char name="numbersign" width="600" llx="133" lly="-32" urx="596" ury="639"/>
+ <char name="o" width="600" llx="102" lly="-15" urx="588" ury="441"/>
+ <char name="oacute" width="600" llx="102" lly="-15" urx="612" ury="672"/>
+ <char name="ocircumflex" width="600" llx="102" lly="-15" urx="588" ury="654"/>
+ <char name="odieresis" width="600" llx="102" lly="-15" urx="588" ury="620"/>
+ <char name="oe" width="600" llx="54" lly="-15" urx="615" ury="441"/>
+ <char name="ogonek" width="600" llx="189" lly="-172" urx="377" ury="4"/>
+ <char name="ograve" width="600" llx="102" lly="-15" urx="588" ury="672"/>
+ <char name="one" width="600" llx="98" lly="0" urx="515" ury="622"/>
+ <char name="onehalf" width="600" llx="65" lly="-57" urx="669" ury="665"/>
+ <char name="onequarter" width="600" llx="65" lly="-57" urx="674" ury="665"/>
+ <char name="onesuperior" width="600" llx="231" lly="249" urx="491" ury="622"/>
+ <char name="ordfeminine" width="600" llx="209" lly="249" urx="512" ury="580"/>
+ <char name="ordmasculine" width="600" llx="210" lly="249" urx="535" ury="580"/>
+ <char name="oslash" width="600" llx="102" lly="-80" urx="588" ury="506"/>
+ <char name="otilde" width="600" llx="102" lly="-15" urx="629" ury="606"/>
+ <char name="p" width="600" llx="-24" lly="-157" urx="605" ury="441"/>
+ <char name="paragraph" width="600" llx="100" lly="-78" urx="630" ury="562"/>
+ <char name="parenleft" width="600" llx="313" lly="-108" urx="572" ury="622"/>
+ <char name="parenright" width="600" llx="137" lly="-108" urx="396" ury="622"/>
+ <char name="percent" width="600" llx="134" lly="-15" urx="599" ury="622"/>
+ <char name="period" width="600" llx="238" lly="-15" urx="382" ury="109"/>
+ <char name="periodcentered" width="600" llx="275" lly="189" urx="434" ury="327"/>
+ <char name="perthousand" width="600" llx="59" lly="-15" urx="627" ury="622"/>
+ <char name="plus" width="600" llx="129" lly="44" urx="580" ury="470"/>
+ <char name="plusminus" width="600" llx="96" lly="44" urx="594" ury="558"/>
+ <char name="q" width="600" llx="85" lly="-157" urx="682" ury="441"/>
+ <char name="question" width="600" llx="222" lly="-15" urx="583" ury="572"/>
+ <char name="questiondown" width="600" llx="105" lly="-157" urx="466" ury="430"/>
+ <char name="quotedbl" width="600" llx="273" lly="328" urx="532" ury="562"/>
+ <char name="quotedblbase" width="600" llx="115" lly="-134" urx="478" ury="100"/>
+ <char name="quotedblleft" width="600" llx="262" lly="328" urx="541" ury="562"/>
+ <char name="quotedblright" width="600" llx="213" lly="328" urx="576" ury="562"/>
+ <char name="quoteleft" width="600" llx="343" lly="328" urx="457" ury="562"/>
+ <char name="quoteright" width="600" llx="283" lly="328" urx="495" ury="562"/>
+ <char name="quotesinglbase" width="600" llx="185" lly="-134" urx="397" ury="100"/>
+ <char name="quotesingle" width="600" llx="345" lly="328" urx="460" ury="562"/>
+ <char name="r" width="600" llx="60" lly="0" urx="636" ury="441"/>
+ <char name="registered" width="600" llx="53" lly="-18" urx="667" ury="580"/>
+ <char name="ring" width="600" llx="332" lly="463" urx="500" ury="627"/>
+ <char name="s" width="600" llx="78" lly="-15" urx="584" ury="441"/>
+ <char name="scaron" width="600" llx="78" lly="-15" urx="614" ury="669"/>
+ <char name="scedilla" width="600" llx="78" lly="-151" urx="584" ury="441"/>
+ <char name="section" width="600" llx="104" lly="-78" urx="590" ury="580"/>
+ <char name="semicolon" width="600" llx="157" lly="-112" urx="441" ury="385"/>
+ <char name="seven" width="600" llx="182" lly="0" urx="612" ury="607"/>
+ <char name="six" width="600" llx="155" lly="-15" urx="629" ury="622"/>
+ <char name="slash" width="600" llx="112" lly="-80" urx="604" ury="629"/>
+ <char name="space" width="600" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="600"/>
- <char name="square" width="600"/>
- <char name="sterling" width="600"/>
- <char name="stop" width="600"/>
- <char name="t" width="600"/>
- <char name="tab" width="600"/>
- <char name="thorn" width="600"/>
- <char name="three" width="600"/>
- <char name="threequarters" width="600"/>
- <char name="threesuperior" width="600"/>
- <char name="tilde" width="600"/>
- <char name="trademark" width="600"/>
- <char name="two" width="600"/>
- <char name="twosuperior" width="600"/>
- <char name="u" width="600"/>
- <char name="uacute" width="600"/>
- <char name="ucircumflex" width="600"/>
- <char name="udieresis" width="600"/>
- <char name="ugrave" width="600"/>
- <char name="underscore" width="600"/>
- <char name="up" width="600"/>
- <char name="v" width="600"/>
- <char name="w" width="600"/>
- <char name="x" width="600"/>
- <char name="y" width="600"/>
- <char name="yacute" width="600"/>
- <char name="ydieresis" width="600"/>
- <char name="yen" width="600"/>
- <char name="z" width="600"/>
- <char name="zcaron" width="600"/>
- <char name="zero" width="600"/>
- </widths>
-</font-metrics> \ No newline at end of file
+ <char name="sterling" width="600" llx="124" lly="-21" urx="621" ury="611"/>
+ <char name="t" width="600" llx="167" lly="-15" urx="561" ury="561"/>
+ <char name="thorn" width="600" llx="-24" lly="-157" urx="605" ury="629"/>
+ <char name="three" width="600" llx="82" lly="-15" urx="538" ury="622"/>
+ <char name="threequarters" width="600" llx="73" lly="-56" urx="659" ury="666"/>
+ <char name="threesuperior" width="600" llx="213" lly="240" urx="501" ury="622"/>
+ <char name="tilde" width="600" llx="212" lly="489" urx="629" ury="606"/>
+ <char name="trademark" width="600" llx="75" lly="263" urx="742" ury="562"/>
+ <char name="two" width="600" llx="70" lly="0" urx="568" ury="622"/>
+ <char name="twosuperior" width="600" llx="230" lly="249" urx="535" ury="622"/>
+ <char name="u" width="600" llx="101" lly="-15" urx="572" ury="426"/>
+ <char name="uacute" width="600" llx="101" lly="-15" urx="602" ury="672"/>
+ <char name="ucircumflex" width="600" llx="101" lly="-15" urx="572" ury="654"/>
+ <char name="udieresis" width="600" llx="101" lly="-15" urx="575" ury="620"/>
+ <char name="ugrave" width="600" llx="101" lly="-15" urx="572" ury="672"/>
+ <char name="underscore" width="600" llx="-27" lly="-125" urx="584" ury="-75"/>
+ <char name="v" width="600" llx="90" lly="-10" urx="681" ury="426"/>
+ <char name="w" width="600" llx="76" lly="-10" urx="695" ury="426"/>
+ <char name="x" width="600" llx="20" lly="0" urx="655" ury="426"/>
+ <char name="y" width="600" llx="-4" lly="-157" urx="683" ury="426"/>
+ <char name="yacute" width="600" llx="-4" lly="-157" urx="683" ury="672"/>
+ <char name="ydieresis" width="600" llx="-4" lly="-157" urx="683" ury="620"/>
+ <char name="yen" width="600" llx="120" lly="0" urx="693" ury="562"/>
+ <char name="z" width="600" llx="99" lly="0" urx="593" ury="426"/>
+ <char name="zcaron" width="600" llx="99" lly="0" urx="624" ury="669"/>
+ <char name="zero" width="600" llx="154" lly="-15" urx="575" ury="622"/>
+ </char-metrics>
+</font-metrics>
diff --git a/src/codegen/fonts/Helvetica.xml b/src/codegen/fonts/Helvetica.xml
index 38ae23055..b6e11a72b 100644
--- a/src/codegen/fonts/Helvetica.xml
+++ b/src/codegen/fonts/Helvetica.xml
@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>Helvetica</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>523</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="667"/>
- <char name="AE" width="1000"/>
- <char name="Aacute" width="667"/>
- <char name="Acircumflex" width="667"/>
- <char name="Adieresis" width="667"/>
- <char name="Agrave" width="667"/>
- <char name="Aring" width="667"/>
- <char name="Atilde" width="667"/>
- <char name="B" width="667"/>
- <char name="C" width="722"/>
- <char name="Ccedilla" width="722"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="556"/>
- <char name="F" width="611"/>
- <char name="G" width="778"/>
- <char name="H" width="722"/>
- <char name="I" width="278"/>
- <char name="Iacute" width="278"/>
- <char name="Icircumflex" width="278"/>
- <char name="Idieresis" width="278"/>
- <char name="Igrave" width="278"/>
- <char name="J" width="500"/>
- <char name="K" width="667"/>
- <char name="L" width="556"/>
- <char name="Lslash" width="556"/>
- <char name="M" width="833"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="778"/>
- <char name="OE" width="1000"/>
- <char name="Oacute" width="778"/>
- <char name="Ocircumflex" width="778"/>
- <char name="Odieresis" width="778"/>
- <char name="Ograve" width="778"/>
- <char name="Oslash" width="778"/>
- <char name="Otilde" width="778"/>
- <char name="P" width="667"/>
- <char name="Q" width="778"/>
- <char name="R" width="722"/>
- <char name="S" width="667"/>
- <char name="Scaron" width="667"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="667"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="667"/>
- <char name="W" width="944"/>
- <char name="X" width="667"/>
- <char name="Y" width="667"/>
- <char name="Yacute" width="667"/>
- <char name="Ydieresis" width="667"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="556"/>
- <char name="aacute" width="556"/>
- <char name="acircumflex" width="556"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="556"/>
- <char name="ae" width="889"/>
- <char name="agrave" width="556"/>
- <char name="ampersand" width="667"/>
- <char name="aring" width="556"/>
- <char name="asciicircum" width="469"/>
- <char name="asciitilde" width="584"/>
- <char name="asterisk" width="389"/>
- <char name="at" width="1015"/>
- <char name="atilde" width="556"/>
- <char name="b" width="556"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="260"/>
- <char name="braceleft" width="334"/>
- <char name="braceright" width="334"/>
- <char name="bracketleft" width="278"/>
- <char name="bracketright" width="278"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="260"/>
- <char name="bullet" width="350"/>
- <char name="c" width="500"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="500"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="556"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="278"/>
- <char name="comma" width="278"/>
- <char name="copyright" width="737"/>
- <char name="currency" width="556"/>
- <char name="d" width="556"/>
- <char name="dagger" width="556"/>
- <char name="daggerdbl" width="556"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="584"/>
- <char name="dollar" width="556"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="556"/>
- <char name="eacute" width="556"/>
- <char name="ecircumflex" width="556"/>
- <char name="edieresis" width="556"/>
- <char name="egrave" width="556"/>
- <char name="eight" width="556"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="556"/>
- <char name="equal" width="584"/>
- <char name="eth" width="556"/>
- <char name="exclam" width="278"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="278"/>
- <char name="fi" width="500"/>
- <char name="five" width="556"/>
- <char name="fl" width="500"/>
- <char name="florin" width="556"/>
- <char name="four" width="556"/>
- <char name="fraction" width="167"/>
- <char name="g" width="556"/>
- <char name="germandbls" width="611"/>
- <char name="grave" width="333"/>
- <char name="greater" width="584"/>
- <char name="guillemotleft" width="556"/>
- <char name="guillemotright" width="556"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="556"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="222"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="222"/>
- <char name="k" width="500"/>
- <char name="l" width="222"/>
- <char name="less" width="584"/>
- <char name="logicalnot" width="584"/>
- <char name="lslash" width="222"/>
- <char name="m" width="833"/>
- <char name="macron" width="333"/>
- <char name="minus" width="324"/>
- <char name="mu" width="556"/>
- <char name="multiply" width="584"/>
- <char name="n" width="556"/>
- <char name="nine" width="556"/>
- <char name="ntilde" width="556"/>
- <char name="numbersign" width="556"/>
- <char name="o" width="556"/>
- <char name="oacute" width="556"/>
- <char name="ocircumflex" width="556"/>
- <char name="odieresis" width="556"/>
- <char name="oe" width="944"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="556"/>
- <char name="one" width="556"/>
- <char name="onehalf" width="834"/>
- <char name="onequarter" width="834"/>
- <char name="onesuperior" width="333"/>
- <char name="ordfeminine" width="370"/>
- <char name="ordmasculine" width="365"/>
- <char name="oslash" width="611"/>
- <char name="otilde" width="556"/>
- <char name="p" width="556"/>
- <char name="paragraph" width="537"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="889"/>
- <char name="period" width="278"/>
- <char name="periodcentered" width="278"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="584"/>
- <char name="plusminus" width="584"/>
- <char name="q" width="556"/>
- <char name="question" width="556"/>
- <char name="questiondown" width="611"/>
- <char name="quotedbl" width="355"/>
- <char name="quotedblbase" width="333"/>
- <char name="quotedblleft" width="333"/>
- <char name="quotedblright" width="333"/>
- <char name="quoteleft" width="222"/>
- <char name="quoteright" width="222"/>
- <char name="quotesinglbase" width="222"/>
- <char name="quotesingle" width="191"/>
- <char name="r" width="333"/>
- <char name="registered" width="737"/>
- <char name="ring" width="333"/>
- <char name="s" width="500"/>
- <char name="scaron" width="500"/>
- <char name="section" width="556"/>
- <char name="semicolon" width="278"/>
- <char name="seven" width="556"/>
- <char name="six" width="556"/>
- <char name="slash" width="278"/>
- <char name="space" width="278"/>
+ <char-metrics>
+ <char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/>
+ <char name="AE" width="1000" llx="8" lly="0" urx="951" ury="718"/>
+ <char name="Aacute" width="667" llx="14" lly="0" urx="654" ury="929"/>
+ <char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/>
+ <char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/>
+ <char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/>
+ <char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/>
+ <char name="Atilde" width="667" llx="14" lly="0" urx="654" ury="917"/>
+ <char name="B" width="667" llx="74" lly="0" urx="627" ury="718"/>
+ <char name="C" width="722" llx="44" lly="-19" urx="681" ury="737"/>
+ <char name="Ccedilla" width="722" llx="44" lly="-225" urx="681" ury="737"/>
+ <char name="D" width="722" llx="81" lly="0" urx="674" ury="718"/>
+ <char name="E" width="667" llx="86" lly="0" urx="616" ury="718"/>
+ <char name="Eacute" width="667" llx="86" lly="0" urx="616" ury="929"/>
+ <char name="Ecircumflex" width="667" llx="86" lly="0" urx="616" ury="929"/>
+ <char name="Edieresis" width="667" llx="86" lly="0" urx="616" ury="901"/>
+ <char name="Egrave" width="667" llx="86" lly="0" urx="616" ury="929"/>
+ <char name="Eth" width="722" llx="0" lly="0" urx="674" ury="718"/>
+ <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="86" lly="0" urx="583" ury="718"/>
+ <char name="G" width="778" llx="48" lly="-19" urx="704" ury="737"/>
+ <char name="H" width="722" llx="77" lly="0" urx="646" ury="718"/>
+ <char name="I" width="278" llx="91" lly="0" urx="188" ury="718"/>
+ <char name="Iacute" width="278" llx="91" lly="0" urx="292" ury="929"/>
+ <char name="Icircumflex" width="278" llx="-6" lly="0" urx="285" ury="929"/>
+ <char name="Idieresis" width="278" llx="13" lly="0" urx="266" ury="901"/>
+ <char name="Igrave" width="278" llx="-13" lly="0" urx="188" ury="929"/>
+ <char name="J" width="500" llx="17" lly="-19" urx="428" ury="718"/>
+ <char name="K" width="667" llx="76" lly="0" urx="663" ury="718"/>
+ <char name="L" width="556" llx="76" lly="0" urx="537" ury="718"/>
+ <char name="Lslash" width="556" llx="-20" lly="0" urx="537" ury="718"/>
+ <char name="M" width="833" llx="73" lly="0" urx="761" ury="718"/>
+ <char name="N" width="722" llx="76" lly="0" urx="646" ury="718"/>
+ <char name="Ntilde" width="722" llx="76" lly="0" urx="646" ury="917"/>
+ <char name="O" width="778" llx="39" lly="-19" urx="739" ury="737"/>
+ <char name="OE" width="1000" llx="36" lly="-19" urx="965" ury="737"/>
+ <char name="Oacute" width="778" llx="39" lly="-19" urx="739" ury="929"/>
+ <char name="Ocircumflex" width="778" llx="39" lly="-19" urx="739" ury="929"/>
+ <char name="Odieresis" width="778" llx="39" lly="-19" urx="739" ury="901"/>
+ <char name="Ograve" width="778" llx="39" lly="-19" urx="739" ury="929"/>
+ <char name="Oslash" width="778" llx="39" lly="-19" urx="740" ury="737"/>
+ <char name="Otilde" width="778" llx="39" lly="-19" urx="739" ury="917"/>
+ <char name="P" width="667" llx="86" lly="0" urx="622" ury="718"/>
+ <char name="Q" width="778" llx="39" lly="-56" urx="739" ury="737"/>
+ <char name="R" width="722" llx="88" lly="0" urx="684" ury="718"/>
+ <char name="S" width="667" llx="49" lly="-19" urx="620" ury="737"/>
+ <char name="Scaron" width="667" llx="49" lly="-19" urx="620" ury="929"/>
+ <char name="T" width="611" llx="14" lly="0" urx="597" ury="718"/>
+ <char name="Thorn" width="667" llx="86" lly="0" urx="622" ury="718"/>
+ <char name="U" width="722" llx="79" lly="-19" urx="644" ury="718"/>
+ <char name="Uacute" width="722" llx="79" lly="-19" urx="644" ury="929"/>
+ <char name="Ucircumflex" width="722" llx="79" lly="-19" urx="644" ury="929"/>
+ <char name="Udieresis" width="722" llx="79" lly="-19" urx="644" ury="901"/>
+ <char name="Ugrave" width="722" llx="79" lly="-19" urx="644" ury="929"/>
+ <char name="V" width="667" llx="20" lly="0" urx="647" ury="718"/>
+ <char name="W" width="944" llx="16" lly="0" urx="928" ury="718"/>
+ <char name="X" width="667" llx="19" lly="0" urx="648" ury="718"/>
+ <char name="Y" width="667" llx="14" lly="0" urx="653" ury="718"/>
+ <char name="Yacute" width="667" llx="14" lly="0" urx="653" ury="929"/>
+ <char name="Ydieresis" width="667" llx="14" lly="0" urx="653" ury="901"/>
+ <char name="Z" width="611" llx="23" lly="0" urx="588" ury="718"/>
+ <char name="Zcaron" width="611" llx="23" lly="0" urx="588" ury="929"/>
+ <char name="a" width="556" llx="36" lly="-15" urx="530" ury="538"/>
+ <char name="aacute" width="556" llx="36" lly="-15" urx="530" ury="734"/>
+ <char name="acircumflex" width="556" llx="36" lly="-15" urx="530" ury="734"/>
+ <char name="acute" width="333" llx="122" lly="593" urx="319" ury="734"/>
+ <char name="adieresis" width="556" llx="36" lly="-15" urx="530" ury="706"/>
+ <char name="ae" width="889" llx="36" lly="-15" urx="847" ury="538"/>
+ <char name="agrave" width="556" llx="36" lly="-15" urx="530" ury="734"/>
+ <char name="ampersand" width="667" llx="44" lly="-15" urx="645" ury="718"/>
+ <char name="aring" width="556" llx="36" lly="-15" urx="530" ury="756"/>
+ <char name="asciicircum" width="469" llx="-14" lly="264" urx="483" ury="688"/>
+ <char name="asciitilde" width="584" llx="61" lly="180" urx="523" ury="326"/>
+ <char name="asterisk" width="389" llx="39" lly="431" urx="349" ury="718"/>
+ <char name="at" width="1015" llx="147" lly="-19" urx="868" ury="737"/>
+ <char name="atilde" width="556" llx="36" lly="-15" urx="530" ury="722"/>
+ <char name="b" width="556" llx="58" lly="-15" urx="517" ury="718"/>
+ <char name="backslash" width="278" llx="-17" lly="-19" urx="295" ury="737"/>
+ <char name="bar" width="260" llx="94" lly="-225" urx="167" ury="775"/>
+ <char name="braceleft" width="334" llx="42" lly="-196" urx="292" ury="722"/>
+ <char name="braceright" width="334" llx="42" lly="-196" urx="292" ury="722"/>
+ <char name="bracketleft" width="278" llx="63" lly="-196" urx="250" ury="722"/>
+ <char name="bracketright" width="278" llx="28" lly="-196" urx="215" ury="722"/>
+ <char name="breve" width="333" llx="13" lly="595" urx="321" ury="731"/>
+ <char name="brokenbar" width="260" llx="94" lly="-150" urx="167" ury="700"/>
+ <char name="bullet" width="350" llx="18" lly="202" urx="333" ury="517"/>
+ <char name="c" width="500" llx="30" lly="-15" urx="477" ury="538"/>
+ <char name="caron" width="333" llx="21" lly="593" urx="312" ury="734"/>
+ <char name="ccedilla" width="500" llx="30" lly="-225" urx="477" ury="538"/>
+ <char name="cedilla" width="333" llx="45" lly="-225" urx="259" ury="0"/>
+ <char name="cent" width="556" llx="51" lly="-115" urx="513" ury="623"/>
+ <char name="circumflex" width="333" llx="21" lly="593" urx="312" ury="734"/>
+ <char name="colon" width="278" llx="87" lly="0" urx="191" ury="516"/>
+ <char name="comma" width="278" llx="87" lly="-147" urx="191" ury="106"/>
+ <char name="copyright" width="737" llx="-14" lly="-19" urx="752" ury="737"/>
+ <char name="currency" width="556" llx="28" lly="99" urx="528" ury="603"/>
+ <char name="d" width="556" llx="35" lly="-15" urx="499" ury="718"/>
+ <char name="dagger" width="556" llx="43" lly="-159" urx="514" ury="718"/>
+ <char name="daggerdbl" width="556" llx="43" lly="-159" urx="514" ury="718"/>
+ <char name="degree" width="400" llx="54" lly="411" urx="346" ury="703"/>
+ <char name="dieresis" width="333" llx="40" lly="604" urx="293" ury="706"/>
+ <char name="divide" width="584" llx="39" lly="-19" urx="545" ury="524"/>
+ <char name="dollar" width="556" llx="32" lly="-115" urx="520" ury="775"/>
+ <char name="dotaccent" width="333" llx="121" lly="604" urx="212" ury="706"/>
+ <char name="dotlessi" width="278" llx="95" lly="0" urx="183" ury="523"/>
+ <char name="e" width="556" llx="40" lly="-15" urx="516" ury="538"/>
+ <char name="eacute" width="556" llx="40" lly="-15" urx="516" ury="734"/>
+ <char name="ecircumflex" width="556" llx="40" lly="-15" urx="516" ury="734"/>
+ <char name="edieresis" width="556" llx="40" lly="-15" urx="516" ury="706"/>
+ <char name="egrave" width="556" llx="40" lly="-15" urx="516" ury="734"/>
+ <char name="eight" width="556" llx="38" lly="-19" urx="517" ury="703"/>
+ <char name="ellipsis" width="1000" llx="115" lly="0" urx="885" ury="106"/>
+ <char name="emdash" width="1000" llx="0" lly="240" urx="1000" ury="313"/>
+ <char name="endash" width="556" llx="0" lly="240" urx="556" ury="313"/>
+ <char name="equal" width="584" llx="39" lly="115" urx="545" ury="390"/>
+ <char name="eth" width="556" llx="35" lly="-15" urx="522" ury="737"/>
+ <char name="exclam" width="278" llx="90" lly="0" urx="187" ury="718"/>
+ <char name="exclamdown" width="333" llx="118" lly="-195" urx="215" ury="523"/>
+ <char name="f" width="278" llx="14" lly="0" urx="262" ury="728"/>
+ <char name="fi" width="500" llx="14" lly="0" urx="434" ury="728"/>
+ <char name="five" width="556" llx="32" lly="-19" urx="514" ury="688"/>
+ <char name="fl" width="500" llx="14" lly="0" urx="432" ury="728"/>
+ <char name="florin" width="556" llx="-11" lly="-207" urx="501" ury="737"/>
+ <char name="four" width="556" llx="25" lly="0" urx="523" ury="703"/>
+ <char name="fraction" width="167" llx="-166" lly="-19" urx="333" ury="703"/>
+ <char name="g" width="556" llx="40" lly="-220" urx="499" ury="538"/>
+ <char name="germandbls" width="611" llx="67" lly="-15" urx="571" ury="728"/>
+ <char name="grave" width="333" llx="14" lly="593" urx="211" ury="734"/>
+ <char name="greater" width="584" llx="48" lly="11" urx="536" ury="495"/>
+ <char name="guillemotleft" width="556" llx="97" lly="108" urx="459" ury="446"/>
+ <char name="guillemotright" width="556" llx="97" lly="108" urx="459" ury="446"/>
+ <char name="guilsinglleft" width="333" llx="88" lly="108" urx="245" ury="446"/>
+ <char name="guilsinglright" width="333" llx="88" lly="108" urx="245" ury="446"/>
+ <char name="h" width="556" llx="65" lly="0" urx="491" ury="718"/>
+ <char name="hungarumlaut" width="333" llx="31" lly="593" urx="409" ury="734"/>
+ <char name="hyphen" width="333" llx="44" lly="232" urx="289" ury="322"/>
+ <char name="i" width="222" llx="67" lly="0" urx="155" ury="718"/>
+ <char name="iacute" width="278" llx="95" lly="0" urx="292" ury="734"/>
+ <char name="icircumflex" width="278" llx="-6" lly="0" urx="285" ury="734"/>
+ <char name="idieresis" width="278" llx="13" lly="0" urx="266" ury="706"/>
+ <char name="igrave" width="278" llx="-13" lly="0" urx="184" ury="734"/>
+ <char name="j" width="222" llx="-16" lly="-210" urx="155" ury="718"/>
+ <char name="k" width="500" llx="67" lly="0" urx="501" ury="718"/>
+ <char name="l" width="222" llx="67" lly="0" urx="155" ury="718"/>
+ <char name="less" width="584" llx="48" lly="11" urx="536" ury="495"/>
+ <char name="logicalnot" width="584" llx="39" lly="108" urx="545" ury="390"/>
+ <char name="lslash" width="222" llx="-20" lly="0" urx="242" ury="718"/>
+ <char name="m" width="833" llx="65" lly="0" urx="769" ury="538"/>
+ <char name="macron" width="333" llx="10" lly="627" urx="323" ury="684"/>
+ <char name="minus" width="324" llx="39" lly="216" urx="545" ury="289"/>
+ <char name="mu" width="556" llx="68" lly="-207" urx="489" ury="523"/>
+ <char name="multiply" width="584" llx="39" lly="0" urx="545" ury="506"/>
+ <char name="n" width="556" llx="65" lly="0" urx="491" ury="538"/>
+ <char name="nine" width="556" llx="42" lly="-19" urx="514" ury="703"/>
+ <char name="ntilde" width="556" llx="65" lly="0" urx="491" ury="722"/>
+ <char name="numbersign" width="556" llx="28" lly="0" urx="529" ury="688"/>
+ <char name="o" width="556" llx="35" lly="-14" urx="521" ury="538"/>
+ <char name="oacute" width="556" llx="35" lly="-14" urx="521" ury="734"/>
+ <char name="ocircumflex" width="556" llx="35" lly="-14" urx="521" ury="734"/>
+ <char name="odieresis" width="556" llx="35" lly="-14" urx="521" ury="706"/>
+ <char name="oe" width="944" llx="35" lly="-15" urx="902" ury="538"/>
+ <char name="ogonek" width="333" llx="73" lly="-225" urx="287" ury="0"/>
+ <char name="ograve" width="556" llx="35" lly="-14" urx="521" ury="734"/>
+ <char name="one" width="556" llx="101" lly="0" urx="359" ury="703"/>
+ <char name="onehalf" width="834" llx="43" lly="-19" urx="773" ury="703"/>
+ <char name="onequarter" width="834" llx="73" lly="-19" urx="756" ury="703"/>
+ <char name="onesuperior" width="333" llx="43" lly="281" urx="222" ury="703"/>
+ <char name="ordfeminine" width="370" llx="24" lly="405" urx="346" ury="737"/>
+ <char name="ordmasculine" width="365" llx="25" lly="405" urx="341" ury="737"/>
+ <char name="oslash" width="611" llx="28" lly="-22" urx="537" ury="545"/>
+ <char name="otilde" width="556" llx="35" lly="-14" urx="521" ury="722"/>
+ <char name="p" width="556" llx="58" lly="-207" urx="517" ury="538"/>
+ <char name="paragraph" width="537" llx="18" lly="-173" urx="497" ury="718"/>
+ <char name="parenleft" width="333" llx="68" lly="-207" urx="299" ury="733"/>
+ <char name="parenright" width="333" llx="34" lly="-207" urx="265" ury="733"/>
+ <char name="percent" width="889" llx="39" lly="-19" urx="850" ury="703"/>
+ <char name="period" width="278" llx="87" lly="0" urx="191" ury="106"/>
+ <char name="periodcentered" width="278" llx="77" lly="190" urx="202" ury="315"/>
+ <char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="703"/>
+ <char name="plus" width="584" llx="39" lly="0" urx="545" ury="505"/>
+ <char name="plusminus" width="584" llx="39" lly="0" urx="545" ury="506"/>
+ <char name="q" width="556" llx="35" lly="-207" urx="494" ury="538"/>
+ <char name="question" width="556" llx="56" lly="0" urx="492" ury="727"/>
+ <char name="questiondown" width="611" llx="91" lly="-201" urx="527" ury="525"/>
+ <char name="quotedbl" width="355" llx="70" lly="463" urx="285" ury="718"/>
+ <char name="quotedblbase" width="333" llx="26" lly="-149" urx="295" ury="106"/>
+ <char name="quotedblleft" width="333" llx="38" lly="470" urx="307" ury="725"/>
+ <char name="quotedblright" width="333" llx="26" lly="463" urx="295" ury="718"/>
+ <char name="quoteleft" width="222" llx="65" lly="470" urx="169" ury="725"/>
+ <char name="quoteright" width="222" llx="53" lly="463" urx="157" ury="718"/>
+ <char name="quotesinglbase" width="222" llx="53" lly="-149" urx="157" ury="106"/>
+ <char name="quotesingle" width="191" llx="59" lly="463" urx="132" ury="718"/>
+ <char name="r" width="333" llx="77" lly="0" urx="332" ury="538"/>
+ <char name="registered" width="737" llx="-14" lly="-19" urx="752" ury="737"/>
+ <char name="ring" width="333" llx="75" lly="572" urx="259" ury="756"/>
+ <char name="s" width="500" llx="32" lly="-15" urx="464" ury="538"/>
+ <char name="scaron" width="500" llx="32" lly="-15" urx="464" ury="734"/>
+ <char name="section" width="556" llx="43" lly="-191" urx="512" ury="737"/>
+ <char name="semicolon" width="278" llx="87" lly="-147" urx="191" ury="516"/>
+ <char name="seven" width="556" llx="37" lly="0" urx="523" ury="688"/>
+ <char name="six" width="556" llx="38" lly="-19" urx="518" ury="703"/>
+ <char name="slash" width="278" llx="-17" lly="-19" urx="295" ury="737"/>
+ <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="278"/>
- <char name="sterling" width="556"/>
- <char name="t" width="278"/>
- <char name="thorn" width="556"/>
- <char name="three" width="556"/>
- <char name="threequarters" width="834"/>
- <char name="threesuperior" width="333"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="556"/>
- <char name="twosuperior" width="333"/>
- <char name="u" width="556"/>
- <char name="uacute" width="556"/>
- <char name="ucircumflex" width="556"/>
- <char name="udieresis" width="556"/>
- <char name="ugrave" width="556"/>
- <char name="underscore" width="556"/>
- <char name="v" width="500"/>
- <char name="w" width="722"/>
- <char name="x" width="500"/>
- <char name="y" width="500"/>
- <char name="yacute" width="500"/>
- <char name="ydieresis" width="500"/>
- <char name="yen" width="556"/>
- <char name="z" width="500"/>
- <char name="zcaron" width="500"/>
- <char name="zero" width="556"/>
- </widths>
+ <char name="sterling" width="556" llx="33" lly="-16" urx="539" ury="718"/>
+ <char name="t" width="278" llx="14" lly="-7" urx="257" ury="669"/>
+ <char name="thorn" width="556" llx="58" lly="-207" urx="517" ury="718"/>
+ <char name="three" width="556" llx="34" lly="-19" urx="522" ury="703"/>
+ <char name="threequarters" width="834" llx="45" lly="-19" urx="810" ury="703"/>
+ <char name="threesuperior" width="333" llx="5" lly="270" urx="325" ury="703"/>
+ <char name="tilde" width="333" llx="-4" lly="606" urx="337" ury="722"/>
+ <char name="trademark" width="1000" llx="46" lly="306" urx="903" ury="718"/>
+ <char name="two" width="556" llx="26" lly="0" urx="507" ury="703"/>
+ <char name="twosuperior" width="333" llx="4" lly="281" urx="323" ury="703"/>
+ <char name="u" width="556" llx="68" lly="-15" urx="489" ury="523"/>
+ <char name="uacute" width="556" llx="68" lly="-15" urx="489" ury="734"/>
+ <char name="ucircumflex" width="556" llx="68" lly="-15" urx="489" ury="734"/>
+ <char name="udieresis" width="556" llx="68" lly="-15" urx="489" ury="706"/>
+ <char name="ugrave" width="556" llx="68" lly="-15" urx="489" ury="734"/>
+ <char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/>
+ <char name="v" width="500" llx="8" lly="0" urx="492" ury="523"/>
+ <char name="w" width="722" llx="14" lly="0" urx="709" ury="523"/>
+ <char name="x" width="500" llx="11" lly="0" urx="490" ury="523"/>
+ <char name="y" width="500" llx="11" lly="-214" urx="489" ury="523"/>
+ <char name="yacute" width="500" llx="11" lly="-214" urx="489" ury="734"/>
+ <char name="ydieresis" width="500" llx="11" lly="-214" urx="489" ury="706"/>
+ <char name="yen" width="556" llx="3" lly="0" urx="553" ury="688"/>
+ <char name="z" width="500" llx="31" lly="0" urx="469" ury="523"/>
+ <char name="zcaron" width="500" llx="31" lly="0" urx="469" ury="734"/>
+ <char name="zero" width="556" llx="37" lly="-19" urx="519" ury="703"/>
+ </char-metrics>
<kerning kpx1="107">
<pair kern="-20" kpx2="111"/>
<pair kern="-20" kpx2="101"/>
diff --git a/src/codegen/fonts/HelveticaBold.xml b/src/codegen/fonts/HelveticaBold.xml
index 2620a128e..4efd01f22 100644
--- a/src/codegen/fonts/HelveticaBold.xml
+++ b/src/codegen/fonts/HelveticaBold.xml
@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaBold</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>532</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="722"/>
- <char name="AE" width="1000"/>
- <char name="Aacute" width="722"/>
- <char name="Acircumflex" width="722"/>
- <char name="Adieresis" width="722"/>
- <char name="Agrave" width="722"/>
- <char name="Aring" width="722"/>
- <char name="Atilde" width="722"/>
- <char name="B" width="722"/>
- <char name="C" width="722"/>
- <char name="Ccedilla" width="722"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="556"/>
- <char name="F" width="611"/>
- <char name="G" width="778"/>
- <char name="H" width="722"/>
- <char name="I" width="278"/>
- <char name="Iacute" width="278"/>
- <char name="Icircumflex" width="278"/>
- <char name="Idieresis" width="278"/>
- <char name="Igrave" width="278"/>
- <char name="J" width="556"/>
- <char name="K" width="722"/>
- <char name="L" width="611"/>
- <char name="Lslash" width="611"/>
- <char name="M" width="833"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="778"/>
- <char name="OE" width="1000"/>
- <char name="Oacute" width="778"/>
- <char name="Ocircumflex" width="778"/>
- <char name="Odieresis" width="778"/>
- <char name="Ograve" width="778"/>
- <char name="Oslash" width="778"/>
- <char name="Otilde" width="778"/>
- <char name="P" width="667"/>
- <char name="Q" width="778"/>
- <char name="R" width="722"/>
- <char name="S" width="667"/>
- <char name="Scaron" width="667"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="667"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="667"/>
- <char name="W" width="944"/>
- <char name="X" width="667"/>
- <char name="Y" width="667"/>
- <char name="Yacute" width="667"/>
- <char name="Ydieresis" width="667"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="556"/>
- <char name="aacute" width="556"/>
- <char name="acircumflex" width="556"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="556"/>
- <char name="ae" width="889"/>
- <char name="agrave" width="556"/>
- <char name="ampersand" width="722"/>
- <char name="aring" width="556"/>
- <char name="asciicircum" width="584"/>
- <char name="asciitilde" width="584"/>
- <char name="asterisk" width="389"/>
- <char name="at" width="975"/>
- <char name="atilde" width="556"/>
- <char name="b" width="611"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="280"/>
- <char name="braceleft" width="389"/>
- <char name="braceright" width="389"/>
- <char name="bracketleft" width="333"/>
- <char name="bracketright" width="333"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="280"/>
- <char name="bullet" width="350"/>
- <char name="c" width="556"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="556"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="556"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="333"/>
- <char name="comma" width="278"/>
- <char name="copyright" width="737"/>
- <char name="currency" width="556"/>
- <char name="d" width="611"/>
- <char name="dagger" width="556"/>
- <char name="daggerdbl" width="556"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="584"/>
- <char name="dollar" width="556"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="556"/>
- <char name="eacute" width="556"/>
- <char name="ecircumflex" width="556"/>
- <char name="edieresis" width="556"/>
- <char name="egrave" width="556"/>
- <char name="eight" width="556"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="556"/>
- <char name="equal" width="584"/>
- <char name="eth" width="611"/>
- <char name="exclam" width="333"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="333"/>
- <char name="fi" width="611"/>
- <char name="five" width="556"/>
- <char name="fl" width="611"/>
- <char name="florin" width="556"/>
- <char name="four" width="556"/>
- <char name="fraction" width="167"/>
- <char name="g" width="611"/>
- <char name="germandbls" width="611"/>
- <char name="grave" width="333"/>
- <char name="greater" width="584"/>
- <char name="guillemotleft" width="556"/>
- <char name="guillemotright" width="556"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="611"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="278"/>
- <char name="k" width="556"/>
- <char name="l" width="278"/>
- <char name="less" width="584"/>
- <char name="logicalnot" width="584"/>
- <char name="lslash" width="278"/>
- <char name="m" width="889"/>
- <char name="macron" width="333"/>
- <char name="minus" width="324"/>
- <char name="mu" width="611"/>
- <char name="multiply" width="584"/>
- <char name="n" width="611"/>
- <char name="nine" width="556"/>
- <char name="ntilde" width="611"/>
- <char name="numbersign" width="556"/>
- <char name="o" width="611"/>
- <char name="oacute" width="611"/>
- <char name="ocircumflex" width="611"/>
- <char name="odieresis" width="611"/>
- <char name="oe" width="944"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="611"/>
- <char name="one" width="556"/>
- <char name="onehalf" width="834"/>
- <char name="onequarter" width="834"/>
- <char name="onesuperior" width="333"/>
- <char name="ordfeminine" width="370"/>
- <char name="ordmasculine" width="365"/>
- <char name="oslash" width="611"/>
- <char name="otilde" width="611"/>
- <char name="p" width="611"/>
- <char name="paragraph" width="556"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="889"/>
- <char name="period" width="278"/>
- <char name="periodcentered" width="278"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="584"/>
- <char name="plusminus" width="584"/>
- <char name="q" width="611"/>
- <char name="question" width="611"/>
- <char name="questiondown" width="611"/>
- <char name="quotedbl" width="474"/>
- <char name="quotedblbase" width="500"/>
- <char name="quotedblleft" width="500"/>
- <char name="quotedblright" width="500"/>
- <char name="quoteleft" width="278"/>
- <char name="quoteright" width="278"/>
- <char name="quotesinglbase" width="278"/>
- <char name="quotesingle" width="238"/>
- <char name="r" width="389"/>
- <char name="registered" width="737"/>
- <char name="ring" width="333"/>
- <char name="s" width="556"/>
- <char name="scaron" width="556"/>
- <char name="section" width="556"/>
- <char name="semicolon" width="333"/>
- <char name="seven" width="556"/>
- <char name="six" width="556"/>
- <char name="slash" width="278"/>
- <char name="space" width="278"/>
+ <char-metrics>
+ <char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/>
+ <char name="AE" width="1000" llx="5" lly="0" urx="954" ury="718"/>
+ <char name="Aacute" width="722" llx="20" lly="0" urx="702" ury="936"/>
+ <char name="Acircumflex" width="722" llx="20" lly="0" urx="702" ury="936"/>
+ <char name="Adieresis" width="722" llx="20" lly="0" urx="702" ury="915"/>
+ <char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/>
+ <char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/>
+ <char name="Atilde" width="722" llx="20" lly="0" urx="702" ury="923"/>
+ <char name="B" width="722" llx="76" lly="0" urx="669" ury="718"/>
+ <char name="C" width="722" llx="44" lly="-19" urx="684" ury="737"/>
+ <char name="Ccedilla" width="722" llx="44" lly="-228" urx="684" ury="737"/>
+ <char name="D" width="722" llx="76" lly="0" urx="685" ury="718"/>
+ <char name="E" width="667" llx="76" lly="0" urx="621" ury="718"/>
+ <char name="Eacute" width="667" llx="76" lly="0" urx="621" ury="936"/>
+ <char name="Ecircumflex" width="667" llx="76" lly="0" urx="621" ury="936"/>
+ <char name="Edieresis" width="667" llx="76" lly="0" urx="621" ury="915"/>
+ <char name="Egrave" width="667" llx="76" lly="0" urx="621" ury="936"/>
+ <char name="Eth" width="722" llx="-5" lly="0" urx="685" ury="718"/>
+ <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="76" lly="0" urx="587" ury="718"/>
+ <char name="G" width="778" llx="44" lly="-19" urx="713" ury="737"/>
+ <char name="H" width="722" llx="71" lly="0" urx="651" ury="718"/>
+ <char name="I" width="278" llx="64" lly="0" urx="214" ury="718"/>
+ <char name="Iacute" width="278" llx="64" lly="0" urx="329" ury="936"/>
+ <char name="Icircumflex" width="278" llx="-37" lly="0" urx="316" ury="936"/>
+ <char name="Idieresis" width="278" llx="-21" lly="0" urx="300" ury="915"/>
+ <char name="Igrave" width="278" llx="-50" lly="0" urx="214" ury="936"/>
+ <char name="J" width="556" llx="22" lly="-18" urx="484" ury="718"/>
+ <char name="K" width="722" llx="87" lly="0" urx="722" ury="718"/>
+ <char name="L" width="611" llx="76" lly="0" urx="583" ury="718"/>
+ <char name="Lslash" width="611" llx="-20" lly="0" urx="583" ury="718"/>
+ <char name="M" width="833" llx="69" lly="0" urx="765" ury="718"/>
+ <char name="N" width="722" llx="69" lly="0" urx="654" ury="718"/>
+ <char name="Ntilde" width="722" llx="69" lly="0" urx="654" ury="923"/>
+ <char name="O" width="778" llx="44" lly="-19" urx="734" ury="737"/>
+ <char name="OE" width="1000" llx="37" lly="-19" urx="961" ury="737"/>
+ <char name="Oacute" width="778" llx="44" lly="-19" urx="734" ury="936"/>
+ <char name="Ocircumflex" width="778" llx="44" lly="-19" urx="734" ury="936"/>
+ <char name="Odieresis" width="778" llx="44" lly="-19" urx="734" ury="915"/>
+ <char name="Ograve" width="778" llx="44" lly="-19" urx="734" ury="936"/>
+ <char name="Oslash" width="778" llx="33" lly="-27" urx="744" ury="745"/>
+ <char name="Otilde" width="778" llx="44" lly="-19" urx="734" ury="923"/>
+ <char name="P" width="667" llx="76" lly="0" urx="627" ury="718"/>
+ <char name="Q" width="778" llx="44" lly="-52" urx="737" ury="737"/>
+ <char name="R" width="722" llx="76" lly="0" urx="677" ury="718"/>
+ <char name="S" width="667" llx="39" lly="-19" urx="629" ury="737"/>
+ <char name="Scaron" width="667" llx="39" lly="-19" urx="629" ury="936"/>
+ <char name="T" width="611" llx="14" lly="0" urx="598" ury="718"/>
+ <char name="Thorn" width="667" llx="76" lly="0" urx="627" ury="718"/>
+ <char name="U" width="722" llx="72" lly="-19" urx="651" ury="718"/>
+ <char name="Uacute" width="722" llx="72" lly="-19" urx="651" ury="936"/>
+ <char name="Ucircumflex" width="722" llx="72" lly="-19" urx="651" ury="936"/>
+ <char name="Udieresis" width="722" llx="72" lly="-19" urx="651" ury="915"/>
+ <char name="Ugrave" width="722" llx="72" lly="-19" urx="651" ury="936"/>
+ <char name="V" width="667" llx="19" lly="0" urx="648" ury="718"/>
+ <char name="W" width="944" llx="16" lly="0" urx="929" ury="718"/>
+ <char name="X" width="667" llx="14" lly="0" urx="653" ury="718"/>
+ <char name="Y" width="667" llx="15" lly="0" urx="653" ury="718"/>
+ <char name="Yacute" width="667" llx="15" lly="0" urx="653" ury="936"/>
+ <char name="Ydieresis" width="667" llx="15" lly="0" urx="653" ury="915"/>
+ <char name="Z" width="611" llx="25" lly="0" urx="586" ury="718"/>
+ <char name="Zcaron" width="611" llx="25" lly="0" urx="586" ury="936"/>
+ <char name="a" width="556" llx="29" lly="-14" urx="527" ury="546"/>
+ <char name="aacute" width="556" llx="29" lly="-14" urx="527" ury="750"/>
+ <char name="acircumflex" width="556" llx="29" lly="-14" urx="527" ury="750"/>
+ <char name="acute" width="333" llx="108" lly="604" urx="356" ury="750"/>
+ <char name="adieresis" width="556" llx="29" lly="-14" urx="527" ury="729"/>
+ <char name="ae" width="889" llx="29" lly="-14" urx="858" ury="546"/>
+ <char name="agrave" width="556" llx="29" lly="-14" urx="527" ury="750"/>
+ <char name="ampersand" width="722" llx="54" lly="-19" urx="701" ury="718"/>
+ <char name="aring" width="556" llx="29" lly="-14" urx="527" ury="776"/>
+ <char name="asciicircum" width="584" llx="62" lly="323" urx="522" ury="698"/>
+ <char name="asciitilde" width="584" llx="61" lly="163" urx="523" ury="343"/>
+ <char name="asterisk" width="389" llx="27" lly="387" urx="362" ury="718"/>
+ <char name="at" width="975" llx="118" lly="-19" urx="856" ury="737"/>
+ <char name="atilde" width="556" llx="29" lly="-14" urx="527" ury="737"/>
+ <char name="b" width="611" llx="61" lly="-14" urx="578" ury="718"/>
+ <char name="backslash" width="278" llx="-33" lly="-19" urx="311" ury="737"/>
+ <char name="bar" width="280" llx="84" lly="-225" urx="196" ury="775"/>
+ <char name="braceleft" width="389" llx="48" lly="-196" urx="365" ury="722"/>
+ <char name="braceright" width="389" llx="24" lly="-196" urx="341" ury="722"/>
+ <char name="bracketleft" width="333" llx="63" lly="-196" urx="309" ury="722"/>
+ <char name="bracketright" width="333" llx="24" lly="-196" urx="270" ury="722"/>
+ <char name="breve" width="333" llx="-2" lly="604" urx="335" ury="750"/>
+ <char name="brokenbar" width="280" llx="84" lly="-150" urx="196" ury="700"/>
+ <char name="bullet" width="350" llx="10" lly="194" urx="340" ury="524"/>
+ <char name="c" width="556" llx="34" lly="-14" urx="524" ury="546"/>
+ <char name="caron" width="333" llx="-10" lly="604" urx="343" ury="750"/>
+ <char name="ccedilla" width="556" llx="34" lly="-228" urx="524" ury="546"/>
+ <char name="cedilla" width="333" llx="6" lly="-228" urx="245" ury="0"/>
+ <char name="cent" width="556" llx="34" lly="-118" urx="524" ury="628"/>
+ <char name="circumflex" width="333" llx="-10" lly="604" urx="343" ury="750"/>
+ <char name="colon" width="333" llx="92" lly="0" urx="242" ury="512"/>
+ <char name="comma" width="278" llx="64" lly="-168" urx="214" ury="146"/>
+ <char name="copyright" width="737" llx="-11" lly="-19" urx="749" ury="737"/>
+ <char name="currency" width="556" llx="-3" lly="76" urx="559" ury="636"/>
+ <char name="d" width="611" llx="34" lly="-14" urx="551" ury="718"/>
+ <char name="dagger" width="556" llx="36" lly="-171" urx="520" ury="718"/>
+ <char name="daggerdbl" width="556" llx="36" lly="-171" urx="520" ury="718"/>
+ <char name="degree" width="400" llx="57" lly="426" urx="343" ury="712"/>
+ <char name="dieresis" width="333" llx="6" lly="614" urx="327" ury="729"/>
+ <char name="divide" width="584" llx="40" lly="-42" urx="544" ury="548"/>
+ <char name="dollar" width="556" llx="30" lly="-115" urx="523" ury="775"/>
+ <char name="dotaccent" width="333" llx="104" lly="614" urx="230" ury="729"/>
+ <char name="dotlessi" width="278" llx="69" lly="0" urx="209" ury="532"/>
+ <char name="e" width="556" llx="23" lly="-14" urx="528" ury="546"/>
+ <char name="eacute" width="556" llx="23" lly="-14" urx="528" ury="750"/>
+ <char name="ecircumflex" width="556" llx="23" lly="-14" urx="528" ury="750"/>
+ <char name="edieresis" width="556" llx="23" lly="-14" urx="528" ury="729"/>
+ <char name="egrave" width="556" llx="23" lly="-14" urx="528" ury="750"/>
+ <char name="eight" width="556" llx="32" lly="-19" urx="524" ury="710"/>
+ <char name="ellipsis" width="1000" llx="92" lly="0" urx="908" ury="146"/>
+ <char name="emdash" width="1000" llx="0" lly="227" urx="1000" ury="333"/>
+ <char name="endash" width="556" llx="0" lly="227" urx="556" ury="333"/>
+ <char name="equal" width="584" llx="40" lly="87" urx="544" ury="419"/>
+ <char name="eth" width="611" llx="34" lly="-14" urx="578" ury="737"/>
+ <char name="exclam" width="333" llx="90" lly="0" urx="244" ury="718"/>
+ <char name="exclamdown" width="333" llx="90" lly="-186" urx="244" ury="532"/>
+ <char name="f" width="333" llx="10" lly="0" urx="318" ury="727"/>
+ <char name="fi" width="611" llx="10" lly="0" urx="542" ury="727"/>
+ <char name="five" width="556" llx="27" lly="-19" urx="516" ury="698"/>
+ <char name="fl" width="611" llx="10" lly="0" urx="542" ury="727"/>
+ <char name="florin" width="556" llx="-10" lly="-210" urx="516" ury="737"/>
+ <char name="four" width="556" llx="27" lly="0" urx="526" ury="710"/>
+ <char name="fraction" width="167" llx="-170" lly="-19" urx="336" ury="710"/>
+ <char name="g" width="611" llx="40" lly="-217" urx="553" ury="546"/>
+ <char name="germandbls" width="611" llx="69" lly="-14" urx="579" ury="731"/>
+ <char name="grave" width="333" llx="-23" lly="604" urx="225" ury="750"/>
+ <char name="greater" width="584" llx="38" lly="-8" urx="546" ury="514"/>
+ <char name="guillemotleft" width="556" llx="88" lly="76" urx="468" ury="484"/>
+ <char name="guillemotright" width="556" llx="88" lly="76" urx="468" ury="484"/>
+ <char name="guilsinglleft" width="333" llx="83" lly="76" urx="250" ury="484"/>
+ <char name="guilsinglright" width="333" llx="83" lly="76" urx="250" ury="484"/>
+ <char name="h" width="611" llx="65" lly="0" urx="546" ury="718"/>
+ <char name="hungarumlaut" width="333" llx="9" lly="604" urx="486" ury="750"/>
+ <char name="hyphen" width="333" llx="27" lly="215" urx="306" ury="345"/>
+ <char name="i" width="278" llx="69" lly="0" urx="209" ury="725"/>
+ <char name="iacute" width="278" llx="69" lly="0" urx="329" ury="750"/>
+ <char name="icircumflex" width="278" llx="-37" lly="0" urx="316" ury="750"/>
+ <char name="idieresis" width="278" llx="-21" lly="0" urx="300" ury="729"/>
+ <char name="igrave" width="278" llx="-50" lly="0" urx="209" ury="750"/>
+ <char name="j" width="278" llx="3" lly="-214" urx="209" ury="725"/>
+ <char name="k" width="556" llx="69" lly="0" urx="562" ury="718"/>
+ <char name="l" width="278" llx="69" lly="0" urx="209" ury="718"/>
+ <char name="less" width="584" llx="38" lly="-8" urx="546" ury="514"/>
+ <char name="logicalnot" width="584" llx="40" lly="108" urx="544" ury="419"/>
+ <char name="lslash" width="278" llx="-18" lly="0" urx="296" ury="718"/>
+ <char name="m" width="889" llx="64" lly="0" urx="826" ury="546"/>
+ <char name="macron" width="333" llx="-6" lly="604" urx="339" ury="678"/>
+ <char name="minus" width="324" llx="40" lly="197" urx="544" ury="309"/>
+ <char name="mu" width="611" llx="66" lly="-207" urx="545" ury="532"/>
+ <char name="multiply" width="584" llx="40" lly="1" urx="545" ury="505"/>
+ <char name="n" width="611" llx="65" lly="0" urx="546" ury="546"/>
+ <char name="nine" width="556" llx="30" lly="-19" urx="522" ury="710"/>
+ <char name="ntilde" width="611" llx="65" lly="0" urx="546" ury="737"/>
+ <char name="numbersign" width="556" llx="18" lly="0" urx="538" ury="698"/>
+ <char name="o" width="611" llx="34" lly="-14" urx="578" ury="546"/>
+ <char name="oacute" width="611" llx="34" lly="-14" urx="578" ury="750"/>
+ <char name="ocircumflex" width="611" llx="34" lly="-14" urx="578" ury="750"/>
+ <char name="odieresis" width="611" llx="34" lly="-14" urx="578" ury="729"/>
+ <char name="oe" width="944" llx="34" lly="-14" urx="912" ury="546"/>
+ <char name="ogonek" width="333" llx="71" lly="-228" urx="304" ury="0"/>
+ <char name="ograve" width="611" llx="34" lly="-14" urx="578" ury="750"/>
+ <char name="one" width="556" llx="69" lly="0" urx="378" ury="710"/>
+ <char name="onehalf" width="834" llx="26" lly="-19" urx="794" ury="710"/>
+ <char name="onequarter" width="834" llx="26" lly="-19" urx="766" ury="710"/>
+ <char name="onesuperior" width="333" llx="26" lly="283" urx="237" ury="710"/>
+ <char name="ordfeminine" width="370" llx="22" lly="401" urx="347" ury="737"/>
+ <char name="ordmasculine" width="365" llx="6" lly="401" urx="360" ury="737"/>
+ <char name="oslash" width="611" llx="22" lly="-29" urx="589" ury="560"/>
+ <char name="otilde" width="611" llx="34" lly="-14" urx="578" ury="737"/>
+ <char name="p" width="611" llx="62" lly="-207" urx="578" ury="546"/>
+ <char name="paragraph" width="556" llx="-8" lly="-191" urx="539" ury="700"/>
+ <char name="parenleft" width="333" llx="35" lly="-208" urx="314" ury="734"/>
+ <char name="parenright" width="333" llx="19" lly="-208" urx="298" ury="734"/>
+ <char name="percent" width="889" llx="28" lly="-19" urx="861" ury="710"/>
+ <char name="period" width="278" llx="64" lly="0" urx="214" ury="146"/>
+ <char name="periodcentered" width="278" llx="58" lly="172" urx="220" ury="334"/>
+ <char name="perthousand" width="1000" llx="-3" lly="-19" urx="1003" ury="710"/>
+ <char name="plus" width="584" llx="40" lly="0" urx="544" ury="506"/>
+ <char name="plusminus" width="584" llx="40" lly="0" urx="544" ury="506"/>
+ <char name="q" width="611" llx="34" lly="-207" urx="552" ury="546"/>
+ <char name="question" width="611" llx="60" lly="0" urx="556" ury="727"/>
+ <char name="questiondown" width="611" llx="55" lly="-195" urx="551" ury="532"/>
+ <char name="quotedbl" width="474" llx="98" lly="447" urx="376" ury="718"/>
+ <char name="quotedblbase" width="500" llx="64" lly="-146" urx="436" ury="127"/>
+ <char name="quotedblleft" width="500" llx="64" lly="454" urx="436" ury="727"/>
+ <char name="quotedblright" width="500" llx="64" lly="445" urx="436" ury="718"/>
+ <char name="quoteleft" width="278" llx="69" lly="454" urx="209" ury="727"/>
+ <char name="quoteright" width="278" llx="69" lly="445" urx="209" ury="718"/>
+ <char name="quotesinglbase" width="278" llx="69" lly="-146" urx="209" ury="127"/>
+ <char name="quotesingle" width="238" llx="70" lly="447" urx="168" ury="718"/>
+ <char name="r" width="389" llx="64" lly="0" urx="373" ury="546"/>
+ <char name="registered" width="737" llx="-11" lly="-19" urx="748" ury="737"/>
+ <char name="ring" width="333" llx="59" lly="568" urx="275" ury="776"/>
+ <char name="s" width="556" llx="30" lly="-14" urx="519" ury="546"/>
+ <char name="scaron" width="556" llx="30" lly="-14" urx="519" ury="750"/>
+ <char name="section" width="556" llx="34" lly="-184" urx="522" ury="727"/>
+ <char name="semicolon" width="333" llx="92" lly="-168" urx="242" ury="512"/>
+ <char name="seven" width="556" llx="25" lly="0" urx="528" ury="698"/>
+ <char name="six" width="556" llx="31" lly="-19" urx="520" ury="710"/>
+ <char name="slash" width="278" llx="-33" lly="-19" urx="311" ury="737"/>
+ <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="278"/>
- <char name="sterling" width="556"/>
- <char name="t" width="333"/>
- <char name="thorn" width="611"/>
- <char name="three" width="556"/>
- <char name="threequarters" width="834"/>
- <char name="threesuperior" width="333"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="556"/>
- <char name="twosuperior" width="333"/>
- <char name="u" width="611"/>
- <char name="uacute" width="611"/>
- <char name="ucircumflex" width="611"/>
- <char name="udieresis" width="611"/>
- <char name="ugrave" width="611"/>
- <char name="underscore" width="556"/>
- <char name="v" width="556"/>
- <char name="w" width="778"/>
- <char name="x" width="556"/>
- <char name="y" width="556"/>
- <char name="yacute" width="556"/>
- <char name="ydieresis" width="556"/>
- <char name="yen" width="556"/>
- <char name="z" width="500"/>
- <char name="zcaron" width="500"/>
- <char name="zero" width="556"/>
- </widths>
+ <char name="sterling" width="556" llx="28" lly="-16" urx="541" ury="718"/>
+ <char name="t" width="333" llx="10" lly="-6" urx="309" ury="676"/>
+ <char name="thorn" width="611" llx="62" lly="-208" urx="578" ury="718"/>
+ <char name="three" width="556" llx="27" lly="-19" urx="516" ury="710"/>
+ <char name="threequarters" width="834" llx="16" lly="-19" urx="799" ury="710"/>
+ <char name="threesuperior" width="333" llx="8" lly="271" urx="326" ury="710"/>
+ <char name="tilde" width="333" llx="-17" lly="610" urx="350" ury="737"/>
+ <char name="trademark" width="1000" llx="44" lly="306" urx="956" ury="718"/>
+ <char name="two" width="556" llx="26" lly="0" urx="511" ury="710"/>
+ <char name="twosuperior" width="333" llx="9" lly="283" urx="324" ury="710"/>
+ <char name="u" width="611" llx="66" lly="-14" urx="545" ury="532"/>
+ <char name="uacute" width="611" llx="66" lly="-14" urx="545" ury="750"/>
+ <char name="ucircumflex" width="611" llx="66" lly="-14" urx="545" ury="750"/>
+ <char name="udieresis" width="611" llx="66" lly="-14" urx="545" ury="729"/>
+ <char name="ugrave" width="611" llx="66" lly="-14" urx="545" ury="750"/>
+ <char name="underscore" width="556" llx="0" lly="-125" urx="556" ury="-75"/>
+ <char name="v" width="556" llx="13" lly="0" urx="543" ury="532"/>
+ <char name="w" width="778" llx="10" lly="0" urx="769" ury="532"/>
+ <char name="x" width="556" llx="15" lly="0" urx="541" ury="532"/>
+ <char name="y" width="556" llx="10" lly="-214" urx="539" ury="532"/>
+ <char name="yacute" width="556" llx="10" lly="-214" urx="539" ury="750"/>
+ <char name="ydieresis" width="556" llx="10" lly="-214" urx="539" ury="729"/>
+ <char name="yen" width="556" llx="-9" lly="0" urx="565" ury="698"/>
+ <char name="z" width="500" llx="20" lly="0" urx="480" ury="532"/>
+ <char name="zcaron" width="500" llx="20" lly="0" urx="480" ury="750"/>
+ <char name="zero" width="556" llx="32" lly="-19" urx="524" ury="710"/>
+ </char-metrics>
<kerning kpx1="107">
<pair kern="-15" kpx2="111"/>
</kerning>
diff --git a/src/codegen/fonts/HelveticaBoldOblique.xml b/src/codegen/fonts/HelveticaBoldOblique.xml
index c11e0ba18..e1d0fd294 100644
--- a/src/codegen/fonts/HelveticaBoldOblique.xml
+++ b/src/codegen/fonts/HelveticaBoldOblique.xml
@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaBoldOblique</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>532</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="722"/>
- <char name="AE" width="1000"/>
- <char name="Aacute" width="722"/>
- <char name="Acircumflex" width="722"/>
- <char name="Adieresis" width="722"/>
- <char name="Agrave" width="722"/>
- <char name="Aring" width="722"/>
- <char name="Atilde" width="722"/>
- <char name="B" width="722"/>
- <char name="C" width="722"/>
- <char name="Ccedilla" width="722"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="556"/>
- <char name="F" width="611"/>
- <char name="G" width="778"/>
- <char name="H" width="722"/>
- <char name="I" width="278"/>
- <char name="Iacute" width="278"/>
- <char name="Icircumflex" width="278"/>
- <char name="Idieresis" width="278"/>
- <char name="Igrave" width="278"/>
- <char name="J" width="556"/>
- <char name="K" width="722"/>
- <char name="L" width="611"/>
- <char name="Lslash" width="611"/>
- <char name="M" width="833"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="778"/>
- <char name="OE" width="1000"/>
- <char name="Oacute" width="778"/>
- <char name="Ocircumflex" width="778"/>
- <char name="Odieresis" width="778"/>
- <char name="Ograve" width="778"/>
- <char name="Oslash" width="778"/>
- <char name="Otilde" width="778"/>
- <char name="P" width="667"/>
- <char name="Q" width="778"/>
- <char name="R" width="722"/>
- <char name="S" width="667"/>
- <char name="Scaron" width="667"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="667"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="667"/>
- <char name="W" width="944"/>
- <char name="X" width="667"/>
- <char name="Y" width="667"/>
- <char name="Yacute" width="667"/>
- <char name="Ydieresis" width="667"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="556"/>
- <char name="aacute" width="556"/>
- <char name="acircumflex" width="556"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="556"/>
- <char name="ae" width="889"/>
- <char name="agrave" width="556"/>
- <char name="ampersand" width="722"/>
- <char name="aring" width="556"/>
- <char name="asciicircum" width="584"/>
- <char name="asciitilde" width="584"/>
- <char name="asterisk" width="389"/>
- <char name="at" width="975"/>
- <char name="atilde" width="556"/>
- <char name="b" width="611"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="280"/>
- <char name="braceleft" width="389"/>
- <char name="braceright" width="389"/>
- <char name="bracketleft" width="333"/>
- <char name="bracketright" width="333"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="280"/>
- <char name="bullet" width="350"/>
- <char name="c" width="556"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="556"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="556"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="333"/>
- <char name="comma" width="278"/>
- <char name="copyright" width="737"/>
- <char name="currency" width="556"/>
- <char name="d" width="611"/>
- <char name="dagger" width="556"/>
- <char name="daggerdbl" width="556"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="584"/>
- <char name="dollar" width="556"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="556"/>
- <char name="eacute" width="556"/>
- <char name="ecircumflex" width="556"/>
- <char name="edieresis" width="556"/>
- <char name="egrave" width="556"/>
- <char name="eight" width="556"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="556"/>
- <char name="equal" width="584"/>
- <char name="eth" width="611"/>
- <char name="exclam" width="333"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="333"/>
- <char name="fi" width="611"/>
- <char name="five" width="556"/>
- <char name="fl" width="611"/>
- <char name="florin" width="556"/>
- <char name="four" width="556"/>
- <char name="fraction" width="167"/>
- <char name="g" width="611"/>
- <char name="germandbls" width="611"/>
- <char name="grave" width="333"/>
- <char name="greater" width="584"/>
- <char name="guillemotleft" width="556"/>
- <char name="guillemotright" width="556"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="611"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="278"/>
- <char name="k" width="556"/>
- <char name="l" width="278"/>
- <char name="less" width="584"/>
- <char name="logicalnot" width="584"/>
- <char name="lslash" width="278"/>
- <char name="m" width="889"/>
- <char name="macron" width="333"/>
- <char name="minus" width="324"/>
- <char name="mu" width="611"/>
- <char name="multiply" width="584"/>
- <char name="n" width="611"/>
- <char name="nine" width="556"/>
- <char name="ntilde" width="611"/>
- <char name="numbersign" width="556"/>
- <char name="o" width="611"/>
- <char name="oacute" width="611"/>
- <char name="ocircumflex" width="611"/>
- <char name="odieresis" width="611"/>
- <char name="oe" width="944"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="611"/>
- <char name="one" width="556"/>
- <char name="onehalf" width="834"/>
- <char name="onequarter" width="834"/>
- <char name="onesuperior" width="333"/>
- <char name="ordfeminine" width="370"/>
- <char name="ordmasculine" width="365"/>
- <char name="oslash" width="611"/>
- <char name="otilde" width="611"/>
- <char name="p" width="611"/>
- <char name="paragraph" width="556"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="889"/>
- <char name="period" width="278"/>
- <char name="periodcentered" width="278"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="584"/>
- <char name="plusminus" width="584"/>
- <char name="q" width="611"/>
- <char name="question" width="611"/>
- <char name="questiondown" width="611"/>
- <char name="quotedbl" width="474"/>
- <char name="quotedblbase" width="500"/>
- <char name="quotedblleft" width="500"/>
- <char name="quotedblright" width="500"/>
- <char name="quoteleft" width="278"/>
- <char name="quoteright" width="278"/>
- <char name="quotesinglbase" width="278"/>
- <char name="quotesingle" width="238"/>
- <char name="r" width="389"/>
- <char name="registered" width="737"/>
- <char name="ring" width="333"/>
- <char name="s" width="556"/>
- <char name="scaron" width="556"/>
- <char name="section" width="556"/>
- <char name="semicolon" width="333"/>
- <char name="seven" width="556"/>
- <char name="six" width="556"/>
- <char name="slash" width="278"/>
- <char name="space" width="278"/>
+ <char-metrics>
+ <char name="A" width="722" llx="20" lly="0" urx="702" ury="718"/>
+ <char name="AE" width="1000" llx="5" lly="0" urx="1100" ury="718"/>
+ <char name="Aacute" width="722" llx="20" lly="0" urx="750" ury="936"/>
+ <char name="Acircumflex" width="722" llx="20" lly="0" urx="706" ury="936"/>
+ <char name="Adieresis" width="722" llx="20" lly="0" urx="716" ury="915"/>
+ <char name="Agrave" width="722" llx="20" lly="0" urx="702" ury="936"/>
+ <char name="Aring" width="722" llx="20" lly="0" urx="702" ury="962"/>
+ <char name="Atilde" width="722" llx="20" lly="0" urx="741" ury="923"/>
+ <char name="B" width="722" llx="76" lly="0" urx="764" ury="718"/>
+ <char name="C" width="722" llx="107" lly="-19" urx="789" ury="737"/>
+ <char name="Ccedilla" width="722" llx="107" lly="-228" urx="789" ury="737"/>
+ <char name="D" width="722" llx="76" lly="0" urx="777" ury="718"/>
+ <char name="E" width="667" llx="76" lly="0" urx="757" ury="718"/>
+ <char name="Eacute" width="667" llx="76" lly="0" urx="757" ury="936"/>
+ <char name="Ecircumflex" width="667" llx="76" lly="0" urx="757" ury="936"/>
+ <char name="Edieresis" width="667" llx="76" lly="0" urx="757" ury="915"/>
+ <char name="Egrave" width="667" llx="76" lly="0" urx="757" ury="936"/>
+ <char name="Eth" width="722" llx="62" lly="0" urx="777" ury="718"/>
+ <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="76" lly="0" urx="740" ury="718"/>
+ <char name="G" width="778" llx="108" lly="-19" urx="817" ury="737"/>
+ <char name="H" width="722" llx="71" lly="0" urx="804" ury="718"/>
+ <char name="I" width="278" llx="64" lly="0" urx="367" ury="718"/>
+ <char name="Iacute" width="278" llx="64" lly="0" urx="528" ury="936"/>
+ <char name="Icircumflex" width="278" llx="64" lly="0" urx="484" ury="936"/>
+ <char name="Idieresis" width="278" llx="64" lly="0" urx="494" ury="915"/>
+ <char name="Igrave" width="278" llx="64" lly="0" urx="367" ury="936"/>
+ <char name="J" width="556" llx="60" lly="-18" urx="637" ury="718"/>
+ <char name="K" width="722" llx="87" lly="0" urx="858" ury="718"/>
+ <char name="L" width="611" llx="76" lly="0" urx="611" ury="718"/>
+ <char name="Lslash" width="611" llx="34" lly="0" urx="611" ury="718"/>
+ <char name="M" width="833" llx="69" lly="0" urx="918" ury="718"/>
+ <char name="N" width="722" llx="69" lly="0" urx="807" ury="718"/>
+ <char name="Ntilde" width="722" llx="69" lly="0" urx="807" ury="923"/>
+ <char name="O" width="778" llx="107" lly="-19" urx="823" ury="737"/>
+ <char name="OE" width="1000" llx="99" lly="-19" urx="1114" ury="737"/>
+ <char name="Oacute" width="778" llx="107" lly="-19" urx="823" ury="936"/>
+ <char name="Ocircumflex" width="778" llx="107" lly="-19" urx="823" ury="936"/>
+ <char name="Odieresis" width="778" llx="107" lly="-19" urx="823" ury="915"/>
+ <char name="Ograve" width="778" llx="107" lly="-19" urx="823" ury="936"/>
+ <char name="Oslash" width="778" llx="35" lly="-27" urx="894" ury="745"/>
+ <char name="Otilde" width="778" llx="107" lly="-19" urx="823" ury="923"/>
+ <char name="P" width="667" llx="76" lly="0" urx="738" ury="718"/>
+ <char name="Q" width="778" llx="107" lly="-52" urx="823" ury="737"/>
+ <char name="R" width="722" llx="76" lly="0" urx="778" ury="718"/>
+ <char name="S" width="667" llx="81" lly="-19" urx="718" ury="737"/>
+ <char name="Scaron" width="667" llx="81" lly="-19" urx="718" ury="936"/>
+ <char name="T" width="611" llx="140" lly="0" urx="751" ury="718"/>
+ <char name="Thorn" width="667" llx="76" lly="0" urx="716" ury="718"/>
+ <char name="U" width="722" llx="116" lly="-19" urx="804" ury="718"/>
+ <char name="Uacute" width="722" llx="116" lly="-19" urx="804" ury="936"/>
+ <char name="Ucircumflex" width="722" llx="116" lly="-19" urx="804" ury="936"/>
+ <char name="Udieresis" width="722" llx="116" lly="-19" urx="804" ury="915"/>
+ <char name="Ugrave" width="722" llx="116" lly="-19" urx="804" ury="936"/>
+ <char name="V" width="667" llx="172" lly="0" urx="801" ury="718"/>
+ <char name="W" width="944" llx="169" lly="0" urx="1082" ury="718"/>
+ <char name="X" width="667" llx="14" lly="0" urx="791" ury="718"/>
+ <char name="Y" width="667" llx="168" lly="0" urx="806" ury="718"/>
+ <char name="Yacute" width="667" llx="168" lly="0" urx="806" ury="936"/>
+ <char name="Ydieresis" width="667" llx="168" lly="0" urx="806" ury="915"/>
+ <char name="Z" width="611" llx="25" lly="0" urx="737" ury="718"/>
+ <char name="Zcaron" width="611" llx="25" lly="0" urx="737" ury="936"/>
+ <char name="a" width="556" llx="55" lly="-14" urx="583" ury="546"/>
+ <char name="aacute" width="556" llx="55" lly="-14" urx="627" ury="750"/>
+ <char name="acircumflex" width="556" llx="55" lly="-14" urx="583" ury="750"/>
+ <char name="acute" width="333" llx="236" lly="604" urx="515" ury="750"/>
+ <char name="adieresis" width="556" llx="55" lly="-14" urx="594" ury="729"/>
+ <char name="ae" width="889" llx="56" lly="-14" urx="923" ury="546"/>
+ <char name="agrave" width="556" llx="55" lly="-14" urx="583" ury="750"/>
+ <char name="ampersand" width="722" llx="89" lly="-19" urx="732" ury="718"/>
+ <char name="aring" width="556" llx="55" lly="-14" urx="583" ury="776"/>
+ <char name="asciicircum" width="584" llx="131" lly="323" urx="591" ury="698"/>
+ <char name="asciitilde" width="584" llx="115" lly="163" urx="577" ury="343"/>
+ <char name="asterisk" width="389" llx="146" lly="387" urx="481" ury="718"/>
+ <char name="at" width="975" llx="186" lly="-19" urx="954" ury="737"/>
+ <char name="atilde" width="556" llx="55" lly="-14" urx="619" ury="737"/>
+ <char name="b" width="611" llx="61" lly="-14" urx="645" ury="718"/>
+ <char name="backslash" width="278" llx="124" lly="-19" urx="307" ury="737"/>
+ <char name="bar" width="280" llx="36" lly="-225" urx="361" ury="775"/>
+ <char name="braceleft" width="389" llx="94" lly="-196" urx="518" ury="722"/>
+ <char name="braceright" width="389" llx="-18" lly="-196" urx="407" ury="722"/>
+ <char name="bracketleft" width="333" llx="21" lly="-196" urx="462" ury="722"/>
+ <char name="bracketright" width="333" llx="-18" lly="-196" urx="423" ury="722"/>
+ <char name="breve" width="333" llx="156" lly="604" urx="494" ury="750"/>
+ <char name="brokenbar" width="280" llx="52" lly="-150" urx="345" ury="700"/>
+ <char name="bullet" width="350" llx="83" lly="194" urx="420" ury="524"/>
+ <char name="c" width="556" llx="79" lly="-14" urx="599" ury="546"/>
+ <char name="caron" width="333" llx="149" lly="604" urx="502" ury="750"/>
+ <char name="ccedilla" width="556" llx="79" lly="-228" urx="599" ury="546"/>
+ <char name="cedilla" width="333" llx="-37" lly="-228" urx="220" ury="0"/>
+ <char name="cent" width="556" llx="79" lly="-118" urx="599" ury="628"/>
+ <char name="circumflex" width="333" llx="118" lly="604" urx="471" ury="750"/>
+ <char name="colon" width="333" llx="92" lly="0" urx="351" ury="512"/>
+ <char name="comma" width="278" llx="28" lly="-168" urx="245" ury="146"/>
+ <char name="copyright" width="737" llx="56" lly="-19" urx="835" ury="737"/>
+ <char name="currency" width="556" llx="27" lly="76" urx="680" ury="636"/>
+ <char name="d" width="611" llx="82" lly="-14" urx="704" ury="718"/>
+ <char name="dagger" width="556" llx="118" lly="-171" urx="626" ury="718"/>
+ <char name="daggerdbl" width="556" llx="46" lly="-171" urx="628" ury="718"/>
+ <char name="degree" width="400" llx="175" lly="426" urx="467" ury="712"/>
+ <char name="dieresis" width="333" llx="137" lly="614" urx="482" ury="729"/>
+ <char name="divide" width="584" llx="82" lly="-42" urx="610" ury="548"/>
+ <char name="dollar" width="556" llx="67" lly="-115" urx="622" ury="775"/>
+ <char name="dotaccent" width="333" llx="235" lly="614" urx="385" ury="729"/>
+ <char name="dotlessi" width="278" llx="69" lly="0" urx="322" ury="532"/>
+ <char name="e" width="556" llx="70" lly="-14" urx="593" ury="546"/>
+ <char name="eacute" width="556" llx="70" lly="-14" urx="627" ury="750"/>
+ <char name="ecircumflex" width="556" llx="70" lly="-14" urx="593" ury="750"/>
+ <char name="edieresis" width="556" llx="70" lly="-14" urx="594" ury="729"/>
+ <char name="egrave" width="556" llx="70" lly="-14" urx="593" ury="750"/>
+ <char name="eight" width="556" llx="69" lly="-19" urx="616" ury="710"/>
+ <char name="ellipsis" width="1000" llx="92" lly="0" urx="939" ury="146"/>
+ <char name="emdash" width="1000" llx="48" lly="227" urx="1071" ury="333"/>
+ <char name="endash" width="556" llx="48" lly="227" urx="627" ury="333"/>
+ <char name="equal" width="584" llx="58" lly="87" urx="633" ury="419"/>
+ <char name="eth" width="611" llx="82" lly="-14" urx="670" ury="737"/>
+ <char name="exclam" width="333" llx="94" lly="0" urx="397" ury="718"/>
+ <char name="exclamdown" width="333" llx="50" lly="-186" urx="353" ury="532"/>
+ <char name="f" width="333" llx="87" lly="0" urx="469" ury="727"/>
+ <char name="fi" width="611" llx="87" lly="0" urx="696" ury="727"/>
+ <char name="five" width="556" llx="64" lly="-19" urx="636" ury="698"/>
+ <char name="fl" width="611" llx="87" lly="0" urx="695" ury="727"/>
+ <char name="florin" width="556" llx="-50" lly="-210" urx="669" ury="737"/>
+ <char name="four" width="556" llx="60" lly="0" urx="598" ury="710"/>
+ <char name="fraction" width="167" llx="-174" lly="-19" urx="487" ury="710"/>
+ <char name="g" width="611" llx="38" lly="-217" urx="666" ury="546"/>
+ <char name="germandbls" width="611" llx="69" lly="-14" urx="657" ury="731"/>
+ <char name="grave" width="333" llx="136" lly="604" urx="353" ury="750"/>
+ <char name="greater" width="584" llx="36" lly="-8" urx="609" ury="514"/>
+ <char name="guillemotleft" width="556" llx="135" lly="76" urx="571" ury="484"/>
+ <char name="guillemotright" width="556" llx="104" lly="76" urx="540" ury="484"/>
+ <char name="guilsinglleft" width="333" llx="130" lly="76" urx="353" ury="484"/>
+ <char name="guilsinglright" width="333" llx="99" lly="76" urx="322" ury="484"/>
+ <char name="h" width="611" llx="65" lly="0" urx="629" ury="718"/>
+ <char name="hungarumlaut" width="333" llx="137" lly="604" urx="645" ury="750"/>
+ <char name="hyphen" width="333" llx="73" lly="215" urx="379" ury="345"/>
+ <char name="i" width="278" llx="69" lly="0" urx="363" ury="725"/>
+ <char name="iacute" width="278" llx="69" lly="0" urx="488" ury="750"/>
+ <char name="icircumflex" width="278" llx="69" lly="0" urx="444" ury="750"/>
+ <char name="idieresis" width="278" llx="69" lly="0" urx="455" ury="729"/>
+ <char name="igrave" width="278" llx="69" lly="0" urx="326" ury="750"/>
+ <char name="j" width="278" llx="-42" lly="-214" urx="363" ury="725"/>
+ <char name="k" width="556" llx="69" lly="0" urx="670" ury="718"/>
+ <char name="l" width="278" llx="69" lly="0" urx="362" ury="718"/>
+ <char name="less" width="584" llx="82" lly="-8" urx="655" ury="514"/>
+ <char name="logicalnot" width="584" llx="105" lly="108" urx="633" ury="419"/>
+ <char name="lslash" width="278" llx="40" lly="0" urx="407" ury="718"/>
+ <char name="m" width="889" llx="64" lly="0" urx="909" ury="546"/>
+ <char name="macron" width="333" llx="122" lly="604" urx="483" ury="678"/>
+ <char name="minus" width="324" llx="82" lly="197" urx="610" ury="309"/>
+ <char name="mu" width="611" llx="22" lly="-207" urx="658" ury="532"/>
+ <char name="multiply" width="584" llx="57" lly="1" urx="635" ury="505"/>
+ <char name="n" width="611" llx="65" lly="0" urx="629" ury="546"/>
+ <char name="nine" width="556" llx="78" lly="-19" urx="615" ury="710"/>
+ <char name="ntilde" width="611" llx="65" lly="0" urx="646" ury="737"/>
+ <char name="numbersign" width="556" llx="60" lly="0" urx="644" ury="698"/>
+ <char name="o" width="611" llx="82" lly="-14" urx="643" ury="546"/>
+ <char name="oacute" width="611" llx="82" lly="-14" urx="654" ury="750"/>
+ <char name="ocircumflex" width="611" llx="82" lly="-14" urx="643" ury="750"/>
+ <char name="odieresis" width="611" llx="82" lly="-14" urx="643" ury="729"/>
+ <char name="oe" width="944" llx="82" lly="-14" urx="977" ury="546"/>
+ <char name="ogonek" width="333" llx="41" lly="-228" urx="264" ury="0"/>
+ <char name="ograve" width="611" llx="82" lly="-14" urx="643" ury="750"/>
+ <char name="one" width="556" llx="173" lly="0" urx="529" ury="710"/>
+ <char name="onehalf" width="834" llx="132" lly="-19" urx="858" ury="710"/>
+ <char name="onequarter" width="834" llx="132" lly="-19" urx="806" ury="710"/>
+ <char name="onesuperior" width="333" llx="148" lly="283" urx="388" ury="710"/>
+ <char name="ordfeminine" width="370" llx="125" lly="401" urx="465" ury="737"/>
+ <char name="ordmasculine" width="365" llx="123" lly="401" urx="485" ury="737"/>
+ <char name="oslash" width="611" llx="22" lly="-29" urx="701" ury="560"/>
+ <char name="otilde" width="611" llx="82" lly="-14" urx="646" ury="737"/>
+ <char name="p" width="611" llx="18" lly="-207" urx="645" ury="546"/>
+ <char name="paragraph" width="556" llx="98" lly="-191" urx="688" ury="700"/>
+ <char name="parenleft" width="333" llx="76" lly="-208" urx="470" ury="734"/>
+ <char name="parenright" width="333" llx="-25" lly="-208" urx="369" ury="734"/>
+ <char name="percent" width="889" llx="136" lly="-19" urx="901" ury="710"/>
+ <char name="period" width="278" llx="64" lly="0" urx="245" ury="146"/>
+ <char name="periodcentered" width="278" llx="110" lly="172" urx="276" ury="334"/>
+ <char name="perthousand" width="1000" llx="76" lly="-19" urx="1038" ury="710"/>
+ <char name="plus" width="584" llx="82" lly="0" urx="610" ury="506"/>
+ <char name="plusminus" width="584" llx="40" lly="0" urx="625" ury="506"/>
+ <char name="q" width="611" llx="80" lly="-207" urx="665" ury="546"/>
+ <char name="question" width="611" llx="165" lly="0" urx="671" ury="727"/>
+ <char name="questiondown" width="611" llx="53" lly="-195" urx="559" ury="532"/>
+ <char name="quotedbl" width="474" llx="193" lly="447" urx="529" ury="718"/>
+ <char name="quotedblbase" width="500" llx="36" lly="-146" urx="463" ury="127"/>
+ <char name="quotedblleft" width="500" llx="160" lly="454" urx="588" ury="727"/>
+ <char name="quotedblright" width="500" llx="162" lly="445" urx="589" ury="718"/>
+ <char name="quoteleft" width="278" llx="165" lly="454" urx="361" ury="727"/>
+ <char name="quoteright" width="278" llx="167" lly="445" urx="362" ury="718"/>
+ <char name="quotesinglbase" width="278" llx="41" lly="-146" urx="236" ury="127"/>
+ <char name="quotesingle" width="238" llx="165" lly="447" urx="321" ury="718"/>
+ <char name="r" width="389" llx="64" lly="0" urx="489" ury="546"/>
+ <char name="registered" width="737" llx="55" lly="-19" urx="834" ury="737"/>
+ <char name="ring" width="333" llx="200" lly="568" urx="420" ury="776"/>
+ <char name="s" width="556" llx="63" lly="-14" urx="584" ury="546"/>
+ <char name="scaron" width="556" llx="63" lly="-14" urx="614" ury="750"/>
+ <char name="section" width="556" llx="61" lly="-184" urx="598" ury="727"/>
+ <char name="semicolon" width="333" llx="56" lly="-168" urx="351" ury="512"/>
+ <char name="seven" width="556" llx="125" lly="0" urx="676" ury="698"/>
+ <char name="six" width="556" llx="85" lly="-19" urx="619" ury="710"/>
+ <char name="slash" width="278" llx="-37" lly="-19" urx="468" ury="737"/>
+ <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="278"/>
- <char name="sterling" width="556"/>
- <char name="t" width="333"/>
- <char name="thorn" width="611"/>
- <char name="three" width="556"/>
- <char name="threequarters" width="834"/>
- <char name="threesuperior" width="333"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="556"/>
- <char name="twosuperior" width="333"/>
- <char name="u" width="611"/>
- <char name="uacute" width="611"/>
- <char name="ucircumflex" width="611"/>
- <char name="udieresis" width="611"/>
- <char name="ugrave" width="611"/>
- <char name="underscore" width="556"/>
- <char name="v" width="556"/>
- <char name="w" width="778"/>
- <char name="x" width="556"/>
- <char name="y" width="556"/>
- <char name="yacute" width="556"/>
- <char name="ydieresis" width="556"/>
- <char name="yen" width="556"/>
- <char name="z" width="500"/>
- <char name="zcaron" width="500"/>
- <char name="zero" width="556"/>
- </widths>
+ <char name="sterling" width="556" llx="50" lly="-16" urx="635" ury="718"/>
+ <char name="t" width="333" llx="100" lly="-6" urx="422" ury="676"/>
+ <char name="thorn" width="611" llx="18" lly="-208" urx="645" ury="718"/>
+ <char name="three" width="556" llx="65" lly="-19" urx="608" ury="710"/>
+ <char name="threequarters" width="834" llx="99" lly="-19" urx="839" ury="710"/>
+ <char name="threesuperior" width="333" llx="91" lly="271" urx="441" ury="710"/>
+ <char name="tilde" width="333" llx="113" lly="610" urx="507" ury="737"/>
+ <char name="trademark" width="1000" llx="179" lly="306" urx="1109" ury="718"/>
+ <char name="two" width="556" llx="26" lly="0" urx="619" ury="710"/>
+ <char name="twosuperior" width="333" llx="69" lly="283" urx="449" ury="710"/>
+ <char name="u" width="611" llx="98" lly="-14" urx="658" ury="532"/>
+ <char name="uacute" width="611" llx="98" lly="-14" urx="658" ury="750"/>
+ <char name="ucircumflex" width="611" llx="98" lly="-14" urx="658" ury="750"/>
+ <char name="udieresis" width="611" llx="98" lly="-14" urx="658" ury="729"/>
+ <char name="ugrave" width="611" llx="98" lly="-14" urx="658" ury="750"/>
+ <char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/>
+ <char name="v" width="556" llx="126" lly="0" urx="656" ury="532"/>
+ <char name="w" width="778" llx="123" lly="0" urx="882" ury="532"/>
+ <char name="x" width="556" llx="15" lly="0" urx="648" ury="532"/>
+ <char name="y" width="556" llx="42" lly="-214" urx="652" ury="532"/>
+ <char name="yacute" width="556" llx="42" lly="-214" urx="652" ury="750"/>
+ <char name="ydieresis" width="556" llx="42" lly="-214" urx="652" ury="729"/>
+ <char name="yen" width="556" llx="60" lly="0" urx="713" ury="698"/>
+ <char name="z" width="500" llx="20" lly="0" urx="583" ury="532"/>
+ <char name="zcaron" width="500" llx="20" lly="0" urx="586" ury="750"/>
+ <char name="zero" width="556" llx="86" lly="-19" urx="617" ury="710"/>
+ </char-metrics>
<kerning kpx1="107">
<pair kern="-15" kpx2="111"/>
</kerning>
diff --git a/src/codegen/fonts/HelveticaOblique.xml b/src/codegen/fonts/HelveticaOblique.xml
index 7f651a5d9..efa1165f2 100644
--- a/src/codegen/fonts/HelveticaOblique.xml
+++ b/src/codegen/fonts/HelveticaOblique.xml
@@ -22,245 +22,246 @@
<family-name>Helvetica</family-name>
<class-name>HelveticaOblique</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>718</cap-height>
<x-height>523</x-height>
<ascender>718</ascender>
<descender>-207</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="667"/>
- <char name="AE" width="1000"/>
- <char name="Aacute" width="667"/>
- <char name="Acircumflex" width="667"/>
- <char name="Adieresis" width="667"/>
- <char name="Agrave" width="667"/>
- <char name="Aring" width="667"/>
- <char name="Atilde" width="667"/>
- <char name="B" width="667"/>
- <char name="C" width="722"/>
- <char name="Ccedilla" width="722"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="556"/>
- <char name="F" width="611"/>
- <char name="G" width="778"/>
- <char name="H" width="722"/>
- <char name="I" width="278"/>
- <char name="Iacute" width="278"/>
- <char name="Icircumflex" width="278"/>
- <char name="Idieresis" width="278"/>
- <char name="Igrave" width="278"/>
- <char name="J" width="500"/>
- <char name="K" width="667"/>
- <char name="L" width="556"/>
- <char name="Lslash" width="556"/>
- <char name="M" width="833"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="778"/>
- <char name="OE" width="1000"/>
- <char name="Oacute" width="778"/>
- <char name="Ocircumflex" width="778"/>
- <char name="Odieresis" width="778"/>
- <char name="Ograve" width="778"/>
- <char name="Oslash" width="778"/>
- <char name="Otilde" width="778"/>
- <char name="P" width="667"/>
- <char name="Q" width="778"/>
- <char name="R" width="722"/>
- <char name="S" width="667"/>
- <char name="Scaron" width="667"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="667"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="667"/>
- <char name="W" width="944"/>
- <char name="X" width="667"/>
- <char name="Y" width="667"/>
- <char name="Yacute" width="667"/>
- <char name="Ydieresis" width="667"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="556"/>
- <char name="aacute" width="556"/>
- <char name="acircumflex" width="556"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="556"/>
- <char name="ae" width="889"/>
- <char name="agrave" width="556"/>
- <char name="ampersand" width="667"/>
- <char name="aring" width="556"/>
- <char name="asciicircum" width="469"/>
- <char name="asciitilde" width="584"/>
- <char name="asterisk" width="389"/>
- <char name="at" width="1015"/>
- <char name="atilde" width="556"/>
- <char name="b" width="556"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="260"/>
- <char name="braceleft" width="334"/>
- <char name="braceright" width="334"/>
- <char name="bracketleft" width="278"/>
- <char name="bracketright" width="278"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="260"/>
- <char name="bullet" width="350"/>
- <char name="c" width="500"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="500"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="556"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="278"/>
- <char name="comma" width="278"/>
- <char name="copyright" width="737"/>
- <char name="currency" width="556"/>
- <char name="d" width="556"/>
- <char name="dagger" width="556"/>
- <char name="daggerdbl" width="556"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="584"/>
- <char name="dollar" width="556"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="556"/>
- <char name="eacute" width="556"/>
- <char name="ecircumflex" width="556"/>
- <char name="edieresis" width="556"/>
- <char name="egrave" width="556"/>
- <char name="eight" width="556"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="556"/>
- <char name="equal" width="584"/>
- <char name="eth" width="556"/>
- <char name="exclam" width="278"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="278"/>
- <char name="fi" width="500"/>
- <char name="five" width="556"/>
- <char name="fl" width="500"/>
- <char name="florin" width="556"/>
- <char name="four" width="556"/>
- <char name="fraction" width="167"/>
- <char name="g" width="556"/>
- <char name="germandbls" width="611"/>
- <char name="grave" width="333"/>
- <char name="greater" width="584"/>
- <char name="guillemotleft" width="556"/>
- <char name="guillemotright" width="556"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="556"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="222"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="222"/>
- <char name="k" width="500"/>
- <char name="l" width="222"/>
- <char name="less" width="584"/>
- <char name="logicalnot" width="584"/>
- <char name="lslash" width="222"/>
- <char name="m" width="833"/>
- <char name="macron" width="333"/>
- <char name="minus" width="584"/>
- <char name="mu" width="556"/>
- <char name="multiply" width="584"/>
- <char name="n" width="556"/>
- <char name="nine" width="556"/>
- <char name="ntilde" width="556"/>
- <char name="numbersign" width="556"/>
- <char name="o" width="556"/>
- <char name="oacute" width="556"/>
- <char name="ocircumflex" width="556"/>
- <char name="odieresis" width="556"/>
- <char name="oe" width="944"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="556"/>
- <char name="one" width="556"/>
- <char name="onehalf" width="834"/>
- <char name="onequarter" width="834"/>
- <char name="onesuperior" width="333"/>
- <char name="ordfeminine" width="370"/>
- <char name="ordmasculine" width="365"/>
- <char name="oslash" width="611"/>
- <char name="otilde" width="556"/>
- <char name="p" width="556"/>
- <char name="paragraph" width="537"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="889"/>
- <char name="period" width="278"/>
- <char name="periodcentered" width="278"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="584"/>
- <char name="plusminus" width="584"/>
- <char name="q" width="556"/>
- <char name="question" width="556"/>
- <char name="questiondown" width="611"/>
- <char name="quotedbl" width="355"/>
- <char name="quotedblbase" width="333"/>
- <char name="quotedblleft" width="333"/>
- <char name="quotedblright" width="333"/>
- <char name="quoteleft" width="222"/>
- <char name="quoteright" width="222"/>
- <char name="quotesinglbase" width="222"/>
- <char name="quotesingle" width="191"/>
- <char name="r" width="333"/>
- <char name="registered" width="737"/>
- <char name="ring" width="333"/>
- <char name="s" width="500"/>
- <char name="scaron" width="500"/>
- <char name="section" width="556"/>
- <char name="semicolon" width="278"/>
- <char name="seven" width="556"/>
- <char name="six" width="556"/>
- <char name="slash" width="278"/>
- <char name="space" width="278"/>
+ <char-metrics>
+ <char name="A" width="667" llx="14" lly="0" urx="654" ury="718"/>
+ <char name="AE" width="1000" llx="8" lly="0" urx="1097" ury="718"/>
+ <char name="Aacute" width="667" llx="14" lly="0" urx="683" ury="929"/>
+ <char name="Acircumflex" width="667" llx="14" lly="0" urx="654" ury="929"/>
+ <char name="Adieresis" width="667" llx="14" lly="0" urx="654" ury="901"/>
+ <char name="Agrave" width="667" llx="14" lly="0" urx="654" ury="929"/>
+ <char name="Aring" width="667" llx="14" lly="0" urx="654" ury="931"/>
+ <char name="Atilde" width="667" llx="14" lly="0" urx="699" ury="917"/>
+ <char name="B" width="667" llx="74" lly="0" urx="712" ury="718"/>
+ <char name="C" width="722" llx="108" lly="-19" urx="782" ury="737"/>
+ <char name="Ccedilla" width="722" llx="108" lly="-225" urx="782" ury="737"/>
+ <char name="D" width="722" llx="81" lly="0" urx="764" ury="718"/>
+ <char name="E" width="667" llx="86" lly="0" urx="762" ury="718"/>
+ <char name="Eacute" width="667" llx="86" lly="0" urx="762" ury="929"/>
+ <char name="Ecircumflex" width="667" llx="86" lly="0" urx="762" ury="929"/>
+ <char name="Edieresis" width="667" llx="86" lly="0" urx="762" ury="901"/>
+ <char name="Egrave" width="667" llx="86" lly="0" urx="762" ury="929"/>
+ <char name="Eth" width="722" llx="69" lly="0" urx="764" ury="718"/>
+ <char name="Euro" width="556" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="86" lly="0" urx="736" ury="718"/>
+ <char name="G" width="778" llx="111" lly="-19" urx="799" ury="737"/>
+ <char name="H" width="722" llx="77" lly="0" urx="799" ury="718"/>
+ <char name="I" width="278" llx="91" lly="0" urx="341" ury="718"/>
+ <char name="Iacute" width="278" llx="91" lly="0" urx="489" ury="929"/>
+ <char name="Icircumflex" width="278" llx="91" lly="0" urx="452" ury="929"/>
+ <char name="Idieresis" width="278" llx="91" lly="0" urx="458" ury="901"/>
+ <char name="Igrave" width="278" llx="91" lly="0" urx="351" ury="929"/>
+ <char name="J" width="500" llx="47" lly="-19" urx="581" ury="718"/>
+ <char name="K" width="667" llx="76" lly="0" urx="808" ury="718"/>
+ <char name="L" width="556" llx="76" lly="0" urx="555" ury="718"/>
+ <char name="Lslash" width="556" llx="41" lly="0" urx="555" ury="718"/>
+ <char name="M" width="833" llx="73" lly="0" urx="914" ury="718"/>
+ <char name="N" width="722" llx="76" lly="0" urx="799" ury="718"/>
+ <char name="Ntilde" width="722" llx="76" lly="0" urx="799" ury="917"/>
+ <char name="O" width="778" llx="105" lly="-19" urx="826" ury="737"/>
+ <char name="OE" width="1000" llx="98" lly="-19" urx="1116" ury="737"/>
+ <char name="Oacute" width="778" llx="105" lly="-19" urx="826" ury="929"/>
+ <char name="Ocircumflex" width="778" llx="105" lly="-19" urx="826" ury="929"/>
+ <char name="Odieresis" width="778" llx="105" lly="-19" urx="826" ury="901"/>
+ <char name="Ograve" width="778" llx="105" lly="-19" urx="826" ury="929"/>
+ <char name="Oslash" width="778" llx="43" lly="-19" urx="890" ury="737"/>
+ <char name="Otilde" width="778" llx="105" lly="-19" urx="826" ury="917"/>
+ <char name="P" width="667" llx="86" lly="0" urx="737" ury="718"/>
+ <char name="Q" width="778" llx="105" lly="-56" urx="826" ury="737"/>
+ <char name="R" width="722" llx="88" lly="0" urx="773" ury="718"/>
+ <char name="S" width="667" llx="90" lly="-19" urx="713" ury="737"/>
+ <char name="Scaron" width="667" llx="90" lly="-19" urx="713" ury="929"/>
+ <char name="T" width="611" llx="148" lly="0" urx="750" ury="718"/>
+ <char name="Thorn" width="667" llx="86" lly="0" urx="712" ury="718"/>
+ <char name="U" width="722" llx="123" lly="-19" urx="797" ury="718"/>
+ <char name="Uacute" width="722" llx="123" lly="-19" urx="797" ury="929"/>
+ <char name="Ucircumflex" width="722" llx="123" lly="-19" urx="797" ury="929"/>
+ <char name="Udieresis" width="722" llx="123" lly="-19" urx="797" ury="901"/>
+ <char name="Ugrave" width="722" llx="123" lly="-19" urx="797" ury="929"/>
+ <char name="V" width="667" llx="173" lly="0" urx="800" ury="718"/>
+ <char name="W" width="944" llx="169" lly="0" urx="1081" ury="718"/>
+ <char name="X" width="667" llx="19" lly="0" urx="790" ury="718"/>
+ <char name="Y" width="667" llx="167" lly="0" urx="806" ury="718"/>
+ <char name="Yacute" width="667" llx="167" lly="0" urx="806" ury="929"/>
+ <char name="Ydieresis" width="667" llx="167" lly="0" urx="806" ury="901"/>
+ <char name="Z" width="611" llx="23" lly="0" urx="741" ury="718"/>
+ <char name="Zcaron" width="611" llx="23" lly="0" urx="741" ury="929"/>
+ <char name="a" width="556" llx="61" lly="-15" urx="559" ury="538"/>
+ <char name="aacute" width="556" llx="61" lly="-15" urx="587" ury="734"/>
+ <char name="acircumflex" width="556" llx="61" lly="-15" urx="559" ury="734"/>
+ <char name="acute" width="333" llx="248" lly="593" urx="475" ury="734"/>
+ <char name="adieresis" width="556" llx="61" lly="-15" urx="559" ury="706"/>
+ <char name="ae" width="889" llx="61" lly="-15" urx="909" ury="538"/>
+ <char name="agrave" width="556" llx="61" lly="-15" urx="559" ury="734"/>
+ <char name="ampersand" width="667" llx="77" lly="-15" urx="647" ury="718"/>
+ <char name="aring" width="556" llx="61" lly="-15" urx="559" ury="756"/>
+ <char name="asciicircum" width="469" llx="42" lly="264" urx="539" ury="688"/>
+ <char name="asciitilde" width="584" llx="111" lly="180" urx="580" ury="326"/>
+ <char name="asterisk" width="389" llx="165" lly="431" urx="475" ury="718"/>
+ <char name="at" width="1015" llx="215" lly="-19" urx="965" ury="737"/>
+ <char name="atilde" width="556" llx="61" lly="-15" urx="592" ury="722"/>
+ <char name="b" width="556" llx="58" lly="-15" urx="584" ury="718"/>
+ <char name="backslash" width="278" llx="140" lly="-19" urx="291" ury="737"/>
+ <char name="bar" width="260" llx="46" lly="-225" urx="332" ury="775"/>
+ <char name="braceleft" width="334" llx="92" lly="-196" urx="445" ury="722"/>
+ <char name="braceright" width="334" llx="0" lly="-196" urx="354" ury="722"/>
+ <char name="bracketleft" width="278" llx="21" lly="-196" urx="403" ury="722"/>
+ <char name="bracketright" width="278" llx="-14" lly="-196" urx="368" ury="722"/>
+ <char name="breve" width="333" llx="167" lly="595" urx="476" ury="731"/>
+ <char name="brokenbar" width="260" llx="62" lly="-150" urx="316" ury="700"/>
+ <char name="bullet" width="350" llx="91" lly="202" urx="413" ury="517"/>
+ <char name="c" width="500" llx="74" lly="-15" urx="553" ury="538"/>
+ <char name="caron" width="333" llx="177" lly="593" urx="468" ury="734"/>
+ <char name="ccedilla" width="500" llx="74" lly="-225" urx="553" ury="538"/>
+ <char name="cedilla" width="333" llx="2" lly="-225" urx="232" ury="0"/>
+ <char name="cent" width="556" llx="95" lly="-115" urx="584" ury="623"/>
+ <char name="circumflex" width="333" llx="147" lly="593" urx="438" ury="734"/>
+ <char name="colon" width="278" llx="87" lly="0" urx="301" ury="516"/>
+ <char name="comma" width="278" llx="56" lly="-147" urx="214" ury="106"/>
+ <char name="copyright" width="737" llx="54" lly="-19" urx="837" ury="737"/>
+ <char name="currency" width="556" llx="60" lly="99" urx="646" ury="603"/>
+ <char name="d" width="556" llx="84" lly="-15" urx="652" ury="718"/>
+ <char name="dagger" width="556" llx="135" lly="-159" urx="622" ury="718"/>
+ <char name="daggerdbl" width="556" llx="52" lly="-159" urx="623" ury="718"/>
+ <char name="degree" width="400" llx="169" lly="411" urx="468" ury="703"/>
+ <char name="dieresis" width="333" llx="168" lly="604" urx="443" ury="706"/>
+ <char name="divide" width="584" llx="85" lly="-19" urx="606" ury="524"/>
+ <char name="dollar" width="556" llx="69" lly="-115" urx="617" ury="775"/>
+ <char name="dotaccent" width="333" llx="249" lly="604" urx="362" ury="706"/>
+ <char name="dotlessi" width="278" llx="95" lly="0" urx="294" ury="523"/>
+ <char name="e" width="556" llx="84" lly="-15" urx="578" ury="538"/>
+ <char name="eacute" width="556" llx="84" lly="-15" urx="587" ury="734"/>
+ <char name="ecircumflex" width="556" llx="84" lly="-15" urx="578" ury="734"/>
+ <char name="edieresis" width="556" llx="84" lly="-15" urx="578" ury="706"/>
+ <char name="egrave" width="556" llx="84" lly="-15" urx="578" ury="734"/>
+ <char name="eight" width="556" llx="74" lly="-19" urx="607" ury="703"/>
+ <char name="ellipsis" width="1000" llx="115" lly="0" urx="908" ury="106"/>
+ <char name="emdash" width="1000" llx="51" lly="240" urx="1067" ury="313"/>
+ <char name="endash" width="556" llx="51" lly="240" urx="623" ury="313"/>
+ <char name="equal" width="584" llx="63" lly="115" urx="628" ury="390"/>
+ <char name="eth" width="556" llx="81" lly="-15" urx="617" ury="737"/>
+ <char name="exclam" width="278" llx="90" lly="0" urx="340" ury="718"/>
+ <char name="exclamdown" width="333" llx="77" lly="-195" urx="326" ury="523"/>
+ <char name="f" width="278" llx="86" lly="0" urx="416" ury="728"/>
+ <char name="fi" width="500" llx="86" lly="0" urx="587" ury="728"/>
+ <char name="five" width="556" llx="68" lly="-19" urx="621" ury="688"/>
+ <char name="fl" width="500" llx="86" lly="0" urx="585" ury="728"/>
+ <char name="florin" width="556" llx="-52" lly="-207" urx="654" ury="737"/>
+ <char name="four" width="556" llx="61" lly="0" urx="576" ury="703"/>
+ <char name="fraction" width="167" llx="-170" lly="-19" urx="482" ury="703"/>
+ <char name="g" width="556" llx="42" lly="-220" urx="610" ury="538"/>
+ <char name="germandbls" width="611" llx="67" lly="-15" urx="658" ury="728"/>
+ <char name="grave" width="333" llx="170" lly="593" urx="337" ury="734"/>
+ <char name="greater" width="584" llx="50" lly="11" urx="597" ury="495"/>
+ <char name="guillemotleft" width="556" llx="146" lly="108" urx="554" ury="446"/>
+ <char name="guillemotright" width="556" llx="120" lly="108" urx="528" ury="446"/>
+ <char name="guilsinglleft" width="333" llx="137" lly="108" urx="340" ury="446"/>
+ <char name="guilsinglright" width="333" llx="111" lly="108" urx="314" ury="446"/>
+ <char name="h" width="556" llx="65" lly="0" urx="573" ury="718"/>
+ <char name="hungarumlaut" width="333" llx="157" lly="593" urx="565" ury="734"/>
+ <char name="hyphen" width="333" llx="93" lly="232" urx="357" ury="322"/>
+ <char name="i" width="222" llx="67" lly="0" urx="308" ury="718"/>
+ <char name="iacute" width="278" llx="95" lly="0" urx="448" ury="734"/>
+ <char name="icircumflex" width="278" llx="95" lly="0" urx="411" ury="734"/>
+ <char name="idieresis" width="278" llx="95" lly="0" urx="416" ury="706"/>
+ <char name="igrave" width="278" llx="95" lly="0" urx="310" ury="734"/>
+ <char name="j" width="222" llx="-60" lly="-210" urx="308" ury="718"/>
+ <char name="k" width="500" llx="67" lly="0" urx="600" ury="718"/>
+ <char name="l" width="222" llx="67" lly="0" urx="308" ury="718"/>
+ <char name="less" width="584" llx="94" lly="11" urx="641" ury="495"/>
+ <char name="logicalnot" width="584" llx="106" lly="108" urx="628" ury="390"/>
+ <char name="lslash" width="222" llx="41" lly="0" urx="347" ury="718"/>
+ <char name="m" width="833" llx="65" lly="0" urx="852" ury="538"/>
+ <char name="macron" width="333" llx="143" lly="627" urx="468" ury="684"/>
+ <char name="minus" width="584" llx="85" lly="216" urx="606" ury="289"/>
+ <char name="mu" width="556" llx="24" lly="-207" urx="600" ury="523"/>
+ <char name="multiply" width="584" llx="50" lly="0" urx="642" ury="506"/>
+ <char name="n" width="556" llx="65" lly="0" urx="573" ury="538"/>
+ <char name="nine" width="556" llx="82" lly="-19" urx="609" ury="703"/>
+ <char name="ntilde" width="556" llx="65" lly="0" urx="592" ury="722"/>
+ <char name="numbersign" width="556" llx="73" lly="0" urx="631" ury="688"/>
+ <char name="o" width="556" llx="83" lly="-14" urx="585" ury="538"/>
+ <char name="oacute" width="556" llx="83" lly="-14" urx="587" ury="734"/>
+ <char name="ocircumflex" width="556" llx="83" lly="-14" urx="585" ury="734"/>
+ <char name="odieresis" width="556" llx="83" lly="-14" urx="585" ury="706"/>
+ <char name="oe" width="944" llx="83" lly="-15" urx="964" ury="538"/>
+ <char name="ogonek" width="333" llx="43" lly="-225" urx="249" ury="0"/>
+ <char name="ograve" width="556" llx="83" lly="-14" urx="585" ury="734"/>
+ <char name="one" width="556" llx="207" lly="0" urx="508" ury="703"/>
+ <char name="onehalf" width="834" llx="114" lly="-19" urx="839" ury="703"/>
+ <char name="onequarter" width="834" llx="150" lly="-19" urx="802" ury="703"/>
+ <char name="onesuperior" width="333" llx="166" lly="281" urx="371" ury="703"/>
+ <char name="ordfeminine" width="370" llx="127" lly="405" urx="449" ury="737"/>
+ <char name="ordmasculine" width="365" llx="141" lly="405" urx="468" ury="737"/>
+ <char name="oslash" width="611" llx="29" lly="-22" urx="647" ury="545"/>
+ <char name="otilde" width="556" llx="83" lly="-14" urx="602" ury="722"/>
+ <char name="p" width="556" llx="14" lly="-207" urx="584" ury="538"/>
+ <char name="paragraph" width="537" llx="126" lly="-173" urx="650" ury="718"/>
+ <char name="parenleft" width="333" llx="108" lly="-207" urx="454" ury="733"/>
+ <char name="parenright" width="333" llx="-9" lly="-207" urx="337" ury="733"/>
+ <char name="percent" width="889" llx="147" lly="-19" urx="889" ury="703"/>
+ <char name="period" width="278" llx="87" lly="0" urx="214" ury="106"/>
+ <char name="periodcentered" width="278" llx="129" lly="190" urx="257" ury="315"/>
+ <char name="perthousand" width="1000" llx="88" lly="-19" urx="1029" ury="703"/>
+ <char name="plus" width="584" llx="85" lly="0" urx="606" ury="505"/>
+ <char name="plusminus" width="584" llx="39" lly="0" urx="618" ury="506"/>
+ <char name="q" width="556" llx="84" lly="-207" urx="605" ury="538"/>
+ <char name="question" width="556" llx="161" lly="0" urx="610" ury="727"/>
+ <char name="questiondown" width="611" llx="85" lly="-201" urx="534" ury="525"/>
+ <char name="quotedbl" width="355" llx="168" lly="463" urx="438" ury="718"/>
+ <char name="quotedblbase" width="333" llx="-6" lly="-149" urx="318" ury="106"/>
+ <char name="quotedblleft" width="333" llx="138" lly="470" urx="461" ury="725"/>
+ <char name="quotedblright" width="333" llx="124" lly="463" urx="448" ury="718"/>
+ <char name="quoteleft" width="222" llx="165" lly="470" urx="323" ury="725"/>
+ <char name="quoteright" width="222" llx="151" lly="463" urx="310" ury="718"/>
+ <char name="quotesinglbase" width="222" llx="21" lly="-149" urx="180" ury="106"/>
+ <char name="quotesingle" width="191" llx="157" lly="463" urx="285" ury="718"/>
+ <char name="r" width="333" llx="77" lly="0" urx="446" ury="538"/>
+ <char name="registered" width="737" llx="54" lly="-19" urx="837" ury="737"/>
+ <char name="ring" width="333" llx="214" lly="572" urx="402" ury="756"/>
+ <char name="s" width="500" llx="63" lly="-15" urx="529" ury="538"/>
+ <char name="scaron" width="500" llx="63" lly="-15" urx="552" ury="734"/>
+ <char name="section" width="556" llx="76" lly="-191" urx="584" ury="737"/>
+ <char name="semicolon" width="278" llx="56" lly="-147" urx="301" ury="516"/>
+ <char name="seven" width="556" llx="137" lly="0" urx="669" ury="688"/>
+ <char name="six" width="556" llx="91" lly="-19" urx="615" ury="703"/>
+ <char name="slash" width="278" llx="-21" lly="-19" urx="452" ury="737"/>
+ <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="278"/>
- <char name="sterling" width="556"/>
- <char name="t" width="278"/>
- <char name="thorn" width="556"/>
- <char name="three" width="556"/>
- <char name="threequarters" width="834"/>
- <char name="threesuperior" width="333"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="556"/>
- <char name="twosuperior" width="333"/>
- <char name="u" width="556"/>
- <char name="uacute" width="556"/>
- <char name="ucircumflex" width="556"/>
- <char name="udieresis" width="556"/>
- <char name="ugrave" width="556"/>
- <char name="underscore" width="556"/>
- <char name="v" width="500"/>
- <char name="w" width="722"/>
- <char name="x" width="500"/>
- <char name="y" width="500"/>
- <char name="yacute" width="500"/>
- <char name="ydieresis" width="500"/>
- <char name="yen" width="556"/>
- <char name="z" width="500"/>
- <char name="zcaron" width="500"/>
- <char name="zero" width="556"/>
- </widths>
+ <char name="sterling" width="556" llx="49" lly="-16" urx="634" ury="718"/>
+ <char name="t" width="278" llx="102" lly="-7" urx="368" ury="669"/>
+ <char name="thorn" width="556" llx="14" lly="-207" urx="584" ury="718"/>
+ <char name="three" width="556" llx="75" lly="-19" urx="610" ury="703"/>
+ <char name="threequarters" width="834" llx="130" lly="-19" urx="861" ury="703"/>
+ <char name="threesuperior" width="333" llx="90" lly="270" urx="436" ury="703"/>
+ <char name="tilde" width="333" llx="125" lly="606" urx="490" ury="722"/>
+ <char name="trademark" width="1000" llx="186" lly="306" urx="1056" ury="718"/>
+ <char name="two" width="556" llx="26" lly="0" urx="617" ury="703"/>
+ <char name="twosuperior" width="333" llx="64" lly="281" urx="449" ury="703"/>
+ <char name="u" width="556" llx="94" lly="-15" urx="600" ury="523"/>
+ <char name="uacute" width="556" llx="94" lly="-15" urx="600" ury="734"/>
+ <char name="ucircumflex" width="556" llx="94" lly="-15" urx="600" ury="734"/>
+ <char name="udieresis" width="556" llx="94" lly="-15" urx="600" ury="706"/>
+ <char name="ugrave" width="556" llx="94" lly="-15" urx="600" ury="734"/>
+ <char name="underscore" width="556" llx="-27" lly="-125" urx="540" ury="-75"/>
+ <char name="v" width="500" llx="119" lly="0" urx="603" ury="523"/>
+ <char name="w" width="722" llx="125" lly="0" urx="820" ury="523"/>
+ <char name="x" width="500" llx="11" lly="0" urx="594" ury="523"/>
+ <char name="y" width="500" llx="15" lly="-214" urx="600" ury="523"/>
+ <char name="yacute" width="500" llx="15" lly="-214" urx="600" ury="734"/>
+ <char name="ydieresis" width="500" llx="15" lly="-214" urx="600" ury="706"/>
+ <char name="yen" width="556" llx="81" lly="0" urx="699" ury="688"/>
+ <char name="z" width="500" llx="31" lly="0" urx="571" ury="523"/>
+ <char name="zcaron" width="500" llx="31" lly="0" urx="571" ury="734"/>
+ <char name="zero" width="556" llx="93" lly="-19" urx="608" ury="703"/>
+ </char-metrics>
<kerning kpx1="107">
<pair kern="-20" kpx2="111"/>
<pair kern="-20" kpx2="101"/>
@@ -602,4 +603,4 @@
<pair kern="-30" kpx2="118"/>
<pair kern="-15" kpx2="44"/>
</kerning>
-</font-metrics> \ No newline at end of file
+</font-metrics>
diff --git a/src/codegen/fonts/Symbol.xml b/src/codegen/fonts/Symbol.xml
index c0dce043a..7493b7e7f 100644
--- a/src/codegen/fonts/Symbol.xml
+++ b/src/codegen/fonts/Symbol.xml
@@ -21,203 +21,204 @@
<family-name>Symbol</family-name>
<class-name>Symbol</class-name>
<encoding>SymbolEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>1010</cap-height>
<x-height>520</x-height>
<ascender>1010</ascender>
<descender>-293</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="space" width="250"/>
- <char name="exclam" width="333"/>
- <char name="universal" width="713"/>
- <char name="numbersign" width="500"/>
- <char name="existential" width="549"/>
- <char name="percent" width="833"/>
- <char name="ampersand" width="778"/>
- <char name="suchthat" width="439"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="asteriskmath" width="500"/>
- <char name="plus" width="549"/>
- <char name="comma" width="250"/>
- <char name="minus" width="549"/>
- <char name="period" width="250"/>
- <char name="slash" width="278"/>
- <char name="zero" width="500"/>
- <char name="one" width="500"/>
- <char name="two" width="500"/>
- <char name="three" width="500"/>
- <char name="four" width="500"/>
- <char name="five" width="500"/>
- <char name="six" width="500"/>
- <char name="seven" width="500"/>
- <char name="eight" width="500"/>
- <char name="nine" width="500"/>
- <char name="colon" width="278"/>
- <char name="semicolon" width="278"/>
- <char name="less" width="549"/>
- <char name="equal" width="549"/>
- <char name="greater" width="549"/>
- <char name="question" width="444"/>
- <char name="congruent" width="549"/>
- <char name="Alpha" width="722"/>
- <char name="Beta" width="667"/>
- <char name="Chi" width="722"/>
- <char name="Delta" width="612"/>
- <char name="Epsilon" width="611"/>
- <char name="Phi" width="763"/>
- <char name="Gamma" width="603"/>
- <char name="Eta" width="722"/>
- <char name="Iota" width="333"/>
- <char name="theta1" width="631"/>
- <char name="Kappa" width="722"/>
- <char name="Lambda" width="686"/>
- <char name="Mu" width="889"/>
- <char name="Nu" width="722"/>
- <char name="Omicron" width="722"/>
- <char name="Pi" width="768"/>
- <char name="Theta" width="741"/>
- <char name="Rho" width="556"/>
- <char name="Sigma" width="592"/>
- <char name="Tau" width="611"/>
- <char name="Upsilon" width="690"/>
- <char name="sigma1" width="439"/>
- <char name="Omega" width="768"/>
- <char name="Xi" width="645"/>
- <char name="Psi" width="795"/>
- <char name="Zeta" width="611"/>
- <char name="bracketleft" width="333"/>
- <char name="therefore" width="863"/>
- <char name="bracketright" width="333"/>
- <char name="perpendicular" width="658"/>
- <char name="underscore" width="500"/>
- <char name="radicalex" width="500"/>
- <char name="alpha" width="631"/>
- <char name="beta" width="549"/>
- <char name="chi" width="549"/>
- <char name="delta" width="494"/>
- <char name="epsilon" width="439"/>
- <char name="phi" width="521"/>
- <char name="gamma" width="411"/>
- <char name="eta" width="603"/>
- <char name="iota" width="329"/>
- <char name="phi1" width="603"/>
- <char name="kappa" width="549"/>
- <char name="lambda" width="549"/>
- <char name="m" width="576"/>
- <char name="mu" width="576"/>
- <char name="nu" width="521"/>
- <char name="omicron" width="549"/>
- <char name="pi" width="549"/>
- <char name="theta" width="521"/>
- <char name="rho" width="549"/>
- <char name="sigma" width="603"/>
- <char name="tau" width="439"/>
- <char name="upsilon" width="576"/>
- <char name="omega1" width="713"/>
- <char name="omega" width="686"/>
- <char name="xi" width="493"/>
- <char name="psi" width="686"/>
- <char name="zeta" width="494"/>
- <char name="braceleft" width="480"/>
- <char name="bar" width="200"/>
- <char name="braceright" width="480"/>
- <char name="similar" width="549"/>
- <char name="Euro" width="750"/>
- <char name="Upsilon1" width="620"/>
- <char name="minute" width="247"/>
- <char name="lessequal" width="549"/>
- <char name="fraction" width="167"/>
- <char name="infinity" width="713"/>
- <char name="florin" width="500"/>
- <char name="club" width="753"/>
- <char name="diamond" width="753"/>
- <char name="heart" width="753"/>
- <char name="spade" width="753"/>
- <char name="arrowboth" width="1042"/>
- <char name="arrowleft" width="987"/>
- <char name="arrowup" width="603"/>
- <char name="arrowright" width="987"/>
- <char name="arrowdown" width="603"/>
- <char name="degree" width="400"/>
- <char name="plusminus" width="549"/>
- <char name="second" width="411"/>
- <char name="greaterequal" width="549"/>
- <char name="multiply" width="549"/>
- <char name="proportional" width="713"/>
- <char name="partialdiff" width="494"/>
- <char name="bullet" width="460"/>
- <char name="divide" width="549"/>
- <char name="notequal" width="549"/>
- <char name="equivalence" width="549"/>
- <char name="approxequal" width="549"/>
- <char name="ellipsis" width="1000"/>
- <char name="arrowvertex" width="603"/>
- <char name="arrowhorizex" width="1000"/>
- <char name="carriagereturn" width="658"/>
- <char name="aleph" width="823"/>
- <char name="Ifraktur" width="686"/>
- <char name="Rfraktur" width="795"/>
- <char name="weierstrass" width="987"/>
- <char name="circlemultiply" width="768"/>
- <char name="circleplus" width="768"/>
- <char name="emptyset" width="823"/>
- <char name="intersection" width="768"/>
- <char name="union" width="768"/>
- <char name="propersuperset" width="713"/>
- <char name="reflexsuperset" width="713"/>
- <char name="notsubset" width="713"/>
- <char name="propersubset" width="713"/>
- <char name="reflexsubset" width="713"/>
- <char name="element" width="713"/>
- <char name="notelement" width="713"/>
- <char name="angle" width="768"/>
- <char name="gradient" width="713"/>
- <char name="registerserif" width="790"/>
- <char name="copyrightserif" width="790"/>
- <char name="trademarkserif" width="890"/>
- <char name="product" width="823"/>
- <char name="radical" width="549"/>
- <char name="dotmath" width="250"/>
- <char name="logicalnot" width="713"/>
- <char name="logicaland" width="603"/>
- <char name="logicalor" width="603"/>
- <char name="arrowdblboth" width="1042"/>
- <char name="arrowdblleft" width="987"/>
- <char name="arrowdblup" width="603"/>
- <char name="arrowdblright" width="987"/>
- <char name="arrowdbldown" width="603"/>
- <char name="lozenge" width="494"/>
- <char name="angleleft" width="329"/>
- <char name="registersans" width="790"/>
- <char name="copyrightsans" width="790"/>
- <char name="trademarksans" width="786"/>
- <char name="summation" width="713"/>
- <char name="parenlefttp" width="384"/>
- <char name="parenleftex" width="384"/>
- <char name="parenleftbt" width="384"/>
- <char name="bracketlefttp" width="384"/>
- <char name="bracketleftex" width="384"/>
- <char name="bracketleftbt" width="384"/>
- <char name="bracelefttp" width="494"/>
- <char name="braceleftmid" width="494"/>
- <char name="braceleftbt" width="494"/>
- <char name="braceex" width="494"/>
- <char name="angleright" width="329"/>
- <char name="integral" width="274"/>
- <char name="integraltp" width="686"/>
- <char name="integralex" width="686"/>
- <char name="integralbt" width="686"/>
- <char name="parenrighttp" width="384"/>
- <char name="parenrightex" width="384"/>
- <char name="parenrightbt" width="384"/>
- <char name="bracketrighttp" width="384"/>
- <char name="bracketrightex" width="384"/>
- <char name="bracketrightbt" width="384"/>
- <char name="bracerighttp" width="494"/>
- <char name="bracerightmid" width="494"/>
- <char name="bracerightbt" width="494"/>
- <char name="apple" width="790"/>
- </widths>
+ <char-metrics>
+ <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="exclam" width="333" llx="128" lly="-17" urx="240" ury="672"/>
+ <char name="universal" width="713" llx="31" lly="0" urx="681" ury="705"/>
+ <char name="numbersign" width="500" llx="20" lly="-16" urx="481" ury="673"/>
+ <char name="existential" width="549" llx="25" lly="0" urx="478" ury="707"/>
+ <char name="percent" width="833" llx="63" lly="-36" urx="771" ury="655"/>
+ <char name="ampersand" width="778" llx="41" lly="-18" urx="750" ury="661"/>
+ <char name="suchthat" width="439" llx="48" lly="-17" urx="414" ury="500"/>
+ <char name="parenleft" width="333" llx="53" lly="-191" urx="300" ury="673"/>
+ <char name="parenright" width="333" llx="30" lly="-191" urx="277" ury="673"/>
+ <char name="asteriskmath" width="500" llx="65" lly="134" urx="427" ury="551"/>
+ <char name="plus" width="549" llx="10" lly="0" urx="539" ury="533"/>
+ <char name="comma" width="250" llx="56" lly="-152" urx="194" ury="104"/>
+ <char name="minus" width="549" llx="11" lly="233" urx="535" ury="288"/>
+ <char name="period" width="250" llx="69" lly="-17" urx="181" ury="95"/>
+ <char name="slash" width="278" llx="0" lly="-18" urx="254" ury="646"/>
+ <char name="zero" width="500" llx="24" lly="-14" urx="476" ury="685"/>
+ <char name="one" width="500" llx="117" lly="0" urx="390" ury="673"/>
+ <char name="two" width="500" llx="25" lly="0" urx="475" ury="685"/>
+ <char name="three" width="500" llx="43" lly="-14" urx="435" ury="685"/>
+ <char name="four" width="500" llx="15" lly="0" urx="469" ury="685"/>
+ <char name="five" width="500" llx="32" lly="-14" urx="445" ury="690"/>
+ <char name="six" width="500" llx="34" lly="-14" urx="468" ury="685"/>
+ <char name="seven" width="500" llx="24" lly="-16" urx="448" ury="673"/>
+ <char name="eight" width="500" llx="56" lly="-14" urx="445" ury="685"/>
+ <char name="nine" width="500" llx="30" lly="-18" urx="459" ury="685"/>
+ <char name="colon" width="278" llx="81" lly="-17" urx="193" ury="460"/>
+ <char name="semicolon" width="278" llx="83" lly="-152" urx="221" ury="460"/>
+ <char name="less" width="549" llx="26" lly="0" urx="523" ury="522"/>
+ <char name="equal" width="549" llx="11" lly="141" urx="537" ury="390"/>
+ <char name="greater" width="549" llx="26" lly="0" urx="523" ury="522"/>
+ <char name="question" width="444" llx="70" lly="-17" urx="412" ury="686"/>
+ <char name="congruent" width="549" llx="11" lly="0" urx="537" ury="475"/>
+ <char name="Alpha" width="722" llx="4" lly="0" urx="684" ury="673"/>
+ <char name="Beta" width="667" llx="29" lly="0" urx="592" ury="673"/>
+ <char name="Chi" width="722" llx="-9" lly="0" urx="704" ury="673"/>
+ <char name="Delta" width="612" llx="6" lly="0" urx="608" ury="688"/>
+ <char name="Epsilon" width="611" llx="32" lly="0" urx="617" ury="673"/>
+ <char name="Phi" width="763" llx="26" lly="0" urx="741" ury="673"/>
+ <char name="Gamma" width="603" llx="24" lly="0" urx="609" ury="673"/>
+ <char name="Eta" width="722" llx="39" lly="0" urx="729" ury="673"/>
+ <char name="Iota" width="333" llx="32" lly="0" urx="316" ury="673"/>
+ <char name="theta1" width="631" llx="18" lly="-18" urx="623" ury="689"/>
+ <char name="Kappa" width="722" llx="35" lly="0" urx="722" ury="673"/>
+ <char name="Lambda" width="686" llx="6" lly="0" urx="680" ury="688"/>
+ <char name="Mu" width="889" llx="28" lly="0" urx="887" ury="673"/>
+ <char name="Nu" width="722" llx="29" lly="-8" urx="720" ury="673"/>
+ <char name="Omicron" width="722" llx="41" lly="-17" urx="715" ury="685"/>
+ <char name="Pi" width="768" llx="25" lly="0" urx="745" ury="673"/>
+ <char name="Theta" width="741" llx="41" lly="-17" urx="715" ury="685"/>
+ <char name="Rho" width="556" llx="28" lly="0" urx="563" ury="673"/>
+ <char name="Sigma" width="592" llx="5" lly="0" urx="589" ury="673"/>
+ <char name="Tau" width="611" llx="33" lly="0" urx="607" ury="673"/>
+ <char name="Upsilon" width="690" llx="-8" lly="0" urx="694" ury="673"/>
+ <char name="sigma1" width="439" llx="40" lly="-233" urx="436" ury="500"/>
+ <char name="Omega" width="768" llx="34" lly="0" urx="736" ury="688"/>
+ <char name="Xi" width="645" llx="40" lly="0" urx="599" ury="673"/>
+ <char name="Psi" width="795" llx="15" lly="0" urx="781" ury="684"/>
+ <char name="Zeta" width="611" llx="44" lly="0" urx="636" ury="673"/>
+ <char name="bracketleft" width="333" llx="86" lly="-155" urx="299" ury="674"/>
+ <char name="therefore" width="863" llx="163" lly="0" urx="701" ury="487"/>
+ <char name="bracketright" width="333" llx="33" lly="-155" urx="246" ury="674"/>
+ <char name="perpendicular" width="658" llx="15" lly="0" urx="652" ury="674"/>
+ <char name="underscore" width="500" llx="-2" lly="-125" urx="502" ury="-75"/>
+ <char name="radicalex" width="500" llx="480" lly="881" urx="1090" ury="917"/>
+ <char name="alpha" width="631" llx="41" lly="-18" urx="622" ury="500"/>
+ <char name="beta" width="549" llx="61" lly="-223" urx="515" ury="741"/>
+ <char name="chi" width="549" llx="12" lly="-231" urx="522" ury="499"/>
+ <char name="delta" width="494" llx="40" lly="-19" urx="481" ury="740"/>
+ <char name="epsilon" width="439" llx="22" lly="-19" urx="427" ury="502"/>
+ <char name="phi" width="521" llx="28" lly="-224" urx="492" ury="673"/>
+ <char name="gamma" width="411" llx="5" lly="-225" urx="484" ury="499"/>
+ <char name="eta" width="603" llx="0" lly="-202" urx="527" ury="514"/>
+ <char name="iota" width="329" llx="0" lly="-17" urx="301" ury="503"/>
+ <char name="phi1" width="603" llx="36" lly="-224" urx="587" ury="499"/>
+ <char name="kappa" width="549" llx="33" lly="0" urx="558" ury="501"/>
+ <char name="lambda" width="549" llx="24" lly="-17" urx="548" ury="739"/>
+ <char name="mu" width="576" llx="33" lly="-223" urx="567" ury="500"/>
+ <char name="nu" width="521" llx="-9" lly="-16" urx="475" ury="507"/>
+ <char name="omicron" width="549" llx="35" lly="-19" urx="501" ury="499"/>
+ <char name="pi" width="549" llx="10" lly="-19" urx="530" ury="487"/>
+ <char name="theta" width="521" llx="43" lly="-17" urx="485" ury="690"/>
+ <char name="rho" width="549" llx="50" lly="-230" urx="490" ury="499"/>
+ <char name="sigma" width="603" llx="30" lly="-21" urx="588" ury="500"/>
+ <char name="tau" width="439" llx="10" lly="-19" urx="418" ury="500"/>
+ <char name="upsilon" width="576" llx="7" lly="-18" urx="535" ury="507"/>
+ <char name="omega1" width="713" llx="12" lly="-18" urx="671" ury="583"/>
+ <char name="omega" width="686" llx="42" lly="-17" urx="684" ury="500"/>
+ <char name="xi" width="493" llx="27" lly="-224" urx="469" ury="766"/>
+ <char name="psi" width="686" llx="12" lly="-228" urx="701" ury="500"/>
+ <char name="zeta" width="494" llx="60" lly="-225" urx="467" ury="756"/>
+ <char name="braceleft" width="480" llx="58" lly="-183" urx="397" ury="673"/>
+ <char name="bar" width="200" llx="65" lly="-293" urx="135" ury="707"/>
+ <char name="braceright" width="480" llx="79" lly="-183" urx="418" ury="673"/>
+ <char name="similar" width="549" llx="17" lly="203" urx="529" ury="307"/>
+ <char name="Euro" width="750" llx="20" lly="-12" urx="714" ury="685"/>
+ <char name="Upsilon1" width="620" llx="-2" lly="0" urx="610" ury="685"/>
+ <char name="minute" width="247" llx="27" lly="459" urx="228" ury="735"/>
+ <char name="lessequal" width="549" llx="29" lly="0" urx="526" ury="639"/>
+ <char name="fraction" width="167" llx="-180" lly="-12" urx="340" ury="677"/>
+ <char name="infinity" width="713" llx="26" lly="124" urx="688" ury="404"/>
+ <char name="florin" width="500" llx="2" lly="-193" urx="494" ury="686"/>
+ <char name="club" width="753" llx="86" lly="-26" urx="660" ury="533"/>
+ <char name="diamond" width="753" llx="142" lly="-36" urx="600" ury="550"/>
+ <char name="heart" width="753" llx="117" lly="-33" urx="631" ury="532"/>
+ <char name="spade" width="753" llx="113" lly="-36" urx="629" ury="548"/>
+ <char name="arrowboth" width="1042" llx="24" lly="-15" urx="1024" ury="511"/>
+ <char name="arrowleft" width="987" llx="32" lly="-15" urx="942" ury="511"/>
+ <char name="arrowup" width="603" llx="45" lly="0" urx="571" ury="910"/>
+ <char name="arrowright" width="987" llx="49" lly="-15" urx="959" ury="511"/>
+ <char name="arrowdown" width="603" llx="45" lly="-22" urx="571" ury="888"/>
+ <char name="degree" width="400" llx="50" lly="385" urx="350" ury="685"/>
+ <char name="plusminus" width="549" llx="10" lly="0" urx="539" ury="645"/>
+ <char name="second" width="411" llx="20" lly="459" urx="413" ury="737"/>
+ <char name="greaterequal" width="549" llx="29" lly="0" urx="526" ury="639"/>
+ <char name="multiply" width="549" llx="17" lly="8" urx="533" ury="524"/>
+ <char name="proportional" width="713" llx="27" lly="123" urx="639" ury="404"/>
+ <char name="partialdiff" width="494" llx="26" lly="-20" urx="462" ury="746"/>
+ <char name="bullet" width="460" llx="50" lly="113" urx="410" ury="473"/>
+ <char name="divide" width="549" llx="10" lly="71" urx="536" ury="456"/>
+ <char name="notequal" width="549" llx="15" lly="-25" urx="540" ury="549"/>
+ <char name="equivalence" width="549" llx="14" lly="82" urx="538" ury="443"/>
+ <char name="approxequal" width="549" llx="14" lly="135" urx="527" ury="394"/>
+ <char name="ellipsis" width="1000" llx="111" lly="-17" urx="889" ury="95"/>
+ <char name="arrowvertex" width="603" llx="280" lly="-120" urx="336" ury="1010"/>
+ <char name="arrowhorizex" width="1000" llx="-60" lly="220" urx="1050" ury="276"/>
+ <char name="carriagereturn" width="658" llx="15" lly="-16" urx="602" ury="629"/>
+ <char name="aleph" width="823" llx="175" lly="-18" urx="661" ury="658"/>
+ <char name="Ifraktur" width="686" llx="10" lly="-53" urx="578" ury="740"/>
+ <char name="Rfraktur" width="795" llx="26" lly="-15" urx="759" ury="734"/>
+ <char name="weierstrass" width="987" llx="159" lly="-211" urx="870" ury="573"/>
+ <char name="circlemultiply" width="768" llx="43" lly="-17" urx="733" ury="673"/>
+ <char name="circleplus" width="768" llx="43" lly="-15" urx="733" ury="675"/>
+ <char name="emptyset" width="823" llx="39" lly="-24" urx="781" ury="719"/>
+ <char name="intersection" width="768" llx="40" lly="0" urx="732" ury="509"/>
+ <char name="union" width="768" llx="40" lly="-17" urx="732" ury="492"/>
+ <char name="propersuperset" width="713" llx="20" lly="0" urx="673" ury="470"/>
+ <char name="reflexsuperset" width="713" llx="20" lly="-125" urx="673" ury="470"/>
+ <char name="notsubset" width="713" llx="36" lly="-70" urx="690" ury="540"/>
+ <char name="propersubset" width="713" llx="37" lly="0" urx="690" ury="470"/>
+ <char name="reflexsubset" width="713" llx="37" lly="-125" urx="690" ury="470"/>
+ <char name="element" width="713" llx="45" lly="0" urx="505" ury="468"/>
+ <char name="notelement" width="713" llx="45" lly="-58" urx="505" ury="555"/>
+ <char name="angle" width="768" llx="26" lly="0" urx="738" ury="673"/>
+ <char name="gradient" width="713" llx="36" lly="-19" urx="681" ury="718"/>
+ <char name="registerserif" width="790" llx="50" lly="-17" urx="740" ury="673"/>
+ <char name="copyrightserif" width="790" llx="51" lly="-15" urx="741" ury="675"/>
+ <char name="trademarkserif" width="890" llx="18" lly="293" urx="855" ury="673"/>
+ <char name="product" width="823" llx="25" lly="-101" urx="803" ury="751"/>
+ <char name="radical" width="549" llx="10" lly="-38" urx="515" ury="917"/>
+ <char name="dotmath" width="250" llx="69" lly="210" urx="169" ury="310"/>
+ <char name="logicalnot" width="713" llx="15" lly="0" urx="680" ury="288"/>
+ <char name="logicaland" width="603" llx="23" lly="0" urx="583" ury="454"/>
+ <char name="logicalor" width="603" llx="30" lly="0" urx="578" ury="477"/>
+ <char name="arrowdblboth" width="1042" llx="27" lly="-20" urx="1023" ury="510"/>
+ <char name="arrowdblleft" width="987" llx="30" lly="-15" urx="939" ury="513"/>
+ <char name="arrowdblup" width="603" llx="39" lly="2" urx="567" ury="911"/>
+ <char name="arrowdblright" width="987" llx="45" lly="-20" urx="954" ury="508"/>
+ <char name="arrowdbldown" width="603" llx="44" lly="-19" urx="572" ury="890"/>
+ <char name="lozenge" width="494" llx="18" lly="0" urx="466" ury="745"/>
+ <char name="angleleft" width="329" llx="25" lly="-198" urx="306" ury="746"/>
+ <char name="registersans" width="790" llx="50" lly="-20" urx="740" ury="670"/>
+ <char name="copyrightsans" width="790" llx="49" lly="-15" urx="739" ury="675"/>
+ <char name="trademarksans" width="786" llx="5" lly="293" urx="725" ury="673"/>
+ <char name="summation" width="713" llx="14" lly="-108" urx="695" ury="752"/>
+ <char name="parenlefttp" width="384" llx="24" lly="-293" urx="436" ury="926"/>
+ <char name="parenleftex" width="384" llx="24" lly="-85" urx="108" ury="925"/>
+ <char name="parenleftbt" width="384" llx="24" lly="-293" urx="436" ury="926"/>
+ <char name="bracketlefttp" width="384" llx="0" lly="-80" urx="349" ury="926"/>
+ <char name="bracketleftex" width="384" llx="0" lly="-79" urx="77" ury="925"/>
+ <char name="bracketleftbt" width="384" llx="0" lly="-80" urx="349" ury="926"/>
+ <char name="bracelefttp" width="494" llx="209" lly="-85" urx="445" ury="925"/>
+ <char name="braceleftmid" width="494" llx="20" lly="-85" urx="284" ury="935"/>
+ <char name="braceleftbt" width="494" llx="209" lly="-75" urx="445" ury="935"/>
+ <char name="braceex" width="494" llx="209" lly="-85" urx="284" ury="935"/>
+ <char name="angleright" width="329" llx="21" lly="-198" urx="302" ury="746"/>
+ <char name="integral" width="274" llx="2" lly="-107" urx="291" ury="916"/>
+ <char name="integraltp" width="686" llx="308" lly="-88" urx="675" ury="920"/>
+ <char name="integralex" width="686" llx="308" lly="-88" urx="378" ury="975"/>
+ <char name="integralbt" width="686" llx="11" lly="-87" urx="378" ury="921"/>
+ <char name="parenrighttp" width="384" llx="54" lly="-293" urx="466" ury="926"/>
+ <char name="parenrightex" width="384" llx="382" lly="-85" urx="466" ury="925"/>
+ <char name="parenrightbt" width="384" llx="54" lly="-293" urx="466" ury="926"/>
+ <char name="bracketrighttp" width="384" llx="22" lly="-80" urx="371" ury="926"/>
+ <char name="bracketrightex" width="384" llx="294" lly="-79" urx="371" ury="925"/>
+ <char name="bracketrightbt" width="384" llx="22" lly="-80" urx="371" ury="926"/>
+ <char name="bracerighttp" width="494" llx="48" lly="-85" urx="284" ury="925"/>
+ <char name="bracerightmid" width="494" llx="209" lly="-85" urx="473" ury="935"/>
+ <char name="bracerightbt" width="494" llx="48" lly="-75" urx="284" ury="935"/>
+ <char name="apple" width="790" llx="56" lly="-3" urx="733" ury="808"/>
+ </char-metrics>
</font-metrics>
diff --git a/src/codegen/fonts/TimesBold.xml b/src/codegen/fonts/TimesBold.xml
index 20d50fdd8..ef5d6bcc0 100644
--- a/src/codegen/fonts/TimesBold.xml
+++ b/src/codegen/fonts/TimesBold.xml
@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesBold</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>676</cap-height>
<x-height>461</x-height>
<ascender>676</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="722"/>
- <char name="AE" width="1000"/>
- <char name="Aacute" width="722"/>
- <char name="Acircumflex" width="722"/>
- <char name="Adieresis" width="722"/>
- <char name="Agrave" width="722"/>
- <char name="Aring" width="722"/>
- <char name="Atilde" width="722"/>
- <char name="B" width="667"/>
- <char name="C" width="722"/>
- <char name="Ccedilla" width="722"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="500"/>
- <char name="F" width="611"/>
- <char name="G" width="778"/>
- <char name="H" width="778"/>
- <char name="I" width="389"/>
- <char name="Iacute" width="389"/>
- <char name="Icircumflex" width="389"/>
- <char name="Idieresis" width="389"/>
- <char name="Igrave" width="389"/>
- <char name="J" width="500"/>
- <char name="K" width="778"/>
- <char name="L" width="667"/>
- <char name="Lslash" width="667"/>
- <char name="M" width="944"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="778"/>
- <char name="OE" width="1000"/>
- <char name="Oacute" width="778"/>
- <char name="Ocircumflex" width="778"/>
- <char name="Odieresis" width="778"/>
- <char name="Ograve" width="778"/>
- <char name="Oslash" width="778"/>
- <char name="Otilde" width="778"/>
- <char name="P" width="611"/>
- <char name="Q" width="778"/>
- <char name="R" width="722"/>
- <char name="S" width="556"/>
- <char name="Scaron" width="556"/>
- <char name="T" width="667"/>
- <char name="Thorn" width="611"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="722"/>
- <char name="W" width="1000"/>
- <char name="X" width="722"/>
- <char name="Y" width="722"/>
- <char name="Yacute" width="722"/>
- <char name="Ydieresis" width="722"/>
- <char name="Z" width="667"/>
- <char name="Zcaron" width="667"/>
- <char name="a" width="500"/>
- <char name="aacute" width="500"/>
- <char name="acircumflex" width="500"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="500"/>
- <char name="ae" width="722"/>
- <char name="agrave" width="500"/>
- <char name="ampersand" width="833"/>
- <char name="aring" width="500"/>
- <char name="asciicircum" width="581"/>
- <char name="asciitilde" width="520"/>
- <char name="asterisk" width="500"/>
- <char name="at" width="930"/>
- <char name="atilde" width="500"/>
- <char name="b" width="556"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="220"/>
- <char name="braceleft" width="394"/>
- <char name="braceright" width="394"/>
- <char name="bracketleft" width="333"/>
- <char name="bracketright" width="333"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="220"/>
- <char name="bullet" width="350"/>
- <char name="c" width="444"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="444"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="500"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="333"/>
- <char name="comma" width="250"/>
- <char name="copyright" width="747"/>
- <char name="currency" width="500"/>
- <char name="d" width="556"/>
- <char name="dagger" width="500"/>
- <char name="daggerdbl" width="500"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="570"/>
- <char name="dollar" width="500"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="444"/>
- <char name="eacute" width="444"/>
- <char name="ecircumflex" width="444"/>
- <char name="edieresis" width="444"/>
- <char name="egrave" width="444"/>
- <char name="eight" width="500"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="500"/>
- <char name="equal" width="570"/>
- <char name="eth" width="500"/>
- <char name="exclam" width="333"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="333"/>
- <char name="fi" width="556"/>
- <char name="five" width="500"/>
- <char name="fl" width="556"/>
- <char name="florin" width="500"/>
- <char name="four" width="500"/>
- <char name="fraction" width="167"/>
- <char name="g" width="500"/>
- <char name="germandbls" width="556"/>
- <char name="grave" width="333"/>
- <char name="greater" width="570"/>
- <char name="guillemotleft" width="500"/>
- <char name="guillemotright" width="500"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="556"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="333"/>
- <char name="k" width="556"/>
- <char name="l" width="278"/>
- <char name="less" width="570"/>
- <char name="logicalnot" width="570"/>
- <char name="lslash" width="278"/>
- <char name="m" width="833"/>
- <char name="macron" width="333"/>
- <char name="minus" width="324"/>
- <char name="mu" width="556"/>
- <char name="multiply" width="570"/>
- <char name="n" width="556"/>
- <char name="nine" width="500"/>
- <char name="ntilde" width="556"/>
- <char name="numbersign" width="500"/>
- <char name="o" width="500"/>
- <char name="oacute" width="500"/>
- <char name="ocircumflex" width="500"/>
- <char name="odieresis" width="500"/>
- <char name="oe" width="722"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="500"/>
- <char name="one" width="500"/>
- <char name="onehalf" width="750"/>
- <char name="onequarter" width="750"/>
- <char name="onesuperior" width="300"/>
- <char name="ordfeminine" width="300"/>
- <char name="ordmasculine" width="330"/>
- <char name="oslash" width="500"/>
- <char name="otilde" width="500"/>
- <char name="p" width="556"/>
- <char name="paragraph" width="540"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="1000"/>
- <char name="period" width="250"/>
- <char name="periodcentered" width="250"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="570"/>
- <char name="plusminus" width="570"/>
- <char name="q" width="556"/>
- <char name="question" width="500"/>
- <char name="questiondown" width="500"/>
- <char name="quotedbl" width="555"/>
- <char name="quotedblbase" width="500"/>
- <char name="quotedblleft" width="500"/>
- <char name="quotedblright" width="500"/>
- <char name="quoteleft" width="333"/>
- <char name="quoteright" width="333"/>
- <char name="quotesinglbase" width="333"/>
- <char name="quotesingle" width="278"/>
- <char name="r" width="444"/>
- <char name="registered" width="747"/>
- <char name="ring" width="333"/>
- <char name="s" width="389"/>
- <char name="scaron" width="389"/>
- <char name="section" width="500"/>
- <char name="semicolon" width="333"/>
- <char name="seven" width="500"/>
- <char name="six" width="500"/>
- <char name="slash" width="278"/>
- <char name="space" width="250"/>
+ <char-metrics>
+ <char name="A" width="722" llx="9" lly="0" urx="689" ury="690"/>
+ <char name="AE" width="1000" llx="4" lly="0" urx="951" ury="676"/>
+ <char name="Aacute" width="722" llx="9" lly="0" urx="689" ury="923"/>
+ <char name="Acircumflex" width="722" llx="9" lly="0" urx="689" ury="914"/>
+ <char name="Adieresis" width="722" llx="9" lly="0" urx="689" ury="877"/>
+ <char name="Agrave" width="722" llx="9" lly="0" urx="689" ury="923"/>
+ <char name="Aring" width="722" llx="9" lly="0" urx="689" ury="935"/>
+ <char name="Atilde" width="722" llx="9" lly="0" urx="689" ury="884"/>
+ <char name="B" width="667" llx="16" lly="0" urx="619" ury="676"/>
+ <char name="C" width="722" llx="49" lly="-19" urx="687" ury="691"/>
+ <char name="Ccedilla" width="722" llx="49" lly="-218" urx="687" ury="691"/>
+ <char name="D" width="722" llx="14" lly="0" urx="690" ury="676"/>
+ <char name="E" width="667" llx="16" lly="0" urx="641" ury="676"/>
+ <char name="Eacute" width="667" llx="16" lly="0" urx="641" ury="923"/>
+ <char name="Ecircumflex" width="667" llx="16" lly="0" urx="641" ury="914"/>
+ <char name="Edieresis" width="667" llx="16" lly="0" urx="641" ury="877"/>
+ <char name="Egrave" width="667" llx="16" lly="0" urx="641" ury="923"/>
+ <char name="Eth" width="722" llx="6" lly="0" urx="690" ury="676"/>
+ <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="16" lly="0" urx="583" ury="676"/>
+ <char name="G" width="778" llx="37" lly="-19" urx="755" ury="691"/>
+ <char name="H" width="778" llx="21" lly="0" urx="759" ury="676"/>
+ <char name="I" width="389" llx="20" lly="0" urx="370" ury="676"/>
+ <char name="Iacute" width="389" llx="20" lly="0" urx="370" ury="923"/>
+ <char name="Icircumflex" width="389" llx="20" lly="0" urx="370" ury="914"/>
+ <char name="Idieresis" width="389" llx="20" lly="0" urx="370" ury="877"/>
+ <char name="Igrave" width="389" llx="20" lly="0" urx="370" ury="923"/>
+ <char name="J" width="500" llx="3" lly="-96" urx="479" ury="676"/>
+ <char name="K" width="778" llx="30" lly="0" urx="769" ury="676"/>
+ <char name="L" width="667" llx="19" lly="0" urx="638" ury="676"/>
+ <char name="Lslash" width="667" llx="19" lly="0" urx="638" ury="676"/>
+ <char name="M" width="944" llx="14" lly="0" urx="921" ury="676"/>
+ <char name="N" width="722" llx="16" lly="-18" urx="701" ury="676"/>
+ <char name="Ntilde" width="722" llx="16" lly="-18" urx="701" ury="884"/>
+ <char name="O" width="778" llx="35" lly="-19" urx="743" ury="691"/>
+ <char name="OE" width="1000" llx="22" lly="-5" urx="981" ury="684"/>
+ <char name="Oacute" width="778" llx="35" lly="-19" urx="743" ury="923"/>
+ <char name="Ocircumflex" width="778" llx="35" lly="-19" urx="743" ury="914"/>
+ <char name="Odieresis" width="778" llx="35" lly="-19" urx="743" ury="877"/>
+ <char name="Ograve" width="778" llx="35" lly="-19" urx="743" ury="923"/>
+ <char name="Oslash" width="778" llx="35" lly="-74" urx="743" ury="737"/>
+ <char name="Otilde" width="778" llx="35" lly="-19" urx="743" ury="884"/>
+ <char name="P" width="611" llx="16" lly="0" urx="600" ury="676"/>
+ <char name="Q" width="778" llx="35" lly="-176" urx="743" ury="691"/>
+ <char name="R" width="722" llx="26" lly="0" urx="715" ury="676"/>
+ <char name="S" width="556" llx="35" lly="-19" urx="513" ury="692"/>
+ <char name="Scaron" width="556" llx="35" lly="-19" urx="513" ury="914"/>
+ <char name="T" width="667" llx="31" lly="0" urx="636" ury="676"/>
+ <char name="Thorn" width="611" llx="16" lly="0" urx="600" ury="676"/>
+ <char name="U" width="722" llx="16" lly="-19" urx="701" ury="676"/>
+ <char name="Uacute" width="722" llx="16" lly="-19" urx="701" ury="923"/>
+ <char name="Ucircumflex" width="722" llx="16" lly="-19" urx="701" ury="914"/>
+ <char name="Udieresis" width="722" llx="16" lly="-19" urx="701" ury="877"/>
+ <char name="Ugrave" width="722" llx="16" lly="-19" urx="701" ury="923"/>
+ <char name="V" width="722" llx="16" lly="-18" urx="701" ury="676"/>
+ <char name="W" width="1000" llx="19" lly="-15" urx="981" ury="676"/>
+ <char name="X" width="722" llx="16" lly="0" urx="699" ury="676"/>
+ <char name="Y" width="722" llx="15" lly="0" urx="699" ury="676"/>
+ <char name="Yacute" width="722" llx="15" lly="0" urx="699" ury="923"/>
+ <char name="Ydieresis" width="722" llx="15" lly="0" urx="699" ury="877"/>
+ <char name="Z" width="667" llx="28" lly="0" urx="634" ury="676"/>
+ <char name="Zcaron" width="667" llx="28" lly="0" urx="634" ury="914"/>
+ <char name="a" width="500" llx="25" lly="-14" urx="488" ury="473"/>
+ <char name="aacute" width="500" llx="25" lly="-14" urx="488" ury="713"/>
+ <char name="acircumflex" width="500" llx="25" lly="-14" urx="488" ury="704"/>
+ <char name="acute" width="333" llx="86" lly="528" urx="324" ury="713"/>
+ <char name="adieresis" width="500" llx="25" lly="-14" urx="488" ury="667"/>
+ <char name="ae" width="722" llx="33" lly="-14" urx="693" ury="473"/>
+ <char name="agrave" width="500" llx="25" lly="-14" urx="488" ury="713"/>
+ <char name="ampersand" width="833" llx="62" lly="-16" urx="787" ury="691"/>
+ <char name="aring" width="500" llx="25" lly="-14" urx="488" ury="740"/>
+ <char name="asciicircum" width="581" llx="73" lly="311" urx="509" ury="676"/>
+ <char name="asciitilde" width="520" llx="29" lly="173" urx="491" ury="333"/>
+ <char name="asterisk" width="500" llx="56" lly="255" urx="447" ury="691"/>
+ <char name="at" width="930" llx="108" lly="-19" urx="822" ury="691"/>
+ <char name="atilde" width="500" llx="25" lly="-14" urx="488" ury="674"/>
+ <char name="b" width="556" llx="17" lly="-14" urx="521" ury="676"/>
+ <char name="backslash" width="278" llx="-25" lly="-19" urx="303" ury="691"/>
+ <char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/>
+ <char name="braceleft" width="394" llx="22" lly="-175" urx="340" ury="698"/>
+ <char name="braceright" width="394" llx="54" lly="-175" urx="372" ury="698"/>
+ <char name="bracketleft" width="333" llx="67" lly="-149" urx="301" ury="678"/>
+ <char name="bracketright" width="333" llx="32" lly="-149" urx="266" ury="678"/>
+ <char name="breve" width="333" llx="15" lly="528" urx="318" ury="691"/>
+ <char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/>
+ <char name="bullet" width="350" llx="35" lly="198" urx="315" ury="478"/>
+ <char name="c" width="444" llx="25" lly="-14" urx="430" ury="473"/>
+ <char name="caron" width="333" llx="-2" lly="528" urx="335" ury="704"/>
+ <char name="ccedilla" width="444" llx="25" lly="-218" urx="430" ury="473"/>
+ <char name="cedilla" width="333" llx="68" lly="-218" urx="294" ury="0"/>
+ <char name="cent" width="500" llx="53" lly="-140" urx="458" ury="588"/>
+ <char name="circumflex" width="333" llx="-2" lly="528" urx="335" ury="704"/>
+ <char name="colon" width="333" llx="82" lly="-13" urx="251" ury="472"/>
+ <char name="comma" width="250" llx="39" lly="-180" urx="223" ury="155"/>
+ <char name="copyright" width="747" llx="26" lly="-19" urx="721" ury="691"/>
+ <char name="currency" width="500" llx="-26" lly="61" urx="526" ury="613"/>
+ <char name="d" width="556" llx="25" lly="-14" urx="534" ury="676"/>
+ <char name="dagger" width="500" llx="47" lly="-134" urx="453" ury="691"/>
+ <char name="daggerdbl" width="500" llx="45" lly="-132" urx="456" ury="691"/>
+ <char name="degree" width="400" llx="57" lly="402" urx="343" ury="688"/>
+ <char name="dieresis" width="333" llx="-2" lly="537" urx="335" ury="667"/>
+ <char name="divide" width="570" llx="33" lly="-31" urx="537" ury="537"/>
+ <char name="dollar" width="500" llx="29" lly="-99" urx="472" ury="750"/>
+ <char name="dotaccent" width="333" llx="103" lly="536" urx="258" ury="691"/>
+ <char name="dotlessi" width="278" llx="16" lly="0" urx="255" ury="461"/>
+ <char name="e" width="444" llx="25" lly="-14" urx="426" ury="473"/>
+ <char name="eacute" width="444" llx="25" lly="-14" urx="426" ury="713"/>
+ <char name="ecircumflex" width="444" llx="25" lly="-14" urx="426" ury="704"/>
+ <char name="edieresis" width="444" llx="25" lly="-14" urx="426" ury="667"/>
+ <char name="egrave" width="444" llx="25" lly="-14" urx="426" ury="713"/>
+ <char name="eight" width="500" llx="28" lly="-13" urx="472" ury="688"/>
+ <char name="ellipsis" width="1000" llx="82" lly="-13" urx="917" ury="156"/>
+ <char name="emdash" width="1000" llx="0" lly="181" urx="1000" ury="271"/>
+ <char name="endash" width="500" llx="0" lly="181" urx="500" ury="271"/>
+ <char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/>
+ <char name="eth" width="500" llx="25" lly="-14" urx="476" ury="691"/>
+ <char name="exclam" width="333" llx="81" lly="-13" urx="251" ury="691"/>
+ <char name="exclamdown" width="333" llx="82" lly="-203" urx="252" ury="501"/>
+ <char name="f" width="333" llx="14" lly="0" urx="389" ury="691"/>
+ <char name="fi" width="556" llx="14" lly="0" urx="536" ury="691"/>
+ <char name="five" width="500" llx="22" lly="-8" urx="470" ury="676"/>
+ <char name="fl" width="556" llx="14" lly="0" urx="536" ury="691"/>
+ <char name="florin" width="500" llx="0" lly="-155" urx="498" ury="706"/>
+ <char name="four" width="500" llx="19" lly="0" urx="475" ury="688"/>
+ <char name="fraction" width="167" llx="-168" lly="-12" urx="329" ury="688"/>
+ <char name="g" width="500" llx="28" lly="-206" urx="483" ury="473"/>
+ <char name="germandbls" width="556" llx="19" lly="-12" urx="517" ury="691"/>
+ <char name="grave" width="333" llx="8" lly="528" urx="246" ury="713"/>
+ <char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/>
+ <char name="guillemotleft" width="500" llx="23" lly="36" urx="473" ury="415"/>
+ <char name="guillemotright" width="500" llx="27" lly="36" urx="477" ury="415"/>
+ <char name="guilsinglleft" width="333" llx="51" lly="36" urx="305" ury="415"/>
+ <char name="guilsinglright" width="333" llx="28" lly="36" urx="282" ury="415"/>
+ <char name="h" width="556" llx="16" lly="0" urx="534" ury="676"/>
+ <char name="hungarumlaut" width="333" llx="-13" lly="528" urx="425" ury="713"/>
+ <char name="hyphen" width="333" llx="44" lly="171" urx="287" ury="287"/>
+ <char name="i" width="278" llx="16" lly="0" urx="255" ury="691"/>
+ <char name="iacute" width="278" llx="16" lly="0" urx="289" ury="713"/>
+ <char name="icircumflex" width="278" llx="-37" lly="0" urx="300" ury="704"/>
+ <char name="idieresis" width="278" llx="-37" lly="0" urx="300" ury="667"/>
+ <char name="igrave" width="278" llx="-27" lly="0" urx="255" ury="713"/>
+ <char name="j" width="333" llx="-57" lly="-203" urx="263" ury="691"/>
+ <char name="k" width="556" llx="22" lly="0" urx="543" ury="676"/>
+ <char name="l" width="278" llx="16" lly="0" urx="255" ury="676"/>
+ <char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/>
+ <char name="logicalnot" width="570" llx="33" lly="108" urx="537" ury="399"/>
+ <char name="lslash" width="278" llx="-22" lly="0" urx="303" ury="676"/>
+ <char name="m" width="833" llx="16" lly="0" urx="814" ury="473"/>
+ <char name="macron" width="333" llx="1" lly="565" urx="331" ury="637"/>
+ <char name="minus" width="324" llx="33" lly="209" urx="537" ury="297"/>
+ <char name="mu" width="556" llx="33" lly="-206" urx="536" ury="461"/>
+ <char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/>
+ <char name="n" width="556" llx="21" lly="0" urx="539" ury="473"/>
+ <char name="nine" width="500" llx="26" lly="-13" urx="473" ury="688"/>
+ <char name="ntilde" width="556" llx="21" lly="0" urx="539" ury="674"/>
+ <char name="numbersign" width="500" llx="4" lly="0" urx="496" ury="700"/>
+ <char name="o" width="500" llx="25" lly="-14" urx="476" ury="473"/>
+ <char name="oacute" width="500" llx="25" lly="-14" urx="476" ury="713"/>
+ <char name="ocircumflex" width="500" llx="25" lly="-14" urx="476" ury="704"/>
+ <char name="odieresis" width="500" llx="25" lly="-14" urx="476" ury="667"/>
+ <char name="oe" width="722" llx="22" lly="-14" urx="696" ury="473"/>
+ <char name="ogonek" width="333" llx="90" lly="-193" urx="319" ury="24"/>
+ <char name="ograve" width="500" llx="25" lly="-14" urx="476" ury="713"/>
+ <char name="one" width="500" llx="65" lly="0" urx="442" ury="688"/>
+ <char name="onehalf" width="750" llx="-7" lly="-12" urx="775" ury="688"/>
+ <char name="onequarter" width="750" llx="28" lly="-12" urx="743" ury="688"/>
+ <char name="onesuperior" width="300" llx="28" lly="275" urx="273" ury="688"/>
+ <char name="ordfeminine" width="300" llx="-1" lly="397" urx="301" ury="688"/>
+ <char name="ordmasculine" width="330" llx="18" lly="397" urx="312" ury="688"/>
+ <char name="oslash" width="500" llx="25" lly="-92" urx="476" ury="549"/>
+ <char name="otilde" width="500" llx="25" lly="-14" urx="476" ury="674"/>
+ <char name="p" width="556" llx="19" lly="-205" urx="524" ury="473"/>
+ <char name="paragraph" width="540" llx="0" lly="-186" urx="519" ury="676"/>
+ <char name="parenleft" width="333" llx="46" lly="-168" urx="306" ury="694"/>
+ <char name="parenright" width="333" llx="27" lly="-168" urx="287" ury="694"/>
+ <char name="percent" width="1000" llx="124" lly="-14" urx="877" ury="692"/>
+ <char name="period" width="250" llx="41" lly="-13" urx="210" ury="156"/>
+ <char name="periodcentered" width="250" llx="41" lly="248" urx="210" ury="417"/>
+ <char name="perthousand" width="1000" llx="7" lly="-29" urx="995" ury="706"/>
+ <char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/>
+ <char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/>
+ <char name="q" width="556" llx="34" lly="-205" urx="536" ury="473"/>
+ <char name="question" width="500" llx="57" lly="-13" urx="445" ury="689"/>
+ <char name="questiondown" width="500" llx="55" lly="-201" urx="443" ury="501"/>
+ <char name="quotedbl" width="555" llx="83" lly="404" urx="472" ury="691"/>
+ <char name="quotedblbase" width="500" llx="14" lly="-180" urx="468" ury="155"/>
+ <char name="quotedblleft" width="500" llx="32" lly="356" urx="486" ury="691"/>
+ <char name="quotedblright" width="500" llx="14" lly="356" urx="468" ury="691"/>
+ <char name="quoteleft" width="333" llx="70" lly="356" urx="254" ury="691"/>
+ <char name="quoteright" width="333" llx="79" lly="356" urx="263" ury="691"/>
+ <char name="quotesinglbase" width="333" llx="79" lly="-180" urx="263" ury="155"/>
+ <char name="quotesingle" width="278" llx="75" lly="404" urx="204" ury="691"/>
+ <char name="r" width="444" llx="29" lly="0" urx="434" ury="473"/>
+ <char name="registered" width="747" llx="26" lly="-19" urx="721" ury="691"/>
+ <char name="ring" width="333" llx="60" lly="527" urx="273" ury="740"/>
+ <char name="s" width="389" llx="25" lly="-14" urx="361" ury="473"/>
+ <char name="scaron" width="389" llx="25" lly="-14" urx="363" ury="704"/>
+ <char name="section" width="500" llx="57" lly="-132" urx="443" ury="691"/>
+ <char name="semicolon" width="333" llx="82" lly="-180" urx="266" ury="472"/>
+ <char name="seven" width="500" llx="17" lly="0" urx="477" ury="676"/>
+ <char name="six" width="500" llx="28" lly="-13" urx="475" ury="688"/>
+ <char name="slash" width="278" llx="-24" lly="-19" urx="302" ury="691"/>
+ <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="250"/>
- <char name="sterling" width="500"/>
- <char name="t" width="333"/>
- <char name="thorn" width="556"/>
- <char name="three" width="500"/>
- <char name="threequarters" width="750"/>
- <char name="threesuperior" width="300"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="500"/>
- <char name="twosuperior" width="300"/>
- <char name="u" width="556"/>
- <char name="uacute" width="556"/>
- <char name="ucircumflex" width="556"/>
- <char name="udieresis" width="556"/>
- <char name="ugrave" width="556"/>
- <char name="underscore" width="500"/>
- <char name="v" width="500"/>
- <char name="w" width="722"/>
- <char name="x" width="500"/>
- <char name="y" width="500"/>
- <char name="yacute" width="500"/>
- <char name="ydieresis" width="500"/>
- <char name="yen" width="500"/>
- <char name="z" width="444"/>
- <char name="zcaron" width="444"/>
- <char name="zero" width="500"/>
- </widths>
+ <char name="sterling" width="500" llx="21" lly="-14" urx="477" ury="684"/>
+ <char name="t" width="333" llx="20" lly="-12" urx="332" ury="630"/>
+ <char name="thorn" width="556" llx="19" lly="-205" urx="524" ury="676"/>
+ <char name="three" width="500" llx="16" lly="-14" urx="468" ury="688"/>
+ <char name="threequarters" width="750" llx="23" lly="-12" urx="733" ury="688"/>
+ <char name="threesuperior" width="300" llx="3" lly="268" urx="297" ury="688"/>
+ <char name="tilde" width="333" llx="-16" lly="547" urx="349" ury="674"/>
+ <char name="trademark" width="1000" llx="24" lly="271" urx="977" ury="676"/>
+ <char name="two" width="500" llx="17" lly="0" urx="478" ury="688"/>
+ <char name="twosuperior" width="300" llx="0" lly="275" urx="300" ury="688"/>
+ <char name="u" width="556" llx="16" lly="-14" urx="537" ury="461"/>
+ <char name="uacute" width="556" llx="16" lly="-14" urx="537" ury="713"/>
+ <char name="ucircumflex" width="556" llx="16" lly="-14" urx="537" ury="704"/>
+ <char name="udieresis" width="556" llx="16" lly="-14" urx="537" ury="667"/>
+ <char name="ugrave" width="556" llx="16" lly="-14" urx="537" ury="713"/>
+ <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
+ <char name="v" width="500" llx="21" lly="-14" urx="485" ury="461"/>
+ <char name="w" width="722" llx="23" lly="-14" urx="707" ury="461"/>
+ <char name="x" width="500" llx="12" lly="0" urx="484" ury="461"/>
+ <char name="y" width="500" llx="16" lly="-205" urx="480" ury="461"/>
+ <char name="yacute" width="500" llx="16" lly="-205" urx="480" ury="713"/>
+ <char name="ydieresis" width="500" llx="16" lly="-205" urx="480" ury="667"/>
+ <char name="yen" width="500" llx="-64" lly="0" urx="547" ury="676"/>
+ <char name="z" width="444" llx="21" lly="0" urx="420" ury="461"/>
+ <char name="zcaron" width="444" llx="21" lly="0" urx="420" ury="704"/>
+ <char name="zero" width="500" llx="24" lly="-13" urx="476" ury="688"/>
+ </char-metrics>
<kerning kpx1="79">
<pair kern="-40" kpx2="65"/>
<pair kern="-50" kpx2="87"/>
diff --git a/src/codegen/fonts/TimesBoldItalic.xml b/src/codegen/fonts/TimesBoldItalic.xml
index d1b70872a..ec67369f2 100644
--- a/src/codegen/fonts/TimesBoldItalic.xml
+++ b/src/codegen/fonts/TimesBoldItalic.xml
@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesBoldItalic</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>669</cap-height>
<x-height>462</x-height>
<ascender>699</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="667"/>
- <char name="AE" width="944"/>
- <char name="Aacute" width="667"/>
- <char name="Acircumflex" width="667"/>
- <char name="Adieresis" width="667"/>
- <char name="Agrave" width="667"/>
- <char name="Aring" width="667"/>
- <char name="Atilde" width="667"/>
- <char name="B" width="667"/>
- <char name="C" width="667"/>
- <char name="Ccedilla" width="667"/>
- <char name="D" width="722"/>
- <char name="E" width="667"/>
- <char name="Eacute" width="667"/>
- <char name="Ecircumflex" width="667"/>
- <char name="Edieresis" width="667"/>
- <char name="Egrave" width="667"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="500"/>
- <char name="F" width="667"/>
- <char name="G" width="722"/>
- <char name="H" width="778"/>
- <char name="I" width="389"/>
- <char name="Iacute" width="389"/>
- <char name="Icircumflex" width="389"/>
- <char name="Idieresis" width="389"/>
- <char name="Igrave" width="389"/>
- <char name="J" width="500"/>
- <char name="K" width="667"/>
- <char name="L" width="611"/>
- <char name="Lslash" width="611"/>
- <char name="M" width="889"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="722"/>
- <char name="OE" width="944"/>
- <char name="Oacute" width="722"/>
- <char name="Ocircumflex" width="722"/>
- <char name="Odieresis" width="722"/>
- <char name="Ograve" width="722"/>
- <char name="Oslash" width="722"/>
- <char name="Otilde" width="722"/>
- <char name="P" width="611"/>
- <char name="Q" width="722"/>
- <char name="R" width="667"/>
- <char name="S" width="556"/>
- <char name="Scaron" width="556"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="611"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="667"/>
- <char name="W" width="889"/>
- <char name="X" width="667"/>
- <char name="Y" width="611"/>
- <char name="Yacute" width="611"/>
- <char name="Ydieresis" width="611"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="500"/>
- <char name="aacute" width="500"/>
- <char name="acircumflex" width="500"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="500"/>
- <char name="ae" width="722"/>
- <char name="agrave" width="500"/>
- <char name="ampersand" width="778"/>
- <char name="aring" width="500"/>
- <char name="asciicircum" width="570"/>
- <char name="asciitilde" width="570"/>
- <char name="asterisk" width="500"/>
- <char name="at" width="832"/>
- <char name="atilde" width="500"/>
- <char name="b" width="500"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="220"/>
- <char name="braceleft" width="348"/>
- <char name="braceright" width="348"/>
- <char name="bracketleft" width="333"/>
- <char name="bracketright" width="333"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="220"/>
- <char name="bullet" width="350"/>
- <char name="c" width="444"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="444"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="500"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="333"/>
- <char name="comma" width="250"/>
- <char name="copyright" width="747"/>
- <char name="currency" width="500"/>
- <char name="d" width="500"/>
- <char name="dagger" width="500"/>
- <char name="daggerdbl" width="500"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="570"/>
- <char name="dollar" width="500"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="444"/>
- <char name="eacute" width="444"/>
- <char name="ecircumflex" width="444"/>
- <char name="edieresis" width="444"/>
- <char name="egrave" width="444"/>
- <char name="eight" width="500"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="500"/>
- <char name="equal" width="570"/>
- <char name="eth" width="500"/>
- <char name="exclam" width="389"/>
- <char name="exclamdown" width="389"/>
- <char name="f" width="333"/>
- <char name="fi" width="556"/>
- <char name="five" width="500"/>
- <char name="fl" width="556"/>
- <char name="florin" width="500"/>
- <char name="four" width="500"/>
- <char name="fraction" width="167"/>
- <char name="g" width="500"/>
- <char name="germandbls" width="500"/>
- <char name="grave" width="333"/>
- <char name="greater" width="570"/>
- <char name="guillemotleft" width="500"/>
- <char name="guillemotright" width="500"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="556"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="278"/>
- <char name="k" width="500"/>
- <char name="l" width="278"/>
- <char name="less" width="570"/>
- <char name="logicalnot" width="606"/>
- <char name="lslash" width="278"/>
- <char name="m" width="778"/>
- <char name="macron" width="333"/>
- <char name="minus" width="330"/>
- <char name="mu" width="576"/>
- <char name="multiply" width="570"/>
- <char name="n" width="556"/>
- <char name="nine" width="500"/>
- <char name="ntilde" width="556"/>
- <char name="numbersign" width="500"/>
- <char name="o" width="500"/>
- <char name="oacute" width="500"/>
- <char name="ocircumflex" width="500"/>
- <char name="odieresis" width="500"/>
- <char name="oe" width="722"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="500"/>
- <char name="one" width="500"/>
- <char name="onehalf" width="750"/>
- <char name="onequarter" width="750"/>
- <char name="onesuperior" width="300"/>
- <char name="ordfeminine" width="266"/>
- <char name="ordmasculine" width="300"/>
- <char name="oslash" width="500"/>
- <char name="otilde" width="500"/>
- <char name="p" width="500"/>
- <char name="paragraph" width="500"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="833"/>
- <char name="period" width="250"/>
- <char name="periodcentered" width="250"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="570"/>
- <char name="plusminus" width="570"/>
- <char name="q" width="500"/>
- <char name="question" width="500"/>
- <char name="questiondown" width="500"/>
- <char name="quotedbl" width="555"/>
- <char name="quotedblbase" width="500"/>
- <char name="quotedblleft" width="500"/>
- <char name="quotedblright" width="500"/>
- <char name="quoteleft" width="333"/>
- <char name="quoteright" width="333"/>
- <char name="quotesinglbase" width="333"/>
- <char name="quotesingle" width="278"/>
- <char name="r" width="389"/>
- <char name="registered" width="747"/>
- <char name="ring" width="333"/>
- <char name="s" width="389"/>
- <char name="scaron" width="389"/>
- <char name="section" width="500"/>
- <char name="semicolon" width="333"/>
- <char name="seven" width="500"/>
- <char name="six" width="500"/>
- <char name="slash" width="278"/>
- <char name="space" width="250"/>
+ <char-metrics>
+ <char name="A" width="667" llx="-67" lly="0" urx="593" ury="683"/>
+ <char name="AE" width="944" llx="-64" lly="0" urx="918" ury="669"/>
+ <char name="Aacute" width="667" llx="-67" lly="0" urx="593" ury="904"/>
+ <char name="Acircumflex" width="667" llx="-67" lly="0" urx="593" ury="897"/>
+ <char name="Adieresis" width="667" llx="-67" lly="0" urx="593" ury="862"/>
+ <char name="Agrave" width="667" llx="-67" lly="0" urx="593" ury="904"/>
+ <char name="Aring" width="667" llx="-67" lly="0" urx="593" ury="921"/>
+ <char name="Atilde" width="667" llx="-67" lly="0" urx="593" ury="862"/>
+ <char name="B" width="667" llx="-24" lly="0" urx="624" ury="669"/>
+ <char name="C" width="667" llx="32" lly="-18" urx="677" ury="685"/>
+ <char name="Ccedilla" width="667" llx="32" lly="-218" urx="677" ury="685"/>
+ <char name="D" width="722" llx="-46" lly="0" urx="685" ury="669"/>
+ <char name="E" width="667" llx="-27" lly="0" urx="653" ury="669"/>
+ <char name="Eacute" width="667" llx="-27" lly="0" urx="653" ury="904"/>
+ <char name="Ecircumflex" width="667" llx="-27" lly="0" urx="653" ury="897"/>
+ <char name="Edieresis" width="667" llx="-27" lly="0" urx="653" ury="862"/>
+ <char name="Egrave" width="667" llx="-27" lly="0" urx="653" ury="904"/>
+ <char name="Eth" width="722" llx="-31" lly="0" urx="700" ury="669"/>
+ <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="667" llx="-13" lly="0" urx="660" ury="669"/>
+ <char name="G" width="722" llx="21" lly="-18" urx="706" ury="685"/>
+ <char name="H" width="778" llx="-24" lly="0" urx="799" ury="669"/>
+ <char name="I" width="389" llx="-32" lly="0" urx="406" ury="669"/>
+ <char name="Iacute" width="389" llx="-32" lly="0" urx="432" ury="904"/>
+ <char name="Icircumflex" width="389" llx="-32" lly="0" urx="450" ury="897"/>
+ <char name="Idieresis" width="389" llx="-32" lly="0" urx="450" ury="862"/>
+ <char name="Igrave" width="389" llx="-32" lly="0" urx="406" ury="904"/>
+ <char name="J" width="500" llx="-46" lly="-99" urx="524" ury="669"/>
+ <char name="K" width="667" llx="-21" lly="0" urx="702" ury="669"/>
+ <char name="L" width="611" llx="-22" lly="0" urx="590" ury="669"/>
+ <char name="Lslash" width="611" llx="-22" lly="0" urx="590" ury="669"/>
+ <char name="M" width="889" llx="-29" lly="-12" urx="917" ury="669"/>
+ <char name="N" width="722" llx="-27" lly="-15" urx="748" ury="669"/>
+ <char name="Ntilde" width="722" llx="-27" lly="-15" urx="748" ury="862"/>
+ <char name="O" width="722" llx="27" lly="-18" urx="691" ury="685"/>
+ <char name="OE" width="944" llx="23" lly="-8" urx="946" ury="677"/>
+ <char name="Oacute" width="722" llx="27" lly="-18" urx="691" ury="904"/>
+ <char name="Ocircumflex" width="722" llx="27" lly="-18" urx="691" ury="897"/>
+ <char name="Odieresis" width="722" llx="27" lly="-18" urx="691" ury="862"/>
+ <char name="Ograve" width="722" llx="27" lly="-18" urx="691" ury="904"/>
+ <char name="Oslash" width="722" llx="27" lly="-125" urx="691" ury="764"/>
+ <char name="Otilde" width="722" llx="27" lly="-18" urx="691" ury="862"/>
+ <char name="P" width="611" llx="-27" lly="0" urx="613" ury="669"/>
+ <char name="Q" width="722" llx="27" lly="-208" urx="691" ury="685"/>
+ <char name="R" width="667" llx="-29" lly="0" urx="623" ury="669"/>
+ <char name="S" width="556" llx="2" lly="-18" urx="526" ury="685"/>
+ <char name="Scaron" width="556" llx="2" lly="-18" urx="553" ury="897"/>
+ <char name="T" width="611" llx="50" lly="0" urx="650" ury="669"/>
+ <char name="Thorn" width="611" llx="-27" lly="0" urx="573" ury="669"/>
+ <char name="U" width="722" llx="67" lly="-18" urx="744" ury="669"/>
+ <char name="Uacute" width="722" llx="67" lly="-18" urx="744" ury="904"/>
+ <char name="Ucircumflex" width="722" llx="67" lly="-18" urx="744" ury="897"/>
+ <char name="Udieresis" width="722" llx="67" lly="-18" urx="744" ury="862"/>
+ <char name="Ugrave" width="722" llx="67" lly="-18" urx="744" ury="904"/>
+ <char name="V" width="667" llx="65" lly="-18" urx="715" ury="669"/>
+ <char name="W" width="889" llx="65" lly="-18" urx="940" ury="669"/>
+ <char name="X" width="667" llx="-24" lly="0" urx="694" ury="669"/>
+ <char name="Y" width="611" llx="73" lly="0" urx="659" ury="669"/>
+ <char name="Yacute" width="611" llx="73" lly="0" urx="659" ury="904"/>
+ <char name="Ydieresis" width="611" llx="73" lly="0" urx="659" ury="862"/>
+ <char name="Z" width="611" llx="-11" lly="0" urx="590" ury="669"/>
+ <char name="Zcaron" width="611" llx="-11" lly="0" urx="590" ury="897"/>
+ <char name="a" width="500" llx="-21" lly="-14" urx="455" ury="462"/>
+ <char name="aacute" width="500" llx="-21" lly="-14" urx="463" ury="697"/>
+ <char name="acircumflex" width="500" llx="-21" lly="-14" urx="455" ury="690"/>
+ <char name="acute" width="333" llx="139" lly="516" urx="379" ury="697"/>
+ <char name="adieresis" width="500" llx="-21" lly="-14" urx="476" ury="655"/>
+ <char name="ae" width="722" llx="-5" lly="-13" urx="673" ury="462"/>
+ <char name="agrave" width="500" llx="-21" lly="-14" urx="455" ury="697"/>
+ <char name="ampersand" width="778" llx="5" lly="-19" urx="699" ury="682"/>
+ <char name="aring" width="500" llx="-21" lly="-14" urx="455" ury="729"/>
+ <char name="asciicircum" width="570" llx="67" lly="304" urx="503" ury="669"/>
+ <char name="asciitilde" width="570" llx="54" lly="173" urx="516" ury="333"/>
+ <char name="asterisk" width="500" llx="65" lly="249" urx="456" ury="685"/>
+ <char name="at" width="832" llx="63" lly="-18" urx="770" ury="685"/>
+ <char name="atilde" width="500" llx="-21" lly="-14" urx="491" ury="655"/>
+ <char name="b" width="500" llx="-14" lly="-13" urx="444" ury="699"/>
+ <char name="backslash" width="278" llx="-1" lly="-18" urx="279" ury="685"/>
+ <char name="bar" width="220" llx="66" lly="-218" urx="154" ury="782"/>
+ <char name="braceleft" width="348" llx="5" lly="-187" urx="436" ury="686"/>
+ <char name="braceright" width="348" llx="-129" lly="-187" urx="302" ury="686"/>
+ <char name="bracketleft" width="333" llx="-37" lly="-159" urx="362" ury="674"/>
+ <char name="bracketright" width="333" llx="-56" lly="-157" urx="343" ury="674"/>
+ <char name="breve" width="333" llx="71" lly="516" urx="387" ury="678"/>
+ <char name="brokenbar" width="220" llx="66" lly="-143" urx="154" ury="707"/>
+ <char name="bullet" width="350" llx="0" lly="175" urx="350" ury="525"/>
+ <char name="c" width="444" llx="-5" lly="-13" urx="392" ury="462"/>
+ <char name="caron" width="333" llx="79" lly="516" urx="411" ury="690"/>
+ <char name="ccedilla" width="444" llx="-5" lly="-218" urx="392" ury="462"/>
+ <char name="cedilla" width="333" llx="-80" lly="-218" urx="156" ury="5"/>
+ <char name="cent" width="500" llx="42" lly="-143" urx="439" ury="576"/>
+ <char name="circumflex" width="333" llx="40" lly="516" urx="367" ury="690"/>
+ <char name="colon" width="333" llx="23" lly="-13" urx="264" ury="459"/>
+ <char name="comma" width="250" llx="-60" lly="-182" urx="144" ury="134"/>
+ <char name="copyright" width="747" llx="30" lly="-18" urx="718" ury="685"/>
+ <char name="currency" width="500" llx="-26" lly="34" urx="526" ury="586"/>
+ <char name="d" width="500" llx="-21" lly="-13" urx="517" ury="699"/>
+ <char name="dagger" width="500" llx="91" lly="-145" urx="494" ury="685"/>
+ <char name="daggerdbl" width="500" llx="10" lly="-139" urx="493" ury="685"/>
+ <char name="degree" width="400" llx="83" lly="397" urx="369" ury="683"/>
+ <char name="dieresis" width="333" llx="55" lly="550" urx="402" ury="684"/>
+ <char name="divide" width="570" llx="33" lly="-29" urx="537" ury="535"/>
+ <char name="dollar" width="500" llx="-20" lly="-100" urx="497" ury="733"/>
+ <char name="dotaccent" width="333" llx="163" lly="550" urx="298" ury="684"/>
+ <char name="dotlessi" width="278" llx="2" lly="-9" urx="238" ury="462"/>
+ <char name="e" width="444" llx="5" lly="-13" urx="398" ury="462"/>
+ <char name="eacute" width="444" llx="5" lly="-13" urx="435" ury="697"/>
+ <char name="ecircumflex" width="444" llx="5" lly="-13" urx="423" ury="690"/>
+ <char name="edieresis" width="444" llx="5" lly="-13" urx="448" ury="655"/>
+ <char name="egrave" width="444" llx="5" lly="-13" urx="398" ury="697"/>
+ <char name="eight" width="500" llx="3" lly="-13" urx="476" ury="683"/>
+ <char name="ellipsis" width="1000" llx="40" lly="-13" urx="852" ury="135"/>
+ <char name="emdash" width="1000" llx="-40" lly="178" urx="977" ury="269"/>
+ <char name="endash" width="500" llx="-40" lly="178" urx="477" ury="269"/>
+ <char name="equal" width="570" llx="33" lly="107" urx="537" ury="399"/>
+ <char name="eth" width="500" llx="-3" lly="-13" urx="454" ury="699"/>
+ <char name="exclam" width="389" llx="67" lly="-13" urx="370" ury="684"/>
+ <char name="exclamdown" width="389" llx="19" lly="-205" urx="322" ury="492"/>
+ <char name="f" width="333" llx="-169" lly="-205" urx="446" ury="698"/>
+ <char name="fi" width="556" llx="-188" lly="-205" urx="514" ury="703"/>
+ <char name="five" width="500" llx="-11" lly="-13" urx="487" ury="669"/>
+ <char name="fl" width="556" llx="-186" lly="-205" urx="553" ury="704"/>
+ <char name="florin" width="500" llx="-87" lly="-156" urx="537" ury="707"/>
+ <char name="four" width="500" llx="-15" lly="0" urx="503" ury="683"/>
+ <char name="fraction" width="167" llx="-169" lly="-14" urx="324" ury="683"/>
+ <char name="g" width="500" llx="-52" lly="-203" urx="478" ury="462"/>
+ <char name="germandbls" width="500" llx="-200" lly="-200" urx="473" ury="705"/>
+ <char name="grave" width="333" llx="85" lly="516" urx="297" ury="697"/>
+ <char name="greater" width="570" llx="31" lly="-8" urx="539" ury="514"/>
+ <char name="guillemotleft" width="500" llx="12" lly="32" urx="468" ury="415"/>
+ <char name="guillemotright" width="500" llx="12" lly="32" urx="468" ury="415"/>
+ <char name="guilsinglleft" width="333" llx="32" lly="32" urx="303" ury="415"/>
+ <char name="guilsinglright" width="333" llx="10" lly="32" urx="281" ury="415"/>
+ <char name="h" width="556" llx="-13" lly="-9" urx="498" ury="699"/>
+ <char name="hungarumlaut" width="333" llx="69" lly="516" urx="498" ury="697"/>
+ <char name="hyphen" width="333" llx="2" lly="166" urx="271" ury="282"/>
+ <char name="i" width="278" llx="2" lly="-9" urx="263" ury="684"/>
+ <char name="iacute" width="278" llx="2" lly="-9" urx="352" ury="697"/>
+ <char name="icircumflex" width="278" llx="-3" lly="-9" urx="324" ury="690"/>
+ <char name="idieresis" width="278" llx="2" lly="-9" urx="364" ury="655"/>
+ <char name="igrave" width="278" llx="2" lly="-9" urx="259" ury="697"/>
+ <char name="j" width="278" llx="-189" lly="-207" urx="279" ury="684"/>
+ <char name="k" width="500" llx="-23" lly="-8" urx="483" ury="699"/>
+ <char name="l" width="278" llx="2" lly="-9" urx="290" ury="699"/>
+ <char name="less" width="570" llx="31" lly="-8" urx="539" ury="514"/>
+ <char name="logicalnot" width="606" llx="51" lly="108" urx="555" ury="399"/>
+ <char name="lslash" width="278" llx="-7" lly="-9" urx="307" ury="699"/>
+ <char name="m" width="778" llx="-14" lly="-9" urx="722" ury="462"/>
+ <char name="macron" width="333" llx="51" lly="553" urx="393" ury="623"/>
+ <char name="minus" width="330" llx="51" lly="209" urx="555" ury="297"/>
+ <char name="mu" width="576" llx="-60" lly="-207" urx="516" ury="449"/>
+ <char name="multiply" width="570" llx="48" lly="16" urx="522" ury="490"/>
+ <char name="n" width="556" llx="-6" lly="-9" urx="493" ury="462"/>
+ <char name="nine" width="500" llx="-12" lly="-10" urx="475" ury="683"/>
+ <char name="ntilde" width="556" llx="-6" lly="-9" urx="504" ury="655"/>
+ <char name="numbersign" width="500" llx="-33" lly="0" urx="533" ury="700"/>
+ <char name="o" width="500" llx="-3" lly="-13" urx="441" ury="462"/>
+ <char name="oacute" width="500" llx="-3" lly="-13" urx="463" ury="697"/>
+ <char name="ocircumflex" width="500" llx="-3" lly="-13" urx="451" ury="690"/>
+ <char name="odieresis" width="500" llx="-3" lly="-13" urx="471" ury="655"/>
+ <char name="oe" width="722" llx="6" lly="-13" urx="674" ury="462"/>
+ <char name="ogonek" width="333" llx="15" lly="-183" urx="244" ury="34"/>
+ <char name="ograve" width="500" llx="-3" lly="-13" urx="441" ury="697"/>
+ <char name="one" width="500" llx="5" lly="0" urx="419" ury="683"/>
+ <char name="onehalf" width="750" llx="-9" lly="-14" urx="723" ury="683"/>
+ <char name="onequarter" width="750" llx="7" lly="-14" urx="721" ury="683"/>
+ <char name="onesuperior" width="300" llx="30" lly="274" urx="301" ury="683"/>
+ <char name="ordfeminine" width="266" llx="16" lly="399" urx="330" ury="685"/>
+ <char name="ordmasculine" width="300" llx="56" lly="400" urx="347" ury="685"/>
+ <char name="oslash" width="500" llx="-3" lly="-119" urx="441" ury="560"/>
+ <char name="otilde" width="500" llx="-3" lly="-13" urx="491" ury="655"/>
+ <char name="p" width="500" llx="-120" lly="-205" urx="446" ury="462"/>
+ <char name="paragraph" width="500" llx="-57" lly="-193" urx="562" ury="669"/>
+ <char name="parenleft" width="333" llx="28" lly="-179" urx="344" ury="685"/>
+ <char name="parenright" width="333" llx="-44" lly="-179" urx="271" ury="685"/>
+ <char name="percent" width="833" llx="39" lly="-10" urx="793" ury="692"/>
+ <char name="period" width="250" llx="-9" lly="-13" urx="139" ury="135"/>
+ <char name="periodcentered" width="250" llx="51" lly="257" urx="199" ury="405"/>
+ <char name="perthousand" width="1000" llx="7" lly="-29" urx="996" ury="706"/>
+ <char name="plus" width="570" llx="33" lly="0" urx="537" ury="506"/>
+ <char name="plusminus" width="570" llx="33" lly="0" urx="537" ury="506"/>
+ <char name="q" width="500" llx="1" lly="-205" urx="471" ury="462"/>
+ <char name="question" width="500" llx="79" lly="-13" urx="470" ury="684"/>
+ <char name="questiondown" width="500" llx="30" lly="-205" urx="421" ury="492"/>
+ <char name="quotedbl" width="555" llx="136" lly="398" urx="536" ury="685"/>
+ <char name="quotedblbase" width="500" llx="-57" lly="-182" urx="403" ury="134"/>
+ <char name="quotedblleft" width="500" llx="53" lly="369" urx="513" ury="685"/>
+ <char name="quotedblright" width="500" llx="53" lly="369" urx="513" ury="685"/>
+ <char name="quoteleft" width="333" llx="128" lly="369" urx="332" ury="685"/>
+ <char name="quoteright" width="333" llx="98" lly="369" urx="302" ury="685"/>
+ <char name="quotesinglbase" width="333" llx="-5" lly="-182" urx="199" ury="134"/>
+ <char name="quotesingle" width="278" llx="128" lly="398" urx="268" ury="685"/>
+ <char name="r" width="389" llx="-21" lly="0" urx="389" ury="462"/>
+ <char name="registered" width="747" llx="30" lly="-18" urx="718" ury="685"/>
+ <char name="ring" width="333" llx="127" lly="516" urx="340" ury="729"/>
+ <char name="s" width="389" llx="-19" lly="-13" urx="333" ury="462"/>
+ <char name="scaron" width="389" llx="-19" lly="-13" urx="424" ury="690"/>
+ <char name="section" width="500" llx="36" lly="-143" urx="459" ury="685"/>
+ <char name="semicolon" width="333" llx="-25" lly="-183" urx="264" ury="459"/>
+ <char name="seven" width="500" llx="52" lly="0" urx="525" ury="669"/>
+ <char name="six" width="500" llx="23" lly="-15" urx="509" ury="679"/>
+ <char name="slash" width="278" llx="-64" lly="-18" urx="342" ury="685"/>
+ <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="250"/>
- <char name="sterling" width="500"/>
- <char name="t" width="278"/>
- <char name="thorn" width="500"/>
- <char name="three" width="500"/>
- <char name="threequarters" width="750"/>
- <char name="threesuperior" width="300"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="1000"/>
- <char name="two" width="500"/>
- <char name="twosuperior" width="300"/>
- <char name="u" width="556"/>
- <char name="uacute" width="556"/>
- <char name="ucircumflex" width="556"/>
- <char name="udieresis" width="556"/>
- <char name="ugrave" width="556"/>
- <char name="underscore" width="500"/>
- <char name="v" width="444"/>
- <char name="w" width="667"/>
- <char name="x" width="500"/>
- <char name="y" width="444"/>
- <char name="yacute" width="444"/>
- <char name="ydieresis" width="444"/>
- <char name="yen" width="500"/>
- <char name="z" width="389"/>
- <char name="zcaron" width="389"/>
- <char name="zero" width="500"/>
- </widths>
+ <char name="sterling" width="500" llx="-32" lly="-12" urx="510" ury="683"/>
+ <char name="t" width="278" llx="-11" lly="-9" urx="281" ury="594"/>
+ <char name="thorn" width="500" llx="-120" lly="-205" urx="446" ury="699"/>
+ <char name="three" width="500" llx="-15" lly="-13" urx="450" ury="683"/>
+ <char name="threequarters" width="750" llx="7" lly="-14" urx="726" ury="683"/>
+ <char name="threesuperior" width="300" llx="17" lly="265" urx="321" ury="683"/>
+ <char name="tilde" width="333" llx="48" lly="536" urx="407" ury="655"/>
+ <char name="trademark" width="1000" llx="32" lly="263" urx="968" ury="669"/>
+ <char name="two" width="500" llx="-27" lly="0" urx="446" ury="683"/>
+ <char name="twosuperior" width="300" llx="2" lly="274" urx="313" ury="683"/>
+ <char name="u" width="556" llx="15" lly="-9" urx="492" ury="462"/>
+ <char name="uacute" width="556" llx="15" lly="-9" urx="492" ury="697"/>
+ <char name="ucircumflex" width="556" llx="15" lly="-9" urx="492" ury="690"/>
+ <char name="udieresis" width="556" llx="15" lly="-9" urx="499" ury="655"/>
+ <char name="ugrave" width="556" llx="15" lly="-9" urx="492" ury="697"/>
+ <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
+ <char name="v" width="444" llx="16" lly="-13" urx="401" ury="462"/>
+ <char name="w" width="667" llx="16" lly="-13" urx="614" ury="462"/>
+ <char name="x" width="500" llx="-46" lly="-13" urx="469" ury="462"/>
+ <char name="y" width="444" llx="-94" lly="-205" urx="392" ury="462"/>
+ <char name="yacute" width="444" llx="-94" lly="-205" urx="435" ury="697"/>
+ <char name="ydieresis" width="444" llx="-94" lly="-205" urx="443" ury="655"/>
+ <char name="yen" width="500" llx="33" lly="0" urx="628" ury="669"/>
+ <char name="z" width="389" llx="-43" lly="-78" urx="368" ury="449"/>
+ <char name="zcaron" width="389" llx="-43" lly="-78" urx="424" ury="690"/>
+ <char name="zero" width="500" llx="17" lly="-14" urx="477" ury="683"/>
+ </char-metrics>
<kerning kpx1="79">
<pair kern="-40" kpx2="65"/>
<pair kern="-50" kpx2="87"/>
diff --git a/src/codegen/fonts/TimesItalic.xml b/src/codegen/fonts/TimesItalic.xml
index 514aaa6dd..607f4d701 100644
--- a/src/codegen/fonts/TimesItalic.xml
+++ b/src/codegen/fonts/TimesItalic.xml
@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesItalic</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>653</cap-height>
<x-height>441</x-height>
<ascender>683</ascender>
<descender>-205</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="611"/>
- <char name="AE" width="889"/>
- <char name="Aacute" width="611"/>
- <char name="Acircumflex" width="611"/>
- <char name="Adieresis" width="611"/>
- <char name="Agrave" width="611"/>
- <char name="Aring" width="611"/>
- <char name="Atilde" width="611"/>
- <char name="B" width="611"/>
- <char name="C" width="667"/>
- <char name="Ccedilla" width="667"/>
- <char name="D" width="722"/>
- <char name="E" width="611"/>
- <char name="Eacute" width="611"/>
- <char name="Ecircumflex" width="611"/>
- <char name="Edieresis" width="611"/>
- <char name="Egrave" width="611"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="500"/>
- <char name="F" width="611"/>
- <char name="G" width="722"/>
- <char name="H" width="722"/>
- <char name="I" width="333"/>
- <char name="Iacute" width="333"/>
- <char name="Icircumflex" width="333"/>
- <char name="Idieresis" width="333"/>
- <char name="Igrave" width="333"/>
- <char name="J" width="444"/>
- <char name="K" width="667"/>
- <char name="L" width="556"/>
- <char name="Lslash" width="556"/>
- <char name="M" width="833"/>
- <char name="N" width="667"/>
- <char name="Ntilde" width="667"/>
- <char name="O" width="722"/>
- <char name="OE" width="944"/>
- <char name="Oacute" width="722"/>
- <char name="Ocircumflex" width="722"/>
- <char name="Odieresis" width="722"/>
- <char name="Ograve" width="722"/>
- <char name="Oslash" width="722"/>
- <char name="Otilde" width="722"/>
- <char name="P" width="611"/>
- <char name="Q" width="722"/>
- <char name="R" width="611"/>
- <char name="S" width="500"/>
- <char name="Scaron" width="500"/>
- <char name="T" width="556"/>
- <char name="Thorn" width="611"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="611"/>
- <char name="W" width="833"/>
- <char name="X" width="611"/>
- <char name="Y" width="556"/>
- <char name="Yacute" width="556"/>
- <char name="Ydieresis" width="556"/>
- <char name="Z" width="556"/>
- <char name="Zcaron" width="556"/>
- <char name="a" width="500"/>
- <char name="aacute" width="500"/>
- <char name="acircumflex" width="500"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="500"/>
- <char name="ae" width="667"/>
- <char name="agrave" width="500"/>
- <char name="ampersand" width="778"/>
- <char name="aring" width="500"/>
- <char name="asciicircum" width="422"/>
- <char name="asciitilde" width="541"/>
- <char name="asterisk" width="500"/>
- <char name="at" width="920"/>
- <char name="atilde" width="500"/>
- <char name="b" width="500"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="275"/>
- <char name="braceleft" width="400"/>
- <char name="braceright" width="400"/>
- <char name="bracketleft" width="389"/>
- <char name="bracketright" width="389"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="275"/>
- <char name="bullet" width="350"/>
- <char name="c" width="444"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="444"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="500"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="333"/>
- <char name="comma" width="250"/>
- <char name="copyright" width="760"/>
- <char name="currency" width="500"/>
- <char name="d" width="500"/>
- <char name="dagger" width="500"/>
- <char name="daggerdbl" width="500"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="675"/>
- <char name="dollar" width="500"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="444"/>
- <char name="eacute" width="444"/>
- <char name="ecircumflex" width="444"/>
- <char name="edieresis" width="444"/>
- <char name="egrave" width="444"/>
- <char name="eight" width="500"/>
- <char name="ellipsis" width="889"/>
- <char name="emdash" width="889"/>
- <char name="endash" width="500"/>
- <char name="equal" width="675"/>
- <char name="eth" width="500"/>
- <char name="exclam" width="333"/>
- <char name="exclamdown" width="389"/>
- <char name="f" width="278"/>
- <char name="fi" width="500"/>
- <char name="five" width="500"/>
- <char name="fl" width="500"/>
- <char name="florin" width="500"/>
- <char name="four" width="500"/>
- <char name="fraction" width="167"/>
- <char name="g" width="500"/>
- <char name="germandbls" width="500"/>
- <char name="grave" width="333"/>
- <char name="greater" width="675"/>
- <char name="guillemotleft" width="500"/>
- <char name="guillemotright" width="500"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="500"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="278"/>
- <char name="k" width="444"/>
- <char name="l" width="278"/>
- <char name="less" width="675"/>
- <char name="logicalnot" width="675"/>
- <char name="lslash" width="278"/>
- <char name="m" width="722"/>
- <char name="macron" width="333"/>
- <char name="minus" width="675"/>
- <char name="mu" width="500"/>
- <char name="multiply" width="675"/>
- <char name="n" width="500"/>
- <char name="nine" width="500"/>
- <char name="ntilde" width="500"/>
- <char name="numbersign" width="500"/>
- <char name="o" width="500"/>
- <char name="oacute" width="500"/>
- <char name="ocircumflex" width="500"/>
- <char name="odieresis" width="500"/>
- <char name="oe" width="667"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="500"/>
- <char name="one" width="500"/>
- <char name="onehalf" width="750"/>
- <char name="onequarter" width="750"/>
- <char name="onesuperior" width="300"/>
- <char name="ordfeminine" width="276"/>
- <char name="ordmasculine" width="310"/>
- <char name="oslash" width="500"/>
- <char name="otilde" width="500"/>
- <char name="p" width="500"/>
- <char name="paragraph" width="523"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="833"/>
- <char name="period" width="250"/>
- <char name="periodcentered" width="250"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="675"/>
- <char name="plusminus" width="675"/>
- <char name="q" width="500"/>
- <char name="question" width="500"/>
- <char name="questiondown" width="500"/>
- <char name="quotedbl" width="420"/>
- <char name="quotedblbase" width="556"/>
- <char name="quotedblleft" width="556"/>
- <char name="quotedblright" width="556"/>
- <char name="quoteleft" width="333"/>
- <char name="quoteright" width="333"/>
- <char name="quotesinglbase" width="333"/>
- <char name="quotesingle" width="214"/>
- <char name="r" width="389"/>
- <char name="registered" width="760"/>
- <char name="ring" width="333"/>
- <char name="s" width="389"/>
- <char name="scaron" width="389"/>
- <char name="section" width="500"/>
- <char name="semicolon" width="333"/>
- <char name="seven" width="500"/>
- <char name="six" width="500"/>
- <char name="slash" width="278"/>
- <char name="space" width="250"/>
+ <char-metrics>
+ <char name="A" width="611" llx="-51" lly="0" urx="564" ury="668"/>
+ <char name="AE" width="889" llx="-27" lly="0" urx="911" ury="653"/>
+ <char name="Aacute" width="611" llx="-51" lly="0" urx="564" ury="876"/>
+ <char name="Acircumflex" width="611" llx="-51" lly="0" urx="564" ury="873"/>
+ <char name="Adieresis" width="611" llx="-51" lly="0" urx="564" ury="818"/>
+ <char name="Agrave" width="611" llx="-51" lly="0" urx="564" ury="876"/>
+ <char name="Aring" width="611" llx="-51" lly="0" urx="564" ury="883"/>
+ <char name="Atilde" width="611" llx="-51" lly="0" urx="566" ury="836"/>
+ <char name="B" width="611" llx="-8" lly="0" urx="588" ury="653"/>
+ <char name="C" width="667" llx="66" lly="-18" urx="689" ury="666"/>
+ <char name="Ccedilla" width="667" llx="66" lly="-217" urx="689" ury="666"/>
+ <char name="D" width="722" llx="-8" lly="0" urx="700" ury="653"/>
+ <char name="E" width="611" llx="-1" lly="0" urx="634" ury="653"/>
+ <char name="Eacute" width="611" llx="-1" lly="0" urx="634" ury="876"/>
+ <char name="Ecircumflex" width="611" llx="-1" lly="0" urx="634" ury="873"/>
+ <char name="Edieresis" width="611" llx="-1" lly="0" urx="634" ury="818"/>
+ <char name="Egrave" width="611" llx="-1" lly="0" urx="634" ury="876"/>
+ <char name="Eth" width="722" llx="-8" lly="0" urx="700" ury="653"/>
+ <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="611" llx="8" lly="0" urx="645" ury="653"/>
+ <char name="G" width="722" llx="52" lly="-18" urx="722" ury="666"/>
+ <char name="H" width="722" llx="-8" lly="0" urx="767" ury="653"/>
+ <char name="I" width="333" llx="-8" lly="0" urx="384" ury="653"/>
+ <char name="Iacute" width="333" llx="-8" lly="0" urx="433" ury="876"/>
+ <char name="Icircumflex" width="333" llx="-8" lly="0" urx="425" ury="873"/>
+ <char name="Idieresis" width="333" llx="-8" lly="0" urx="435" ury="818"/>
+ <char name="Igrave" width="333" llx="-8" lly="0" urx="384" ury="876"/>
+ <char name="J" width="444" llx="-6" lly="-18" urx="491" ury="653"/>
+ <char name="K" width="667" llx="7" lly="0" urx="722" ury="653"/>
+ <char name="L" width="556" llx="-8" lly="0" urx="559" ury="653"/>
+ <char name="Lslash" width="556" llx="-8" lly="0" urx="559" ury="653"/>
+ <char name="M" width="833" llx="-18" lly="0" urx="873" ury="653"/>
+ <char name="N" width="667" llx="-20" lly="-15" urx="727" ury="653"/>
+ <char name="Ntilde" width="667" llx="-20" lly="-15" urx="727" ury="836"/>
+ <char name="O" width="722" llx="60" lly="-18" urx="699" ury="666"/>
+ <char name="OE" width="944" llx="49" lly="-8" urx="964" ury="666"/>
+ <char name="Oacute" width="722" llx="60" lly="-18" urx="699" ury="876"/>
+ <char name="Ocircumflex" width="722" llx="60" lly="-18" urx="699" ury="873"/>
+ <char name="Odieresis" width="722" llx="60" lly="-18" urx="699" ury="818"/>
+ <char name="Ograve" width="722" llx="60" lly="-18" urx="699" ury="876"/>
+ <char name="Oslash" width="722" llx="60" lly="-105" urx="699" ury="722"/>
+ <char name="Otilde" width="722" llx="60" lly="-18" urx="699" ury="836"/>
+ <char name="P" width="611" llx="0" lly="0" urx="605" ury="653"/>
+ <char name="Q" width="722" llx="59" lly="-182" urx="699" ury="666"/>
+ <char name="R" width="611" llx="-13" lly="0" urx="588" ury="653"/>
+ <char name="S" width="500" llx="17" lly="-18" urx="508" ury="667"/>
+ <char name="Scaron" width="500" llx="17" lly="-18" urx="520" ury="873"/>
+ <char name="T" width="556" llx="59" lly="0" urx="633" ury="653"/>
+ <char name="Thorn" width="611" llx="0" lly="0" urx="569" ury="653"/>
+ <char name="U" width="722" llx="102" lly="-18" urx="765" ury="653"/>
+ <char name="Uacute" width="722" llx="102" lly="-18" urx="765" ury="876"/>
+ <char name="Ucircumflex" width="722" llx="102" lly="-18" urx="765" ury="873"/>
+ <char name="Udieresis" width="722" llx="102" lly="-18" urx="765" ury="818"/>
+ <char name="Ugrave" width="722" llx="102" lly="-18" urx="765" ury="876"/>
+ <char name="V" width="611" llx="76" lly="-18" urx="688" ury="653"/>
+ <char name="W" width="833" llx="71" lly="-18" urx="906" ury="653"/>
+ <char name="X" width="611" llx="-29" lly="0" urx="655" ury="653"/>
+ <char name="Y" width="556" llx="78" lly="0" urx="633" ury="653"/>
+ <char name="Yacute" width="556" llx="78" lly="0" urx="633" ury="876"/>
+ <char name="Ydieresis" width="556" llx="78" lly="0" urx="633" ury="818"/>
+ <char name="Z" width="556" llx="-6" lly="0" urx="606" ury="653"/>
+ <char name="Zcaron" width="556" llx="-6" lly="0" urx="606" ury="873"/>
+ <char name="a" width="500" llx="17" lly="-11" urx="476" ury="441"/>
+ <char name="aacute" width="500" llx="17" lly="-11" urx="487" ury="664"/>
+ <char name="acircumflex" width="500" llx="17" lly="-11" urx="476" ury="661"/>
+ <char name="acute" width="333" llx="180" lly="494" urx="403" ury="664"/>
+ <char name="adieresis" width="500" llx="17" lly="-11" urx="489" ury="606"/>
+ <char name="ae" width="667" llx="23" lly="-11" urx="640" ury="441"/>
+ <char name="agrave" width="500" llx="17" lly="-11" urx="476" ury="664"/>
+ <char name="ampersand" width="778" llx="76" lly="-18" urx="723" ury="666"/>
+ <char name="aring" width="500" llx="17" lly="-11" urx="476" ury="691"/>
+ <char name="asciicircum" width="422" llx="0" lly="301" urx="422" ury="666"/>
+ <char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/>
+ <char name="asterisk" width="500" llx="128" lly="255" urx="492" ury="666"/>
+ <char name="at" width="920" llx="118" lly="-18" urx="806" ury="666"/>
+ <char name="atilde" width="500" llx="17" lly="-11" urx="511" ury="624"/>
+ <char name="b" width="500" llx="23" lly="-11" urx="473" ury="683"/>
+ <char name="backslash" width="278" llx="-41" lly="-18" urx="319" ury="666"/>
+ <char name="bar" width="275" llx="105" lly="-217" urx="171" ury="783"/>
+ <char name="braceleft" width="400" llx="51" lly="-177" urx="407" ury="687"/>
+ <char name="braceright" width="400" llx="-7" lly="-177" urx="349" ury="687"/>
+ <char name="bracketleft" width="389" llx="21" lly="-153" urx="391" ury="663"/>
+ <char name="bracketright" width="389" llx="12" lly="-153" urx="382" ury="663"/>
+ <char name="breve" width="333" llx="117" lly="492" urx="418" ury="650"/>
+ <char name="brokenbar" width="275" llx="105" lly="-142" urx="171" ury="708"/>
+ <char name="bullet" width="350" llx="40" lly="191" urx="310" ury="461"/>
+ <char name="c" width="444" llx="30" lly="-11" urx="425" ury="441"/>
+ <char name="caron" width="333" llx="121" lly="492" urx="426" ury="661"/>
+ <char name="ccedilla" width="444" llx="30" lly="-217" urx="425" ury="441"/>
+ <char name="cedilla" width="333" llx="-30" lly="-217" urx="182" ury="0"/>
+ <char name="cent" width="500" llx="77" lly="-143" urx="472" ury="560"/>
+ <char name="circumflex" width="333" llx="91" lly="492" urx="385" ury="661"/>
+ <char name="colon" width="333" llx="50" lly="-11" urx="261" ury="441"/>
+ <char name="comma" width="250" llx="-4" lly="-129" urx="135" ury="101"/>
+ <char name="copyright" width="760" llx="41" lly="-18" urx="719" ury="666"/>
+ <char name="currency" width="500" llx="-22" lly="53" urx="522" ury="597"/>
+ <char name="d" width="500" llx="15" lly="-13" urx="527" ury="683"/>
+ <char name="dagger" width="500" llx="101" lly="-159" urx="488" ury="666"/>
+ <char name="daggerdbl" width="500" llx="22" lly="-143" urx="491" ury="666"/>
+ <char name="degree" width="400" llx="101" lly="390" urx="387" ury="676"/>
+ <char name="dieresis" width="333" llx="107" lly="548" urx="405" ury="646"/>
+ <char name="divide" width="675" llx="86" lly="-11" urx="590" ury="517"/>
+ <char name="dollar" width="500" llx="31" lly="-89" urx="497" ury="731"/>
+ <char name="dotaccent" width="333" llx="207" lly="548" urx="305" ury="646"/>
+ <char name="dotlessi" width="278" llx="49" lly="-11" urx="235" ury="441"/>
+ <char name="e" width="444" llx="31" lly="-11" urx="412" ury="441"/>
+ <char name="eacute" width="444" llx="31" lly="-11" urx="459" ury="664"/>
+ <char name="ecircumflex" width="444" llx="31" lly="-11" urx="441" ury="661"/>
+ <char name="edieresis" width="444" llx="31" lly="-11" urx="451" ury="606"/>
+ <char name="egrave" width="444" llx="31" lly="-11" urx="412" ury="664"/>
+ <char name="eight" width="500" llx="30" lly="-7" urx="493" ury="676"/>
+ <char name="ellipsis" width="889" llx="57" lly="-11" urx="762" ury="100"/>
+ <char name="emdash" width="889" llx="-6" lly="197" urx="894" ury="243"/>
+ <char name="endash" width="500" llx="-6" lly="197" urx="505" ury="243"/>
+ <char name="equal" width="675" llx="86" lly="120" urx="590" ury="386"/>
+ <char name="eth" width="500" llx="27" lly="-11" urx="482" ury="683"/>
+ <char name="exclam" width="333" llx="39" lly="-11" urx="302" ury="667"/>
+ <char name="exclamdown" width="389" llx="59" lly="-205" urx="322" ury="473"/>
+ <char name="f" width="278" llx="-147" lly="-207" urx="424" ury="678"/>
+ <char name="fi" width="500" llx="-141" lly="-207" urx="481" ury="681"/>
+ <char name="five" width="500" llx="15" lly="-7" urx="491" ury="666"/>
+ <char name="fl" width="500" llx="-141" lly="-204" urx="518" ury="682"/>
+ <char name="florin" width="500" llx="25" lly="-182" urx="507" ury="682"/>
+ <char name="four" width="500" llx="1" lly="0" urx="479" ury="676"/>
+ <char name="fraction" width="167" llx="-169" lly="-10" urx="337" ury="676"/>
+ <char name="g" width="500" llx="8" lly="-206" urx="472" ury="441"/>
+ <char name="germandbls" width="500" llx="-168" lly="-207" urx="493" ury="679"/>
+ <char name="grave" width="333" llx="121" lly="492" urx="311" ury="664"/>
+ <char name="greater" width="675" llx="84" lly="-8" urx="592" ury="514"/>
+ <char name="guillemotleft" width="500" llx="53" lly="37" urx="445" ury="403"/>
+ <char name="guillemotright" width="500" llx="55" lly="37" urx="447" ury="403"/>
+ <char name="guilsinglleft" width="333" llx="51" lly="37" urx="281" ury="403"/>
+ <char name="guilsinglright" width="333" llx="52" lly="37" urx="282" ury="403"/>
+ <char name="h" width="500" llx="19" lly="-9" urx="478" ury="683"/>
+ <char name="hungarumlaut" width="333" llx="93" lly="494" urx="486" ury="664"/>
+ <char name="hyphen" width="333" llx="49" lly="192" urx="282" ury="255"/>
+ <char name="i" width="278" llx="49" lly="-11" urx="264" ury="654"/>
+ <char name="iacute" width="278" llx="49" lly="-11" urx="355" ury="664"/>
+ <char name="icircumflex" width="278" llx="33" lly="-11" urx="327" ury="661"/>
+ <char name="idieresis" width="278" llx="49" lly="-11" urx="352" ury="606"/>
+ <char name="igrave" width="278" llx="49" lly="-11" urx="284" ury="664"/>
+ <char name="j" width="278" llx="-124" lly="-207" urx="276" ury="654"/>
+ <char name="k" width="444" llx="14" lly="-11" urx="461" ury="683"/>
+ <char name="l" width="278" llx="41" lly="-11" urx="279" ury="683"/>
+ <char name="less" width="675" llx="84" lly="-8" urx="592" ury="514"/>
+ <char name="logicalnot" width="675" llx="86" lly="108" urx="590" ury="386"/>
+ <char name="lslash" width="278" llx="41" lly="-11" urx="312" ury="683"/>
+ <char name="m" width="722" llx="12" lly="-9" urx="704" ury="441"/>
+ <char name="macron" width="333" llx="99" lly="532" urx="411" ury="583"/>
+ <char name="minus" width="675" llx="86" lly="220" urx="590" ury="286"/>
+ <char name="mu" width="500" llx="-30" lly="-209" urx="497" ury="428"/>
+ <char name="multiply" width="675" llx="93" lly="8" urx="582" ury="497"/>
+ <char name="n" width="500" llx="14" lly="-9" urx="474" ury="441"/>
+ <char name="nine" width="500" llx="23" lly="-17" urx="492" ury="676"/>
+ <char name="ntilde" width="500" llx="14" lly="-9" urx="476" ury="624"/>
+ <char name="numbersign" width="500" llx="2" lly="0" urx="540" ury="676"/>
+ <char name="o" width="500" llx="27" lly="-11" urx="468" ury="441"/>
+ <char name="oacute" width="500" llx="27" lly="-11" urx="487" ury="664"/>
+ <char name="ocircumflex" width="500" llx="27" lly="-11" urx="468" ury="661"/>
+ <char name="odieresis" width="500" llx="27" lly="-11" urx="489" ury="606"/>
+ <char name="oe" width="667" llx="20" lly="-12" urx="646" ury="441"/>
+ <char name="ogonek" width="333" llx="20" lly="-169" urx="203" ury="40"/>
+ <char name="ograve" width="500" llx="27" lly="-11" urx="468" ury="664"/>
+ <char name="one" width="500" llx="49" lly="0" urx="409" ury="676"/>
+ <char name="onehalf" width="750" llx="34" lly="-10" urx="749" ury="676"/>
+ <char name="onequarter" width="750" llx="33" lly="-10" urx="736" ury="676"/>
+ <char name="onesuperior" width="300" llx="43" lly="271" urx="284" ury="676"/>
+ <char name="ordfeminine" width="276" llx="42" lly="406" urx="352" ury="676"/>
+ <char name="ordmasculine" width="310" llx="67" lly="406" urx="362" ury="676"/>
+ <char name="oslash" width="500" llx="28" lly="-135" urx="469" ury="554"/>
+ <char name="otilde" width="500" llx="27" lly="-11" urx="496" ury="624"/>
+ <char name="p" width="500" llx="-75" lly="-205" urx="469" ury="441"/>
+ <char name="paragraph" width="523" llx="55" lly="-123" urx="616" ury="653"/>
+ <char name="parenleft" width="333" llx="42" lly="-181" urx="315" ury="669"/>
+ <char name="parenright" width="333" llx="16" lly="-180" urx="289" ury="669"/>
+ <char name="percent" width="833" llx="79" lly="-13" urx="790" ury="676"/>
+ <char name="period" width="250" llx="27" lly="-11" urx="138" ury="100"/>
+ <char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/>
+ <char name="perthousand" width="1000" llx="25" lly="-19" urx="1010" ury="706"/>
+ <char name="plus" width="675" llx="86" lly="0" urx="590" ury="506"/>
+ <char name="plusminus" width="675" llx="86" lly="0" urx="590" ury="506"/>
+ <char name="q" width="500" llx="25" lly="-209" urx="483" ury="441"/>
+ <char name="question" width="500" llx="132" lly="-12" urx="472" ury="664"/>
+ <char name="questiondown" width="500" llx="28" lly="-205" urx="368" ury="471"/>
+ <char name="quotedbl" width="420" llx="144" lly="421" urx="432" ury="666"/>
+ <char name="quotedblbase" width="556" llx="57" lly="-129" urx="405" ury="101"/>
+ <char name="quotedblleft" width="556" llx="166" lly="436" urx="514" ury="666"/>
+ <char name="quotedblright" width="556" llx="151" lly="436" urx="499" ury="666"/>
+ <char name="quoteleft" width="333" llx="171" lly="436" urx="310" ury="666"/>
+ <char name="quoteright" width="333" llx="151" lly="436" urx="290" ury="666"/>
+ <char name="quotesinglbase" width="333" llx="44" lly="-129" urx="183" ury="101"/>
+ <char name="quotesingle" width="214" llx="132" lly="421" urx="241" ury="666"/>
+ <char name="r" width="389" llx="45" lly="0" urx="412" ury="441"/>
+ <char name="registered" width="760" llx="41" lly="-18" urx="719" ury="666"/>
+ <char name="ring" width="333" llx="155" lly="492" urx="355" ury="691"/>
+ <char name="s" width="389" llx="16" lly="-13" urx="366" ury="442"/>
+ <char name="scaron" width="389" llx="16" lly="-13" urx="454" ury="661"/>
+ <char name="section" width="500" llx="53" lly="-162" urx="461" ury="666"/>
+ <char name="semicolon" width="333" llx="27" lly="-129" urx="261" ury="441"/>
+ <char name="seven" width="500" llx="75" lly="-8" urx="537" ury="666"/>
+ <char name="six" width="500" llx="30" lly="-7" urx="521" ury="686"/>
+ <char name="slash" width="278" llx="-65" lly="-18" urx="386" ury="666"/>
+ <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="250"/>
- <char name="sterling" width="500"/>
- <char name="t" width="278"/>
- <char name="thorn" width="500"/>
- <char name="three" width="500"/>
- <char name="threequarters" width="750"/>
- <char name="threesuperior" width="300"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="980"/>
- <char name="two" width="500"/>
- <char name="twosuperior" width="300"/>
- <char name="u" width="500"/>
- <char name="uacute" width="500"/>
- <char name="ucircumflex" width="500"/>
- <char name="udieresis" width="500"/>
- <char name="ugrave" width="500"/>
- <char name="underscore" width="500"/>
- <char name="v" width="444"/>
- <char name="w" width="667"/>
- <char name="x" width="444"/>
- <char name="y" width="444"/>
- <char name="yacute" width="444"/>
- <char name="ydieresis" width="444"/>
- <char name="yen" width="500"/>
- <char name="z" width="389"/>
- <char name="zcaron" width="389"/>
- <char name="zero" width="500"/>
- </widths>
+ <char name="sterling" width="500" llx="10" lly="-6" urx="517" ury="670"/>
+ <char name="t" width="278" llx="37" lly="-11" urx="296" ury="546"/>
+ <char name="thorn" width="500" llx="-75" lly="-205" urx="469" ury="683"/>
+ <char name="three" width="500" llx="15" lly="-7" urx="465" ury="676"/>
+ <char name="threequarters" width="750" llx="23" lly="-10" urx="736" ury="676"/>
+ <char name="threesuperior" width="300" llx="43" lly="268" urx="339" ury="676"/>
+ <char name="tilde" width="333" llx="100" lly="517" urx="427" ury="624"/>
+ <char name="trademark" width="980" llx="30" lly="247" urx="957" ury="653"/>
+ <char name="two" width="500" llx="12" lly="0" urx="452" ury="676"/>
+ <char name="twosuperior" width="300" llx="33" lly="271" urx="324" ury="676"/>
+ <char name="u" width="500" llx="42" lly="-11" urx="475" ury="441"/>
+ <char name="uacute" width="500" llx="42" lly="-11" urx="477" ury="664"/>
+ <char name="ucircumflex" width="500" llx="42" lly="-11" urx="475" ury="661"/>
+ <char name="udieresis" width="500" llx="42" lly="-11" urx="479" ury="606"/>
+ <char name="ugrave" width="500" llx="42" lly="-11" urx="475" ury="664"/>
+ <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
+ <char name="v" width="444" llx="21" lly="-18" urx="426" ury="441"/>
+ <char name="w" width="667" llx="16" lly="-18" urx="648" ury="441"/>
+ <char name="x" width="444" llx="-27" lly="-11" urx="447" ury="441"/>
+ <char name="y" width="444" llx="-24" lly="-206" urx="426" ury="441"/>
+ <char name="yacute" width="444" llx="-24" lly="-206" urx="459" ury="664"/>
+ <char name="ydieresis" width="444" llx="-24" lly="-206" urx="441" ury="606"/>
+ <char name="yen" width="500" llx="27" lly="0" urx="603" ury="653"/>
+ <char name="z" width="389" llx="-2" lly="-81" urx="380" ury="428"/>
+ <char name="zcaron" width="389" llx="-2" lly="-81" urx="434" ury="661"/>
+ <char name="zero" width="500" llx="32" lly="-7" urx="497" ury="676"/>
+ </char-metrics>
<kerning kpx1="79">
<pair kern="-55" kpx2="65"/>
<pair kern="-50" kpx2="87"/>
@@ -641,4 +642,4 @@
<pair kern="0" kpx2="121"/>
<pair kern="-40" kpx2="118"/>
</kerning>
-</font-metrics> \ No newline at end of file
+</font-metrics>
diff --git a/src/codegen/fonts/TimesRoman.xml b/src/codegen/fonts/TimesRoman.xml
index 9ddadfddd..9e16b6a3b 100644
--- a/src/codegen/fonts/TimesRoman.xml
+++ b/src/codegen/fonts/TimesRoman.xml
@@ -22,245 +22,246 @@
<family-name>Times</family-name>
<class-name>TimesRoman</class-name>
<encoding>StandardEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>662</cap-height>
<x-height>450</x-height>
<ascender>683</ascender>
<descender>-217</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="A" width="722"/>
- <char name="AE" width="889"/>
- <char name="Aacute" width="722"/>
- <char name="Acircumflex" width="722"/>
- <char name="Adieresis" width="722"/>
- <char name="Agrave" width="722"/>
- <char name="Aring" width="722"/>
- <char name="Atilde" width="722"/>
- <char name="B" width="667"/>
- <char name="C" width="667"/>
- <char name="Ccedilla" width="667"/>
- <char name="D" width="722"/>
- <char name="E" width="611"/>
- <char name="Eacute" width="611"/>
- <char name="Ecircumflex" width="611"/>
- <char name="Edieresis" width="611"/>
- <char name="Egrave" width="611"/>
- <char name="Eth" width="722"/>
- <char name="Euro" width="500"/>
- <char name="F" width="556"/>
- <char name="G" width="722"/>
- <char name="H" width="722"/>
- <char name="I" width="333"/>
- <char name="Iacute" width="333"/>
- <char name="Icircumflex" width="333"/>
- <char name="Idieresis" width="333"/>
- <char name="Igrave" width="333"/>
- <char name="J" width="389"/>
- <char name="K" width="722"/>
- <char name="L" width="611"/>
- <char name="Lslash" width="611"/>
- <char name="M" width="889"/>
- <char name="N" width="722"/>
- <char name="Ntilde" width="722"/>
- <char name="O" width="722"/>
- <char name="OE" width="889"/>
- <char name="Oacute" width="722"/>
- <char name="Ocircumflex" width="722"/>
- <char name="Odieresis" width="722"/>
- <char name="Ograve" width="722"/>
- <char name="Oslash" width="722"/>
- <char name="Otilde" width="722"/>
- <char name="P" width="556"/>
- <char name="Q" width="722"/>
- <char name="R" width="667"/>
- <char name="S" width="556"/>
- <char name="Scaron" width="556"/>
- <char name="T" width="611"/>
- <char name="Thorn" width="556"/>
- <char name="U" width="722"/>
- <char name="Uacute" width="722"/>
- <char name="Ucircumflex" width="722"/>
- <char name="Udieresis" width="722"/>
- <char name="Ugrave" width="722"/>
- <char name="V" width="722"/>
- <char name="W" width="944"/>
- <char name="X" width="722"/>
- <char name="Y" width="722"/>
- <char name="Yacute" width="722"/>
- <char name="Ydieresis" width="722"/>
- <char name="Z" width="611"/>
- <char name="Zcaron" width="611"/>
- <char name="a" width="444"/>
- <char name="aacute" width="444"/>
- <char name="acircumflex" width="444"/>
- <char name="acute" width="333"/>
- <char name="adieresis" width="444"/>
- <char name="ae" width="667"/>
- <char name="agrave" width="444"/>
- <char name="ampersand" width="778"/>
- <char name="aring" width="444"/>
- <char name="asciicircum" width="469"/>
- <char name="asciitilde" width="541"/>
- <char name="asterisk" width="500"/>
- <char name="at" width="921"/>
- <char name="atilde" width="444"/>
- <char name="b" width="500"/>
- <char name="backslash" width="278"/>
- <char name="bar" width="200"/>
- <char name="braceleft" width="480"/>
- <char name="braceright" width="480"/>
- <char name="bracketleft" width="333"/>
- <char name="bracketright" width="333"/>
- <char name="breve" width="333"/>
- <char name="brokenbar" width="200"/>
- <char name="bullet" width="350"/>
- <char name="c" width="444"/>
- <char name="caron" width="333"/>
- <char name="ccedilla" width="444"/>
- <char name="cedilla" width="333"/>
- <char name="cent" width="500"/>
- <char name="circumflex" width="333"/>
- <char name="colon" width="278"/>
- <char name="comma" width="250"/>
- <char name="copyright" width="760"/>
- <char name="currency" width="500"/>
- <char name="d" width="500"/>
- <char name="dagger" width="500"/>
- <char name="daggerdbl" width="500"/>
- <char name="degree" width="400"/>
- <char name="dieresis" width="333"/>
- <char name="divide" width="564"/>
- <char name="dollar" width="500"/>
- <char name="dotaccent" width="333"/>
- <char name="dotlessi" width="278"/>
- <char name="e" width="444"/>
- <char name="eacute" width="444"/>
- <char name="ecircumflex" width="444"/>
- <char name="edieresis" width="444"/>
- <char name="egrave" width="444"/>
- <char name="eight" width="500"/>
- <char name="ellipsis" width="1000"/>
- <char name="emdash" width="1000"/>
- <char name="endash" width="500"/>
- <char name="equal" width="564"/>
- <char name="eth" width="500"/>
- <char name="exclam" width="333"/>
- <char name="exclamdown" width="333"/>
- <char name="f" width="333"/>
- <char name="fi" width="556"/>
- <char name="five" width="500"/>
- <char name="fl" width="556"/>
- <char name="florin" width="500"/>
- <char name="four" width="500"/>
- <char name="fraction" width="167"/>
- <char name="g" width="500"/>
- <char name="germandbls" width="500"/>
- <char name="grave" width="333"/>
- <char name="greater" width="564"/>
- <char name="guillemotleft" width="500"/>
- <char name="guillemotright" width="500"/>
- <char name="guilsinglleft" width="333"/>
- <char name="guilsinglright" width="333"/>
- <char name="h" width="500"/>
- <char name="hungarumlaut" width="333"/>
- <char name="hyphen" width="333"/>
- <char name="i" width="278"/>
- <char name="iacute" width="278"/>
- <char name="icircumflex" width="278"/>
- <char name="idieresis" width="278"/>
- <char name="igrave" width="278"/>
- <char name="j" width="278"/>
- <char name="k" width="500"/>
- <char name="l" width="278"/>
- <char name="less" width="564"/>
- <char name="logicalnot" width="564"/>
- <char name="lslash" width="278"/>
- <char name="m" width="778"/>
- <char name="macron" width="333"/>
- <char name="minus" width="324"/>
- <char name="mu" width="500"/>
- <char name="multiply" width="564"/>
- <char name="n" width="500"/>
- <char name="nine" width="500"/>
- <char name="ntilde" width="500"/>
- <char name="numbersign" width="500"/>
- <char name="o" width="500"/>
- <char name="oacute" width="500"/>
- <char name="ocircumflex" width="500"/>
- <char name="odieresis" width="500"/>
- <char name="oe" width="722"/>
- <char name="ogonek" width="333"/>
- <char name="ograve" width="500"/>
- <char name="one" width="500"/>
- <char name="onehalf" width="750"/>
- <char name="onequarter" width="750"/>
- <char name="onesuperior" width="300"/>
- <char name="ordfeminine" width="276"/>
- <char name="ordmasculine" width="310"/>
- <char name="oslash" width="500"/>
- <char name="otilde" width="500"/>
- <char name="p" width="500"/>
- <char name="paragraph" width="453"/>
- <char name="parenleft" width="333"/>
- <char name="parenright" width="333"/>
- <char name="percent" width="833"/>
- <char name="period" width="250"/>
- <char name="periodcentered" width="250"/>
- <char name="perthousand" width="1000"/>
- <char name="plus" width="564"/>
- <char name="plusminus" width="564"/>
- <char name="q" width="500"/>
- <char name="question" width="444"/>
- <char name="questiondown" width="444"/>
- <char name="quotedbl" width="408"/>
- <char name="quotedblbase" width="444"/>
- <char name="quotedblleft" width="444"/>
- <char name="quotedblright" width="444"/>
- <char name="quoteleft" width="333"/>
- <char name="quoteright" width="333"/>
- <char name="quotesinglbase" width="333"/>
- <char name="quotesingle" width="180"/>
- <char name="r" width="333"/>
- <char name="registered" width="760"/>
- <char name="ring" width="333"/>
- <char name="s" width="389"/>
- <char name="scaron" width="389"/>
- <char name="section" width="500"/>
- <char name="semicolon" width="278"/>
- <char name="seven" width="500"/>
- <char name="six" width="500"/>
- <char name="slash" width="278"/>
- <char name="space" width="250"/>
+ <char-metrics>
+ <char name="A" width="722" llx="15" lly="0" urx="706" ury="674"/>
+ <char name="AE" width="889" llx="0" lly="0" urx="863" ury="662"/>
+ <char name="Aacute" width="722" llx="15" lly="0" urx="706" ury="890"/>
+ <char name="Acircumflex" width="722" llx="15" lly="0" urx="706" ury="886"/>
+ <char name="Adieresis" width="722" llx="15" lly="0" urx="706" ury="835"/>
+ <char name="Agrave" width="722" llx="15" lly="0" urx="706" ury="890"/>
+ <char name="Aring" width="722" llx="15" lly="0" urx="706" ury="898"/>
+ <char name="Atilde" width="722" llx="15" lly="0" urx="706" ury="850"/>
+ <char name="B" width="667" llx="17" lly="0" urx="593" ury="662"/>
+ <char name="C" width="667" llx="28" lly="-14" urx="633" ury="676"/>
+ <char name="Ccedilla" width="667" llx="28" lly="-215" urx="633" ury="676"/>
+ <char name="D" width="722" llx="16" lly="0" urx="685" ury="662"/>
+ <char name="E" width="611" llx="12" lly="0" urx="597" ury="662"/>
+ <char name="Eacute" width="611" llx="12" lly="0" urx="597" ury="890"/>
+ <char name="Ecircumflex" width="611" llx="12" lly="0" urx="597" ury="886"/>
+ <char name="Edieresis" width="611" llx="12" lly="0" urx="597" ury="835"/>
+ <char name="Egrave" width="611" llx="12" lly="0" urx="597" ury="890"/>
+ <char name="Eth" width="722" llx="16" lly="0" urx="685" ury="662"/>
+ <char name="Euro" width="500" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="F" width="556" llx="12" lly="0" urx="546" ury="662"/>
+ <char name="G" width="722" llx="32" lly="-14" urx="709" ury="676"/>
+ <char name="H" width="722" llx="19" lly="0" urx="702" ury="662"/>
+ <char name="I" width="333" llx="18" lly="0" urx="315" ury="662"/>
+ <char name="Iacute" width="333" llx="18" lly="0" urx="317" ury="890"/>
+ <char name="Icircumflex" width="333" llx="11" lly="0" urx="322" ury="886"/>
+ <char name="Idieresis" width="333" llx="18" lly="0" urx="315" ury="835"/>
+ <char name="Igrave" width="333" llx="18" lly="0" urx="315" ury="890"/>
+ <char name="J" width="389" llx="10" lly="-14" urx="370" ury="662"/>
+ <char name="K" width="722" llx="34" lly="0" urx="723" ury="662"/>
+ <char name="L" width="611" llx="12" lly="0" urx="598" ury="662"/>
+ <char name="Lslash" width="611" llx="12" lly="0" urx="598" ury="662"/>
+ <char name="M" width="889" llx="12" lly="0" urx="863" ury="662"/>
+ <char name="N" width="722" llx="12" lly="-11" urx="707" ury="662"/>
+ <char name="Ntilde" width="722" llx="12" lly="-11" urx="707" ury="850"/>
+ <char name="O" width="722" llx="34" lly="-14" urx="688" ury="676"/>
+ <char name="OE" width="889" llx="30" lly="-6" urx="885" ury="668"/>
+ <char name="Oacute" width="722" llx="34" lly="-14" urx="688" ury="890"/>
+ <char name="Ocircumflex" width="722" llx="34" lly="-14" urx="688" ury="886"/>
+ <char name="Odieresis" width="722" llx="34" lly="-14" urx="688" ury="835"/>
+ <char name="Ograve" width="722" llx="34" lly="-14" urx="688" ury="890"/>
+ <char name="Oslash" width="722" llx="34" lly="-80" urx="688" ury="734"/>
+ <char name="Otilde" width="722" llx="34" lly="-14" urx="688" ury="850"/>
+ <char name="P" width="556" llx="16" lly="0" urx="542" ury="662"/>
+ <char name="Q" width="722" llx="34" lly="-178" urx="701" ury="676"/>
+ <char name="R" width="667" llx="17" lly="0" urx="659" ury="662"/>
+ <char name="S" width="556" llx="42" lly="-14" urx="491" ury="676"/>
+ <char name="Scaron" width="556" llx="42" lly="-14" urx="491" ury="886"/>
+ <char name="T" width="611" llx="17" lly="0" urx="593" ury="662"/>
+ <char name="Thorn" width="556" llx="16" lly="0" urx="542" ury="662"/>
+ <char name="U" width="722" llx="14" lly="-14" urx="705" ury="662"/>
+ <char name="Uacute" width="722" llx="14" lly="-14" urx="705" ury="890"/>
+ <char name="Ucircumflex" width="722" llx="14" lly="-14" urx="705" ury="886"/>
+ <char name="Udieresis" width="722" llx="14" lly="-14" urx="705" ury="835"/>
+ <char name="Ugrave" width="722" llx="14" lly="-14" urx="705" ury="890"/>
+ <char name="V" width="722" llx="16" lly="-11" urx="697" ury="662"/>
+ <char name="W" width="944" llx="5" lly="-11" urx="932" ury="662"/>
+ <char name="X" width="722" llx="10" lly="0" urx="704" ury="662"/>
+ <char name="Y" width="722" llx="22" lly="0" urx="703" ury="662"/>
+ <char name="Yacute" width="722" llx="22" lly="0" urx="703" ury="890"/>
+ <char name="Ydieresis" width="722" llx="22" lly="0" urx="703" ury="835"/>
+ <char name="Z" width="611" llx="9" lly="0" urx="597" ury="662"/>
+ <char name="Zcaron" width="611" llx="9" lly="0" urx="597" ury="886"/>
+ <char name="a" width="444" llx="37" lly="-10" urx="442" ury="460"/>
+ <char name="aacute" width="444" llx="37" lly="-10" urx="442" ury="678"/>
+ <char name="acircumflex" width="444" llx="37" lly="-10" urx="442" ury="674"/>
+ <char name="acute" width="333" llx="93" lly="507" urx="317" ury="678"/>
+ <char name="adieresis" width="444" llx="37" lly="-10" urx="442" ury="623"/>
+ <char name="ae" width="667" llx="38" lly="-10" urx="632" ury="460"/>
+ <char name="agrave" width="444" llx="37" lly="-10" urx="442" ury="678"/>
+ <char name="ampersand" width="778" llx="42" lly="-13" urx="750" ury="676"/>
+ <char name="aring" width="444" llx="37" lly="-10" urx="442" ury="711"/>
+ <char name="asciicircum" width="469" llx="24" lly="297" urx="446" ury="662"/>
+ <char name="asciitilde" width="541" llx="40" lly="183" urx="502" ury="323"/>
+ <char name="asterisk" width="500" llx="69" lly="265" urx="432" ury="676"/>
+ <char name="at" width="921" llx="116" lly="-14" urx="809" ury="676"/>
+ <char name="atilde" width="444" llx="37" lly="-10" urx="442" ury="638"/>
+ <char name="b" width="500" llx="3" lly="-10" urx="468" ury="683"/>
+ <char name="backslash" width="278" llx="-9" lly="-14" urx="287" ury="676"/>
+ <char name="bar" width="200" llx="67" lly="-218" urx="133" ury="782"/>
+ <char name="braceleft" width="480" llx="100" lly="-181" urx="350" ury="680"/>
+ <char name="braceright" width="480" llx="130" lly="-181" urx="380" ury="680"/>
+ <char name="bracketleft" width="333" llx="88" lly="-156" urx="299" ury="662"/>
+ <char name="bracketright" width="333" llx="34" lly="-156" urx="245" ury="662"/>
+ <char name="breve" width="333" llx="26" lly="507" urx="307" ury="664"/>
+ <char name="brokenbar" width="200" llx="67" lly="-143" urx="133" ury="707"/>
+ <char name="bullet" width="350" llx="40" lly="196" urx="310" ury="466"/>
+ <char name="c" width="444" llx="25" lly="-10" urx="412" ury="460"/>
+ <char name="caron" width="333" llx="11" lly="507" urx="322" ury="674"/>
+ <char name="ccedilla" width="444" llx="25" lly="-215" urx="412" ury="460"/>
+ <char name="cedilla" width="333" llx="52" lly="-215" urx="261" ury="0"/>
+ <char name="cent" width="500" llx="53" lly="-138" urx="448" ury="579"/>
+ <char name="circumflex" width="333" llx="11" lly="507" urx="322" ury="674"/>
+ <char name="colon" width="278" llx="81" lly="-11" urx="192" ury="459"/>
+ <char name="comma" width="250" llx="56" lly="-141" urx="195" ury="102"/>
+ <char name="copyright" width="760" llx="38" lly="-14" urx="722" ury="676"/>
+ <char name="currency" width="500" llx="-22" lly="58" urx="522" ury="602"/>
+ <char name="d" width="500" llx="27" lly="-10" urx="491" ury="683"/>
+ <char name="dagger" width="500" llx="59" lly="-149" urx="442" ury="676"/>
+ <char name="daggerdbl" width="500" llx="58" lly="-153" urx="442" ury="676"/>
+ <char name="degree" width="400" llx="57" lly="390" urx="343" ury="676"/>
+ <char name="dieresis" width="333" llx="18" lly="581" urx="315" ury="681"/>
+ <char name="divide" width="564" llx="30" lly="-10" urx="534" ury="516"/>
+ <char name="dollar" width="500" llx="44" lly="-87" urx="457" ury="727"/>
+ <char name="dotaccent" width="333" llx="118" lly="581" urx="216" ury="681"/>
+ <char name="dotlessi" width="278" llx="16" lly="0" urx="253" ury="460"/>
+ <char name="e" width="444" llx="25" lly="-10" urx="424" ury="460"/>
+ <char name="eacute" width="444" llx="25" lly="-10" urx="424" ury="678"/>
+ <char name="ecircumflex" width="444" llx="25" lly="-10" urx="424" ury="674"/>
+ <char name="edieresis" width="444" llx="25" lly="-10" urx="424" ury="623"/>
+ <char name="egrave" width="444" llx="25" lly="-10" urx="424" ury="678"/>
+ <char name="eight" width="500" llx="56" lly="-14" urx="445" ury="676"/>
+ <char name="ellipsis" width="1000" llx="111" lly="-11" urx="888" ury="100"/>
+ <char name="emdash" width="1000" llx="0" lly="201" urx="1000" ury="250"/>
+ <char name="endash" width="500" llx="0" lly="201" urx="500" ury="250"/>
+ <char name="equal" width="564" llx="30" lly="120" urx="534" ury="386"/>
+ <char name="eth" width="500" llx="29" lly="-10" urx="471" ury="686"/>
+ <char name="exclam" width="333" llx="130" lly="-9" urx="238" ury="676"/>
+ <char name="exclamdown" width="333" llx="97" lly="-218" urx="205" ury="467"/>
+ <char name="f" width="333" llx="20" lly="0" urx="383" ury="683"/>
+ <char name="fi" width="556" llx="31" lly="0" urx="521" ury="683"/>
+ <char name="five" width="500" llx="32" lly="-14" urx="438" ury="688"/>
+ <char name="fl" width="556" llx="32" lly="0" urx="521" ury="683"/>
+ <char name="florin" width="500" llx="7" lly="-189" urx="490" ury="676"/>
+ <char name="four" width="500" llx="12" lly="0" urx="472" ury="676"/>
+ <char name="fraction" width="167" llx="-168" lly="-14" urx="331" ury="676"/>
+ <char name="g" width="500" llx="28" lly="-218" urx="470" ury="460"/>
+ <char name="germandbls" width="500" llx="12" lly="-9" urx="468" ury="683"/>
+ <char name="grave" width="333" llx="19" lly="507" urx="242" ury="678"/>
+ <char name="greater" width="564" llx="28" lly="-8" urx="536" ury="514"/>
+ <char name="guillemotleft" width="500" llx="42" lly="33" urx="456" ury="416"/>
+ <char name="guillemotright" width="500" llx="44" lly="33" urx="458" ury="416"/>
+ <char name="guilsinglleft" width="333" llx="63" lly="33" urx="285" ury="416"/>
+ <char name="guilsinglright" width="333" llx="48" lly="33" urx="270" ury="416"/>
+ <char name="h" width="500" llx="9" lly="0" urx="487" ury="683"/>
+ <char name="hungarumlaut" width="333" llx="-3" lly="507" urx="377" ury="678"/>
+ <char name="hyphen" width="333" llx="39" lly="194" urx="285" ury="257"/>
+ <char name="i" width="278" llx="16" lly="0" urx="253" ury="683"/>
+ <char name="iacute" width="278" llx="16" lly="0" urx="290" ury="678"/>
+ <char name="icircumflex" width="278" llx="-16" lly="0" urx="295" ury="674"/>
+ <char name="idieresis" width="278" llx="-9" lly="0" urx="288" ury="623"/>
+ <char name="igrave" width="278" llx="-8" lly="0" urx="253" ury="678"/>
+ <char name="j" width="278" llx="-70" lly="-218" urx="194" ury="683"/>
+ <char name="k" width="500" llx="7" lly="0" urx="505" ury="683"/>
+ <char name="l" width="278" llx="19" lly="0" urx="257" ury="683"/>
+ <char name="less" width="564" llx="28" lly="-8" urx="536" ury="514"/>
+ <char name="logicalnot" width="564" llx="30" lly="108" urx="534" ury="386"/>
+ <char name="lslash" width="278" llx="19" lly="0" urx="259" ury="683"/>
+ <char name="m" width="778" llx="16" lly="0" urx="775" ury="460"/>
+ <char name="macron" width="333" llx="11" lly="547" urx="322" ury="601"/>
+ <char name="minus" width="324" llx="30" lly="220" urx="534" ury="286"/>
+ <char name="mu" width="500" llx="36" lly="-218" urx="512" ury="450"/>
+ <char name="multiply" width="564" llx="38" lly="8" urx="527" ury="497"/>
+ <char name="n" width="500" llx="16" lly="0" urx="485" ury="460"/>
+ <char name="nine" width="500" llx="30" lly="-22" urx="459" ury="676"/>
+ <char name="ntilde" width="500" llx="16" lly="0" urx="485" ury="638"/>
+ <char name="numbersign" width="500" llx="5" lly="0" urx="496" ury="662"/>
+ <char name="o" width="500" llx="29" lly="-10" urx="470" ury="460"/>
+ <char name="oacute" width="500" llx="29" lly="-10" urx="470" ury="678"/>
+ <char name="ocircumflex" width="500" llx="29" lly="-10" urx="470" ury="674"/>
+ <char name="odieresis" width="500" llx="29" lly="-10" urx="470" ury="623"/>
+ <char name="oe" width="722" llx="30" lly="-10" urx="690" ury="460"/>
+ <char name="ogonek" width="333" llx="62" lly="-165" urx="243" ury="0"/>
+ <char name="ograve" width="500" llx="29" lly="-10" urx="470" ury="678"/>
+ <char name="one" width="500" llx="111" lly="0" urx="394" ury="676"/>
+ <char name="onehalf" width="750" llx="31" lly="-14" urx="746" ury="676"/>
+ <char name="onequarter" width="750" llx="37" lly="-14" urx="718" ury="676"/>
+ <char name="onesuperior" width="300" llx="57" lly="270" urx="248" ury="676"/>
+ <char name="ordfeminine" width="276" llx="4" lly="394" urx="270" ury="676"/>
+ <char name="ordmasculine" width="310" llx="6" lly="394" urx="304" ury="676"/>
+ <char name="oslash" width="500" llx="29" lly="-112" urx="470" ury="551"/>
+ <char name="otilde" width="500" llx="29" lly="-10" urx="470" ury="638"/>
+ <char name="p" width="500" llx="5" lly="-217" urx="470" ury="460"/>
+ <char name="paragraph" width="453" llx="-22" lly="-154" urx="450" ury="662"/>
+ <char name="parenleft" width="333" llx="48" lly="-177" urx="304" ury="676"/>
+ <char name="parenright" width="333" llx="29" lly="-177" urx="285" ury="676"/>
+ <char name="percent" width="833" llx="61" lly="-13" urx="772" ury="676"/>
+ <char name="period" width="250" llx="70" lly="-11" urx="181" ury="100"/>
+ <char name="periodcentered" width="250" llx="70" lly="199" urx="181" ury="310"/>
+ <char name="perthousand" width="1000" llx="7" lly="-19" urx="994" ury="706"/>
+ <char name="plus" width="564" llx="30" lly="0" urx="534" ury="506"/>
+ <char name="plusminus" width="564" llx="30" lly="0" urx="534" ury="506"/>
+ <char name="q" width="500" llx="24" lly="-217" urx="488" ury="460"/>
+ <char name="question" width="444" llx="68" lly="-8" urx="414" ury="676"/>
+ <char name="questiondown" width="444" llx="30" lly="-218" urx="376" ury="466"/>
+ <char name="quotedbl" width="408" llx="77" lly="431" urx="331" ury="676"/>
+ <char name="quotedblbase" width="444" llx="45" lly="-141" urx="416" ury="102"/>
+ <char name="quotedblleft" width="444" llx="43" lly="433" urx="414" ury="676"/>
+ <char name="quotedblright" width="444" llx="30" lly="433" urx="401" ury="676"/>
+ <char name="quoteleft" width="333" llx="115" lly="433" urx="254" ury="676"/>
+ <char name="quoteright" width="333" llx="79" lly="433" urx="218" ury="676"/>
+ <char name="quotesinglbase" width="333" llx="79" lly="-141" urx="218" ury="102"/>
+ <char name="quotesingle" width="180" llx="48" lly="431" urx="133" ury="676"/>
+ <char name="r" width="333" llx="5" lly="0" urx="335" ury="460"/>
+ <char name="registered" width="760" llx="38" lly="-14" urx="722" ury="676"/>
+ <char name="ring" width="333" llx="67" lly="512" urx="266" ury="711"/>
+ <char name="s" width="389" llx="51" lly="-10" urx="348" ury="460"/>
+ <char name="scaron" width="389" llx="39" lly="-10" urx="350" ury="674"/>
+ <char name="section" width="500" llx="70" lly="-148" urx="426" ury="676"/>
+ <char name="semicolon" width="278" llx="80" lly="-141" urx="219" ury="459"/>
+ <char name="seven" width="500" llx="20" lly="-8" urx="449" ury="662"/>
+ <char name="six" width="500" llx="34" lly="-14" urx="468" ury="684"/>
+ <char name="slash" width="278" llx="-9" lly="-14" urx="287" ury="676"/>
+ <char name="space" width="250" llx="0" lly="0" urx="0" ury="0"/>
<!-- JKT: the following has been manually added -->
- <char name="nbsp" width="250"/>
- <char name="sterling" width="500"/>
- <char name="t" width="278"/>
- <char name="thorn" width="500"/>
- <char name="three" width="500"/>
- <char name="threequarters" width="750"/>
- <char name="threesuperior" width="300"/>
- <char name="tilde" width="333"/>
- <char name="trademark" width="980"/>
- <char name="two" width="500"/>
- <char name="twosuperior" width="300"/>
- <char name="u" width="500"/>
- <char name="uacute" width="500"/>
- <char name="ucircumflex" width="500"/>
- <char name="udieresis" width="500"/>
- <char name="ugrave" width="500"/>
- <char name="underscore" width="500"/>
- <char name="v" width="500"/>
- <char name="w" width="722"/>
- <char name="x" width="500"/>
- <char name="y" width="500"/>
- <char name="yacute" width="500"/>
- <char name="ydieresis" width="500"/>
- <char name="yen" width="500"/>
- <char name="z" width="444"/>
- <char name="zcaron" width="444"/>
- <char name="zero" width="500"/>
- </widths>
+ <char name="sterling" width="500" llx="12" lly="-8" urx="490" ury="676"/>
+ <char name="t" width="278" llx="13" lly="-10" urx="279" ury="579"/>
+ <char name="thorn" width="500" llx="5" lly="-217" urx="470" ury="683"/>
+ <char name="three" width="500" llx="43" lly="-14" urx="431" ury="676"/>
+ <char name="threequarters" width="750" llx="15" lly="-14" urx="718" ury="676"/>
+ <char name="threesuperior" width="300" llx="15" lly="262" urx="291" ury="676"/>
+ <char name="tilde" width="333" llx="1" lly="532" urx="331" ury="638"/>
+ <char name="trademark" width="980" llx="30" lly="256" urx="957" ury="662"/>
+ <char name="two" width="500" llx="30" lly="0" urx="475" ury="676"/>
+ <char name="twosuperior" width="300" llx="1" lly="270" urx="296" ury="676"/>
+ <char name="u" width="500" llx="9" lly="-10" urx="479" ury="450"/>
+ <char name="uacute" width="500" llx="9" lly="-10" urx="479" ury="678"/>
+ <char name="ucircumflex" width="500" llx="9" lly="-10" urx="479" ury="674"/>
+ <char name="udieresis" width="500" llx="9" lly="-10" urx="479" ury="623"/>
+ <char name="ugrave" width="500" llx="9" lly="-10" urx="479" ury="678"/>
+ <char name="underscore" width="500" llx="0" lly="-125" urx="500" ury="-75"/>
+ <char name="v" width="500" llx="19" lly="-14" urx="477" ury="450"/>
+ <char name="w" width="722" llx="21" lly="-14" urx="694" ury="450"/>
+ <char name="x" width="500" llx="17" lly="0" urx="479" ury="450"/>
+ <char name="y" width="500" llx="14" lly="-218" urx="475" ury="450"/>
+ <char name="yacute" width="500" llx="14" lly="-218" urx="475" ury="678"/>
+ <char name="ydieresis" width="500" llx="14" lly="-218" urx="475" ury="623"/>
+ <char name="yen" width="500" llx="-53" lly="0" urx="512" ury="662"/>
+ <char name="z" width="444" llx="27" lly="0" urx="418" ury="450"/>
+ <char name="zcaron" width="444" llx="27" lly="0" urx="418" ury="674"/>
+ <char name="zero" width="500" llx="24" lly="-14" urx="476" ury="676"/>
+ </char-metrics>
<kerning kpx1="79">
<pair kern="-35" kpx2="65"/>
<pair kern="-35" kpx2="87"/>
diff --git a/src/codegen/fonts/ZapfDingbats.xml b/src/codegen/fonts/ZapfDingbats.xml
index f6ed76d25..bd72901dc 100644
--- a/src/codegen/fonts/ZapfDingbats.xml
+++ b/src/codegen/fonts/ZapfDingbats.xml
@@ -21,214 +21,216 @@
<family-name>ZapfDingbats</family-name>
<class-name>ZapfDingbats</class-name>
<encoding>ZapfDingbatsEncoding</encoding>
+ <underline-position>-100</underline-position>
+ <underline-thickness>50</underline-thickness>
<cap-height>820</cap-height>
<x-height>426</x-height>
<ascender>820</ascender>
<descender>-143</descender>
<first-char>32</first-char>
<last-char>255</last-char>
- <widths>
- <char name="space" width="278"/>
- <char name="a1" width="974"/>
- <char name="a2" width="961"/>
- <char name="a202" width="974"/>
- <char name="a3" width="980"/>
- <char name="a4" width="719"/>
- <char name="a5" width="789"/>
- <char name="a119" width="790"/>
- <char name="a118" width="791"/>
- <char name="a117" width="690"/>
- <char name="a11" width="960"/>
- <char name="a12" width="939"/>
- <char name="a13" width="549"/>
- <char name="a14" width="855"/>
- <char name="a15" width="911"/>
- <char name="a16" width="933"/>
- <char name="a105" width="911"/>
- <char name="a17" width="945"/>
- <char name="a18" width="974"/>
- <char name="a19" width="755"/>
- <char name="a20" width="846"/>
- <char name="a21" width="762"/>
- <char name="a22" width="761"/>
- <char name="a23" width="571"/>
- <char name="a24" width="677"/>
- <char name="a25" width="763"/>
- <char name="a26" width="760"/>
- <char name="a27" width="759"/>
- <char name="a28" width="754"/>
- <char name="a6" width="494"/>
- <char name="a7" width="552"/>
- <char name="a8" width="537"/>
- <char name="a9" width="577"/>
- <char name="a10" width="692"/>
- <char name="a29" width="786"/>
- <char name="a30" width="788"/>
- <char name="a31" width="788"/>
- <char name="a32" width="790"/>
- <char name="a33" width="793"/>
- <char name="a34" width="794"/>
- <char name="a35" width="816"/>
- <char name="a36" width="823"/>
- <char name="a37" width="789"/>
- <char name="a38" width="841"/>
- <char name="a39" width="823"/>
- <char name="a40" width="833"/>
- <char name="a41" width="816"/>
- <char name="a42" width="831"/>
- <char name="a43" width="923"/>
- <char name="a44" width="744"/>
- <char name="a45" width="723"/>
- <char name="a46" width="749"/>
- <char name="a47" width="790"/>
- <char name="a48" width="792"/>
- <char name="a49" width="695"/>
- <char name="a50" width="776"/>
- <char name="a51" width="768"/>
- <char name="a52" width="792"/>
- <char name="a53" width="759"/>
- <char name="a54" width="707"/>
- <char name="a55" width="708"/>
- <char name="a56" width="682"/>
- <char name="a57" width="701"/>
- <char name="a58" width="826"/>
- <char name="a59" width="815"/>
- <char name="a60" width="789"/>
- <char name="a61" width="789"/>
- <char name="a62" width="707"/>
- <char name="a63" width="687"/>
- <char name="a64" width="696"/>
- <char name="a65" width="689"/>
- <char name="a66" width="786"/>
- <char name="a67" width="787"/>
- <char name="a68" width="713"/>
- <char name="a69" width="791"/>
- <char name="a70" width="785"/>
- <char name="a71" width="791"/>
- <char name="a72" width="873"/>
- <char name="a73" width="761"/>
- <char name="a74" width="762"/>
- <char name="a203" width="762"/>
- <char name="a75" width="759"/>
- <char name="a204" width="759"/>
- <char name="a76" width="892"/>
- <char name="a77" width="892"/>
- <char name="a78" width="788"/>
- <char name="a79" width="784"/>
- <char name="a81" width="438"/>
- <char name="a82" width="138"/>
- <char name="a83" width="277"/>
- <char name="a84" width="415"/>
- <char name="a97" width="392"/>
- <char name="a98" width="392"/>
- <char name="a99" width="668"/>
- <char name="a100" width="668"/>
- <char name="a101" width="732"/>
- <char name="a102" width="544"/>
- <char name="a103" width="544"/>
- <char name="a104" width="910"/>
- <char name="a106" width="667"/>
- <char name="a107" width="760"/>
- <char name="a108" width="760"/>
- <char name="a112" width="776"/>
- <char name="a111" width="595"/>
- <char name="a110" width="694"/>
- <char name="a109" width="626"/>
- <char name="a120" width="788"/>
- <char name="a121" width="788"/>
- <char name="a122" width="788"/>
- <char name="a123" width="788"/>
- <char name="a124" width="788"/>
- <char name="a125" width="788"/>
- <char name="a126" width="788"/>
- <char name="a127" width="788"/>
- <char name="a128" width="788"/>
- <char name="a129" width="788"/>
- <char name="a130" width="788"/>
- <char name="a131" width="788"/>
- <char name="a132" width="788"/>
- <char name="a133" width="788"/>
- <char name="a134" width="788"/>
- <char name="a135" width="788"/>
- <char name="a136" width="788"/>
- <char name="a137" width="788"/>
- <char name="a138" width="788"/>
- <char name="a139" width="788"/>
- <char name="a140" width="788"/>
- <char name="a141" width="788"/>
- <char name="a142" width="788"/>
- <char name="a143" width="788"/>
- <char name="a144" width="788"/>
- <char name="a145" width="788"/>
- <char name="a146" width="788"/>
- <char name="a147" width="788"/>
- <char name="a148" width="788"/>
- <char name="a149" width="788"/>
- <char name="a150" width="788"/>
- <char name="a151" width="788"/>
- <char name="a152" width="788"/>
- <char name="a153" width="788"/>
- <char name="a154" width="788"/>
- <char name="a155" width="788"/>
- <char name="a156" width="788"/>
- <char name="a157" width="788"/>
- <char name="a158" width="788"/>
- <char name="a159" width="788"/>
- <char name="a160" width="894"/>
- <char name="a161" width="838"/>
- <char name="a163" width="1016"/>
- <char name="a164" width="458"/>
- <char name="a196" width="748"/>
- <char name="a165" width="924"/>
- <char name="a192" width="748"/>
- <char name="a166" width="918"/>
- <char name="a167" width="927"/>
- <char name="a168" width="928"/>
- <char name="a169" width="928"/>
- <char name="a170" width="834"/>
- <char name="a171" width="873"/>
- <char name="a172" width="828"/>
- <char name="a173" width="924"/>
- <char name="a162" width="924"/>
- <char name="a174" width="917"/>
- <char name="a175" width="930"/>
- <char name="a176" width="931"/>
- <char name="a177" width="463"/>
- <char name="a178" width="883"/>
- <char name="a179" width="836"/>
- <char name="a193" width="836"/>
- <char name="a180" width="867"/>
- <char name="a199" width="867"/>
- <char name="a181" width="696"/>
- <char name="a200" width="696"/>
- <char name="a182" width="874"/>
- <char name="a201" width="874"/>
- <char name="a183" width="760"/>
- <char name="a184" width="946"/>
- <char name="a197" width="771"/>
- <char name="a185" width="865"/>
- <char name="a194" width="771"/>
- <char name="a198" width="888"/>
- <char name="a186" width="967"/>
- <char name="a195" width="888"/>
- <char name="a187" width="831"/>
- <char name="a188" width="873"/>
- <char name="a189" width="927"/>
- <char name="a190" width="970"/>
- <char name="a191" width="918"/>
- <char name="a86" width="410"/>
- <char name="a85" width="509"/>
- <char name="a95" width="334"/>
- <char name="a205" width="509"/>
- <char name="a89" width="390"/>
- <char name="a87" width="234"/>
- <char name="a91" width="276"/>
- <char name="a90" width="390"/>
- <char name="a206" width="410"/>
- <char name="a94" width="317"/>
- <char name="a93" width="317"/>
- <char name="a92" width="276"/>
- <char name="a96" width="334"/>
- <char name="a88" width="234"/>
- </widths>
-</font-metrics> \ No newline at end of file
+ <char-metrics>
+ <char name="space" width="278" llx="0" lly="0" urx="0" ury="0"/>
+ <char name="a1" width="974" llx="35" lly="72" urx="939" ury="621"/>
+ <char name="a2" width="961" llx="35" lly="81" urx="927" ury="611"/>
+ <char name="a202" width="974" llx="35" lly="72" urx="939" ury="621"/>
+ <char name="a3" width="980" llx="35" lly="0" urx="945" ury="692"/>
+ <char name="a4" width="719" llx="34" lly="139" urx="685" ury="566"/>
+ <char name="a5" width="789" llx="35" lly="-14" urx="755" ury="705"/>
+ <char name="a119" width="790" llx="35" lly="-14" urx="755" ury="705"/>
+ <char name="a118" width="791" llx="35" lly="-13" urx="761" ury="705"/>
+ <char name="a117" width="690" llx="34" lly="138" urx="655" ury="553"/>
+ <char name="a11" width="960" llx="35" lly="123" urx="925" ury="568"/>
+ <char name="a12" width="939" llx="35" lly="134" urx="904" ury="559"/>
+ <char name="a13" width="549" llx="29" lly="-11" urx="516" ury="705"/>
+ <char name="a14" width="855" llx="34" lly="59" urx="820" ury="632"/>
+ <char name="a15" width="911" llx="35" lly="50" urx="876" ury="642"/>
+ <char name="a16" width="933" llx="35" lly="139" urx="899" ury="550"/>
+ <char name="a105" width="911" llx="35" lly="50" urx="876" ury="642"/>
+ <char name="a17" width="945" llx="35" lly="139" urx="909" ury="553"/>
+ <char name="a18" width="974" llx="35" lly="104" urx="938" ury="587"/>
+ <char name="a19" width="755" llx="34" lly="-13" urx="721" ury="705"/>
+ <char name="a20" width="846" llx="36" lly="-14" urx="811" ury="705"/>
+ <char name="a21" width="762" llx="35" lly="0" urx="727" ury="692"/>
+ <char name="a22" width="761" llx="35" lly="0" urx="727" ury="692"/>
+ <char name="a23" width="571" llx="-1" lly="-68" urx="571" ury="661"/>
+ <char name="a24" width="677" llx="36" lly="-13" urx="642" ury="705"/>
+ <char name="a25" width="763" llx="35" lly="0" urx="728" ury="692"/>
+ <char name="a26" width="760" llx="35" lly="0" urx="726" ury="692"/>
+ <char name="a27" width="759" llx="35" lly="0" urx="725" ury="692"/>
+ <char name="a28" width="754" llx="35" lly="0" urx="720" ury="692"/>
+ <char name="a6" width="494" llx="35" lly="0" urx="460" ury="692"/>
+ <char name="a7" width="552" llx="35" lly="0" urx="517" ury="692"/>
+ <char name="a8" width="537" llx="35" lly="0" urx="503" ury="692"/>
+ <char name="a9" width="577" llx="35" lly="96" urx="542" ury="596"/>
+ <char name="a10" width="692" llx="35" lly="-14" urx="657" ury="705"/>
+ <char name="a29" width="786" llx="35" lly="-14" urx="751" ury="705"/>
+ <char name="a30" width="788" llx="35" lly="-14" urx="752" ury="705"/>
+ <char name="a31" width="788" llx="35" lly="-14" urx="753" ury="705"/>
+ <char name="a32" width="790" llx="35" lly="-14" urx="756" ury="705"/>
+ <char name="a33" width="793" llx="35" lly="-13" urx="759" ury="705"/>
+ <char name="a34" width="794" llx="35" lly="-13" urx="759" ury="705"/>
+ <char name="a35" width="816" llx="35" lly="-14" urx="782" ury="705"/>
+ <char name="a36" width="823" llx="35" lly="-14" urx="787" ury="705"/>
+ <char name="a37" width="789" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a38" width="841" llx="35" lly="-14" urx="807" ury="705"/>
+ <char name="a39" width="823" llx="35" lly="-14" urx="789" ury="705"/>
+ <char name="a40" width="833" llx="35" lly="-14" urx="798" ury="705"/>
+ <char name="a41" width="816" llx="35" lly="-13" urx="782" ury="705"/>
+ <char name="a42" width="831" llx="35" lly="-14" urx="796" ury="705"/>
+ <char name="a43" width="923" llx="35" lly="-14" urx="888" ury="705"/>
+ <char name="a44" width="744" llx="35" lly="0" urx="710" ury="692"/>
+ <char name="a45" width="723" llx="35" lly="0" urx="688" ury="692"/>
+ <char name="a46" width="749" llx="35" lly="0" urx="714" ury="692"/>
+ <char name="a47" width="790" llx="34" lly="-14" urx="756" ury="705"/>
+ <char name="a48" width="792" llx="35" lly="-14" urx="758" ury="705"/>
+ <char name="a49" width="695" llx="35" lly="-14" urx="661" ury="706"/>
+ <char name="a50" width="776" llx="35" lly="-6" urx="741" ury="699"/>
+ <char name="a51" width="768" llx="35" lly="-7" urx="734" ury="699"/>
+ <char name="a52" width="792" llx="35" lly="-14" urx="757" ury="705"/>
+ <char name="a53" width="759" llx="35" lly="0" urx="725" ury="692"/>
+ <char name="a54" width="707" llx="35" lly="-13" urx="672" ury="704"/>
+ <char name="a55" width="708" llx="35" lly="-14" urx="672" ury="705"/>
+ <char name="a56" width="682" llx="35" lly="-14" urx="647" ury="705"/>
+ <char name="a57" width="701" llx="35" lly="-14" urx="666" ury="705"/>
+ <char name="a58" width="826" llx="35" lly="-14" urx="791" ury="705"/>
+ <char name="a59" width="815" llx="35" lly="-14" urx="780" ury="705"/>
+ <char name="a60" width="789" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a61" width="789" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a62" width="707" llx="34" lly="-14" urx="673" ury="705"/>
+ <char name="a63" width="687" llx="36" lly="0" urx="651" ury="692"/>
+ <char name="a64" width="696" llx="35" lly="0" urx="661" ury="691"/>
+ <char name="a65" width="689" llx="35" lly="0" urx="655" ury="692"/>
+ <char name="a66" width="786" llx="34" lly="-14" urx="751" ury="705"/>
+ <char name="a67" width="787" llx="35" lly="-14" urx="752" ury="705"/>
+ <char name="a68" width="713" llx="35" lly="-14" urx="678" ury="705"/>
+ <char name="a69" width="791" llx="35" lly="-14" urx="756" ury="705"/>
+ <char name="a70" width="785" llx="36" lly="-14" urx="751" ury="705"/>
+ <char name="a71" width="791" llx="35" lly="-14" urx="757" ury="705"/>
+ <char name="a72" width="873" llx="35" lly="-14" urx="838" ury="705"/>
+ <char name="a73" width="761" llx="35" lly="0" urx="726" ury="692"/>
+ <char name="a74" width="762" llx="35" lly="0" urx="727" ury="692"/>
+ <char name="a203" width="762" llx="35" lly="0" urx="727" ury="692"/>
+ <char name="a75" width="759" llx="35" lly="0" urx="725" ury="692"/>
+ <char name="a204" width="759" llx="35" lly="0" urx="725" ury="692"/>
+ <char name="a76" width="892" llx="35" lly="0" urx="858" ury="705"/>
+ <char name="a77" width="892" llx="35" lly="-14" urx="858" ury="692"/>
+ <char name="a78" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a79" width="784" llx="35" lly="-14" urx="749" ury="705"/>
+ <char name="a81" width="438" llx="35" lly="-14" urx="403" ury="705"/>
+ <char name="a82" width="138" llx="35" lly="0" urx="104" ury="692"/>
+ <char name="a83" width="277" llx="35" lly="0" urx="242" ury="692"/>
+ <char name="a84" width="415" llx="35" lly="0" urx="380" ury="692"/>
+ <char name="a97" width="392" llx="35" lly="263" urx="357" ury="705"/>
+ <char name="a98" width="392" llx="34" lly="263" urx="357" ury="705"/>
+ <char name="a99" width="668" llx="35" lly="263" urx="633" ury="705"/>
+ <char name="a100" width="668" llx="36" lly="263" urx="634" ury="705"/>
+ <char name="a101" width="732" llx="35" lly="-143" urx="697" ury="806"/>
+ <char name="a102" width="544" llx="56" lly="-14" urx="488" ury="706"/>
+ <char name="a103" width="544" llx="34" lly="-14" urx="508" ury="705"/>
+ <char name="a104" width="910" llx="35" lly="40" urx="875" ury="651"/>
+ <char name="a106" width="667" llx="35" lly="-14" urx="633" ury="705"/>
+ <char name="a107" width="760" llx="35" lly="-14" urx="726" ury="705"/>
+ <char name="a108" width="760" llx="0" lly="121" urx="758" ury="569"/>
+ <char name="a112" width="776" llx="35" lly="0" urx="741" ury="705"/>
+ <char name="a111" width="595" llx="34" lly="-14" urx="560" ury="705"/>
+ <char name="a110" width="694" llx="35" lly="-14" urx="659" ury="705"/>
+ <char name="a109" width="626" llx="34" lly="0" urx="591" ury="705"/>
+ <char name="a120" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a121" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a122" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a123" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a124" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a125" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a126" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a127" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a128" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a129" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a130" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a131" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a132" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a133" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a134" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a135" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a136" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a137" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a138" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a139" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a140" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a141" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a142" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a143" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a144" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a145" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a146" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a147" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a148" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a149" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a150" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a151" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a152" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a153" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a154" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a155" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a156" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a157" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a158" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a159" width="788" llx="35" lly="-14" urx="754" ury="705"/>
+ <char name="a160" width="894" llx="35" lly="58" urx="860" ury="634"/>
+ <char name="a161" width="838" llx="35" lly="152" urx="803" ury="540"/>
+ <char name="a163" width="1016" llx="34" lly="152" urx="981" ury="540"/>
+ <char name="a164" width="458" llx="35" lly="-127" urx="422" ury="820"/>
+ <char name="a196" width="748" llx="35" lly="94" urx="698" ury="597"/>
+ <char name="a165" width="924" llx="35" lly="140" urx="890" ury="552"/>
+ <char name="a192" width="748" llx="35" lly="94" urx="698" ury="597"/>
+ <char name="a166" width="918" llx="35" lly="166" urx="884" ury="526"/>
+ <char name="a167" width="927" llx="35" lly="32" urx="892" ury="660"/>
+ <char name="a168" width="928" llx="35" lly="129" urx="891" ury="562"/>
+ <char name="a169" width="928" llx="35" lly="128" urx="893" ury="563"/>
+ <char name="a170" width="834" llx="35" lly="155" urx="799" ury="537"/>
+ <char name="a171" width="873" llx="35" lly="93" urx="838" ury="599"/>
+ <char name="a172" width="828" llx="35" lly="104" urx="791" ury="588"/>
+ <char name="a173" width="924" llx="35" lly="98" urx="889" ury="594"/>
+ <char name="a162" width="924" llx="35" lly="98" urx="889" ury="594"/>
+ <char name="a174" width="917" llx="35" lly="0" urx="882" ury="692"/>
+ <char name="a175" width="930" llx="35" lly="84" urx="896" ury="608"/>
+ <char name="a176" width="931" llx="35" lly="84" urx="896" ury="608"/>
+ <char name="a177" width="463" llx="35" lly="-99" urx="429" ury="791"/>
+ <char name="a178" width="883" llx="35" lly="71" urx="848" ury="623"/>
+ <char name="a179" width="836" llx="35" lly="44" urx="802" ury="648"/>
+ <char name="a193" width="836" llx="35" lly="44" urx="802" ury="648"/>
+ <char name="a180" width="867" llx="35" lly="101" urx="832" ury="591"/>
+ <char name="a199" width="867" llx="35" lly="101" urx="832" ury="591"/>
+ <char name="a181" width="696" llx="35" lly="44" urx="661" ury="648"/>
+ <char name="a200" width="696" llx="35" lly="44" urx="661" ury="648"/>
+ <char name="a182" width="874" llx="35" lly="77" urx="840" ury="619"/>
+ <char name="a201" width="874" llx="35" lly="73" urx="840" ury="615"/>
+ <char name="a183" width="760" llx="35" lly="0" urx="725" ury="692"/>
+ <char name="a184" width="946" llx="35" lly="160" urx="911" ury="533"/>
+ <char name="a197" width="771" llx="34" lly="37" urx="736" ury="655"/>
+ <char name="a185" width="865" llx="35" lly="207" urx="830" ury="481"/>
+ <char name="a194" width="771" llx="34" lly="37" urx="736" ury="655"/>
+ <char name="a198" width="888" llx="34" lly="-19" urx="853" ury="712"/>
+ <char name="a186" width="967" llx="35" lly="124" urx="932" ury="568"/>
+ <char name="a195" width="888" llx="34" lly="-19" urx="853" ury="712"/>
+ <char name="a187" width="831" llx="35" lly="113" urx="796" ury="579"/>
+ <char name="a188" width="873" llx="36" lly="118" urx="838" ury="578"/>
+ <char name="a189" width="927" llx="35" lly="150" urx="891" ury="542"/>
+ <char name="a190" width="970" llx="35" lly="76" urx="931" ury="616"/>
+ <char name="a191" width="918" llx="34" lly="99" urx="884" ury="593"/>
+ <char name="a86" width="410" llx="35" lly="0" urx="375" ury="692"/>
+ <char name="a85" width="509" llx="35" lly="0" urx="475" ury="692"/>
+ <char name="a95" width="334" llx="35" lly="0" urx="299" ury="692"/>
+ <char name="a205" width="509" llx="35" lly="0" urx="475" ury="692"/>
+ <char name="a89" width="390" llx="35" lly="-14" urx="356" ury="705"/>
+ <char name="a87" width="234" llx="35" lly="-14" urx="199" ury="705"/>
+ <char name="a91" width="276" llx="35" lly="0" urx="242" ury="692"/>
+ <char name="a90" width="390" llx="35" lly="-14" urx="355" ury="705"/>
+ <char name="a206" width="410" llx="35" lly="0" urx="375" ury="692"/>
+ <char name="a94" width="317" llx="35" lly="0" urx="283" ury="692"/>
+ <char name="a93" width="317" llx="35" lly="0" urx="283" ury="692"/>
+ <char name="a92" width="276" llx="35" lly="0" urx="242" ury="692"/>
+ <char name="a96" width="334" llx="35" lly="0" urx="299" ury="692"/>
+ <char name="a88" width="234" llx="35" lly="-14" urx="199" ury="705"/>
+ </char-metrics>
+</font-metrics>
diff --git a/src/codegen/fonts/font-file.xsl b/src/codegen/fonts/font-file.xsl
index 85b968808..8723ed960 100644
--- a/src/codegen/fonts/font-file.xsl
+++ b/src/codegen/fonts/font-file.xsl
@@ -35,6 +35,7 @@
<xsl:template match="font-metrics">
package org.apache.fop.fonts.base14;
+import java.awt.Rectangle;
<xsl:if test="count(kerning) &gt; 0">
import java.util.Map;
</xsl:if>
@@ -42,12 +43,14 @@ import java.util.Set;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.Base14Font;
import org.apache.fop.fonts.CodePointMapping;
-import org.apache.fop.fonts.Typeface;;
+import org.apache.fop.fonts.Typeface;
public class <xsl:value-of select="class-name"/> extends Base14Font {
private final static String fontName = "<xsl:value-of select="font-name"/>";
private final static String fullName = "<xsl:value-of select="full-name"/>";
private final static Set familyNames;
+ private final static int underlinePosition = <xsl:value-of select="underline-position"/>;
+ private final static int underlineThickness = <xsl:value-of select="underline-thickness"/>;
private final static String encoding = "<xsl:value-of select="$encoding"/>";
private final static int capHeight = <xsl:value-of select="cap-height"/>;
private final static int xHeight = <xsl:value-of select="x-height"/>;
@@ -56,6 +59,7 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
private final static int firstChar = <xsl:value-of select="first-char"/>;
private final static int lastChar = <xsl:value-of select="last-char"/>;
private final static int[] width;
+ private final static Rectangle[] boundingBoxes;
private final CodePointMapping mapping =
CodePointMapping.getMapping("<xsl:value-of select="$encoding"/>");
<xsl:if test="count(kerning) &gt; 0">
@@ -66,7 +70,8 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
static {
width = new int[256];
- <xsl:apply-templates select="widths"/>
+ boundingBoxes = new Rectangle[256];
+ <xsl:apply-templates select="char-metrics"/>
<xsl:if test="count(kerning) &gt; 0">
kerning = new java.util.HashMap();
Integer first, second;
@@ -125,6 +130,14 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
return size * xHeight;
}
+ public int getUnderlinePosition(int size) {
+ return size * underlinePosition;
+ }
+
+ public int getUnderlineThickness(int size) {
+ return size * underlineThickness;
+ }
+
public int getFirstChar() {
return firstChar;
}
@@ -137,6 +150,11 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
return size * width[i];
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ Rectangle bbox = boundingBoxes[glyphIndex];
+ return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
+ }
+
public int[] getWidths() {
int[] arr = new int[getLastChar() - getFirstChar() + 1];
System.arraycopy(width, getFirstChar(), arr, 0, getLastChar() - getFirstChar() + 1);
@@ -182,7 +200,9 @@ public class <xsl:value-of select="class-name"/> extends Base14Font {
}
</xsl:template>
- <xsl:template match="widths/char"><xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;</xsl:if></xsl:template>
+ <xsl:template match="char-metrics/char">
+ <xsl:variable name="char-name" select="@name"/><xsl:variable name="char-num" select="$glyphs[@name = $char-name]/@codepoint"/><xsl:if test="$char-num!=''"> width[0x<xsl:value-of select="$char-num"/>] = <xsl:value-of select="@width"/>;
+ boundingBoxes[0x<xsl:value-of select="$char-num"/>] = new Rectangle(<xsl:value-of select="@llx"/>,<xsl:value-of select="@lly"/>,<xsl:value-of select="@urx - @llx"/>,<xsl:value-of select="@ury - @lly"/>);</xsl:if></xsl:template>
<xsl:template match="kerning">
first = new Integer(<xsl:value-of select="@kpx1"/>);
diff --git a/src/java/org/apache/fop/Version.java b/src/java/org/apache/fop/Version.java
index 86861a60b..a8903c74e 100644
--- a/src/java/org/apache/fop/Version.java
+++ b/src/java/org/apache/fop/Version.java
@@ -40,8 +40,9 @@ public final class Version {
}
if (version == null) {
//Fallback if FOP is used in a development environment
- String headURL
- = "$HeadURL$";
+ // CSOFF: LineLength
+ String headURL = "$HeadURL$";
+ // CSON: LineLength
version = headURL;
final String pathPrefix = "/xmlgraphics/fop/";
int pos = version.indexOf(pathPrefix);
diff --git a/src/java/org/apache/fop/afp/AFPEventProducer.java b/src/java/org/apache/fop/afp/AFPEventProducer.java
index 01d5c4ad7..1b43400c5 100644
--- a/src/java/org/apache/fop/afp/AFPEventProducer.java
+++ b/src/java/org/apache/fop/afp/AFPEventProducer.java
@@ -122,4 +122,12 @@ public interface AFPEventProducer extends EventProducer {
* @event.severity WARN
*/
void charactersetMissingMetrics(Object source, char character, String charSet);
+
+ /**
+ * Double-byte fonts are not currently supported in SVG.
+ * @param source the event source
+ * @param fontFamily name of DB font
+ * @event.severity WARN
+ */
+ void invalidDBFontInSVG(Object source, String fontFamily);
}
diff --git a/src/java/org/apache/fop/afp/fonts/AFPFont.java b/src/java/org/apache/fop/afp/fonts/AFPFont.java
index 06f484f37..99e15a46b 100644
--- a/src/java/org/apache/fop/afp/fonts/AFPFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AFPFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -34,6 +35,8 @@ import org.apache.fop.fonts.Typeface;
*/
public abstract class AFPFont extends Typeface {
+ private static final double STRIKEOUT_POSITION_FACTOR = 0.45;
+
/** The font name */
protected final String name;
@@ -117,7 +120,34 @@ public abstract class AFPFont extends Typeface {
*/
protected static final char toUnicodeCodepoint(int character) {
//AFP fonts use Unicode directly as their mapped code points, so we can simply cast to char
- return (char)character;
+ return (char) character;
+ }
+
+ /** {@inheritDoc} */
+ public int getUnderlineThickness(int size) {
+ // This is the FOCA recommendation in the absence of the Underline Thickness parameter
+ return getBoundingBox('-', size).height;
+ }
+
+ /** {@inheritDoc} */
+ public int getStrikeoutPosition(int size) {
+ //TODO This conflicts with the FOCA recommendation of 0 in the absence of the Throughscore Position
+ // parameter
+ return (int) (STRIKEOUT_POSITION_FACTOR * getCapHeight(size));
+ }
+
+ /** {@inheritDoc} */
+ public int getStrikeoutThickness(int size) {
+ // This is the FOCA recommendation in the absence of the Throughscore Thickness parameter
+ return getBoundingBox('-', size).height;
+ }
+
+ /** {@inheritDoc} */
+ public abstract Rectangle getBoundingBox(int glyphIndex, int size);
+
+ /** {@inheritDoc} */
+ public int[] getWidths() {
+ throw new UnsupportedOperationException();
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
index 7b57a2b8c..edbdf5e95 100644
--- a/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/AbstractOutlineFont.java
@@ -71,22 +71,6 @@ public abstract class AbstractOutlineFont extends AFPFont {
}
/**
- * Get the first character in this font.
- * @return the first character in this font
- */
- public int getFirstChar() {
- return charSet.getFirstChar();
- }
-
- /**
- * Get the last character in this font.
- * @return the last character in this font
- */
- public int getLastChar() {
- return charSet.getLastChar();
- }
-
- /**
* The ascender is the part of a lowercase letter that extends above the
* "x-height" (the height of the letter "x"), such as "d", "t", or "h". Also
* used to denote the part of the letter extending above the x-height.
@@ -98,6 +82,17 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getAscender() * size;
}
+ /** {@inheritDoc} */
+ public int getUnderlinePosition(int size) {
+ return charSet.getUnderscorePosition() * size;
+ }
+
+ @Override
+ public int getUnderlineThickness(int size) {
+ int underscoreWidth = charSet.getUnderscoreWidth();
+ return underscoreWidth == 0 ? super.getUnderlineThickness(size) : underscoreWidth * size;
+ }
+
/**
* Obtains the height of capital letters for the specified point size.
*
@@ -130,40 +125,7 @@ public abstract class AbstractOutlineFont extends AFPFont {
return charSet.getXHeight() * size;
}
- /**
- * Obtain the width of the character for the specified point size.
- * @param character the character
- * @param size the font size (in mpt)
- * @return the width of the character for the specified point size
- */
- public int getWidth(int character, int size) {
- return charSet.getWidth(toUnicodeCodepoint(character)) * size;
- }
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size the font size (in mpt)
- * @return the widths of all characters
- */
- public int[] getWidths(int size) {
- int[] widths = charSet.getWidths();
- for (int i = 0; i < widths.length; i++) {
- widths[i] = widths[i] * size;
- }
- return widths;
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return getWidths(1000);
- }
/** {@inheritDoc} */
public boolean hasChar(char c) {
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index e0c3b9c9a..3df8ba4c4 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -19,10 +19,9 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.io.UnsupportedEncodingException;
import java.nio.charset.CharacterCodingException;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -63,6 +62,8 @@ public class CharacterSet {
private static final int MAX_NAME_LEN = 8;
+ /** The current orientation (currently only 0 is supported by FOP) */
+ public static final int SUPPORTED_ORIENTATION = 0;
/** The code page to which the character set relates */
protected final String codePage;
@@ -79,11 +80,8 @@ public class CharacterSet {
/** The path to the installed fonts */
private final AFPResourceAccessor accessor;
- /** The current orientation (currently only 0 is supported by FOP) */
- private final String currentOrientation = "0";
-
/** The collection of objects for each orientation */
- private final Map<String, CharacterSetOrientation> characterSetOrientations;
+ private CharacterSetOrientation characterSetOrientation;
/** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */
private int nominalVerticalSize;
@@ -116,8 +114,6 @@ public class CharacterSet {
this.encoding = encoding;
this.encoder = charsetType.getEncoder(encoding);
this.accessor = accessor;
-
- this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
}
// right pad short names with space
@@ -131,7 +127,9 @@ public class CharacterSet {
* @param cso the metrics for the orientation
*/
public void addCharacterSetOrientation(CharacterSetOrientation cso) {
- characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso);
+ if (cso.getOrientation() == SUPPORTED_ORIENTATION) {
+ characterSetOrientation = cso;
+ }
}
/**
@@ -165,11 +163,24 @@ public class CharacterSet {
* @return the ascender value in millipoints
*/
public int getAscender() {
-
return getCharacterSetOrientation().getAscender();
}
/**
+ * TODO
+ */
+ public int getUnderscoreWidth() {
+ return getCharacterSetOrientation().getUnderscoreWidth();
+ }
+
+ /**
+ * TODO
+ */
+ public int getUnderscorePosition() {
+ return getCharacterSetOrientation().getUnderscorePosition();
+ }
+
+ /**
* Cap height is the average height of the uppercase characters in
* a font. This value is specified by the designer of a font and is
* usually the height of the uppercase M.
@@ -177,7 +188,6 @@ public class CharacterSet {
* @return the cap height value in millipoints
*/
public int getCapHeight() {
-
return getCharacterSetOrientation().getCapHeight();
}
@@ -194,24 +204,6 @@ public class CharacterSet {
}
/**
- * Returns the first character in the character set
- *
- * @return the first character in the character set (Unicode codepoint)
- */
- public char getFirstChar() {
- return getCharacterSetOrientation().getFirstChar();
- }
-
- /**
- * Returns the last character in the character set
- *
- * @return the last character in the character set (Unicode codepoint)
- */
- public char getLastChar() {
- return getCharacterSetOrientation().getLastChar();
- }
-
- /**
* Returns the resource accessor to load the font resources with.
* @return the resource accessor to load the font resources with
*/
@@ -220,16 +212,6 @@ public class CharacterSet {
}
/**
- * Get the width (in 1/1000ths of a point size) of all characters
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
-
- return getCharacterSetOrientation().getWidths();
- }
-
- /**
* XHeight refers to the height of the lower case letters above the baseline.
*
* @return the typical height of characters
@@ -246,11 +228,13 @@ public class CharacterSet {
* @param character the Unicode character from which the width will be calculated
* @return the width of the character
*/
- public int getWidth(char character) {
- return getCharacterSetOrientation().getWidth(character);
+ public int getWidth(char character, int size) {
+ return getCharacterSetOrientation().getWidth(character, size);
}
-
+ public Rectangle getCharacterBox(char character, int size) {
+ return getCharacterSetOrientation().getCharacterBox(character, size);
+ }
/**
* Returns the AFP character set identifier
@@ -309,9 +293,7 @@ public class CharacterSet {
* @return characterSetOrentation The current orientation metrics.
*/
private CharacterSetOrientation getCharacterSetOrientation() {
- CharacterSetOrientation c
- = characterSetOrientations.get(currentOrientation);
- return c;
+ return characterSetOrientation;
}
/**
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index 2565942b5..a3b2ab8ec 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -292,16 +293,14 @@ public abstract class CharacterSetBuilder {
metricNormalizationFactor = 1000.0d * 72000.0d
/ fontDescriptor.getNominalFontSizeInMillipoints() / dpi;
}
-
+ ValueNormalizer normalizer = new ValueNormalizer(metricNormalizationFactor);
//process D3AC89 Font Position
- processFontPosition(structuredFieldReader, characterSetOrientations,
- metricNormalizationFactor);
-
+ processFontPosition(structuredFieldReader, characterSetOrientations, normalizer);
//process D38C89 Font Index (per orientation)
for (int i = 0; i < characterSetOrientations.length; i++) {
- processFontIndex(structuredFieldReader,
- characterSetOrientations[i], codePage, metricNormalizationFactor);
- characterSet.addCharacterSetOrientation(characterSetOrientations[i]);
+ CharacterSetOrientation characterSetOrientation = characterSetOrientations[i];
+ processFontIndex(structuredFieldReader, characterSetOrientation, codePage, normalizer);
+ characterSet.addCharacterSetOrientation(characterSetOrientation);
}
} else {
throw new IOException("Missing D3AE89 Font Control structured field.");
@@ -314,6 +313,19 @@ public abstract class CharacterSetBuilder {
return characterSet;
}
+ private static class ValueNormalizer {
+
+ private final double factor;
+
+ public ValueNormalizer(double factor) {
+ this.factor = factor;
+ }
+
+ public int normalize(int value) {
+ return (int) Math.round(value * factor);
+ }
+ }
+
/**
* Load the code page information from the appropriate file. The file name
* to load is determined by the code page name and the file extension 'CDP'.
@@ -475,7 +487,7 @@ public abstract class CharacterSetBuilder {
* @throws IOException if an I/O exception of some sort has occurred.
*/
private void processFontPosition(StructuredFieldReader structuredFieldReader,
- CharacterSetOrientation[] characterSetOrientations, double metricNormalizationFactor)
+ CharacterSetOrientation[] characterSetOrientations, ValueNormalizer normalizer)
throws IOException {
byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF);
@@ -493,48 +505,34 @@ public abstract class CharacterSetBuilder {
if (position == 9) {
CharacterSetOrientation characterSetOrientation
= characterSetOrientations[characterSetOrientationIndex];
-
int xHeight = getSBIN(fpData, 2);
int capHeight = getSBIN(fpData, 4);
int ascHeight = getSBIN(fpData, 6);
int dscHeight = getSBIN(fpData, 8);
-
dscHeight = dscHeight * -1;
-
- characterSetOrientation.setXHeight(
- (int)Math.round(xHeight * metricNormalizationFactor));
- characterSetOrientation.setCapHeight(
- (int)Math.round(capHeight * metricNormalizationFactor));
- characterSetOrientation.setAscender(
- (int)Math.round(ascHeight * metricNormalizationFactor));
- characterSetOrientation.setDescender(
- (int)Math.round(dscHeight * metricNormalizationFactor));
+ int underscoreWidth = getUBIN(fpData, 17);
+ int underscorePosition = getSBIN(fpData, 20);
+ characterSetOrientation.setXHeight(normalizer.normalize(xHeight));
+ characterSetOrientation.setCapHeight(normalizer.normalize(capHeight));
+ characterSetOrientation.setAscender(normalizer.normalize(ascHeight));
+ characterSetOrientation.setDescender(normalizer.normalize(dscHeight));
+ characterSetOrientation.setUnderscoreWidth(normalizer.normalize(underscoreWidth));
+ characterSetOrientation.setUnderscorePosition(normalizer.normalize(underscorePosition));
}
} else if (position == 22) {
position = 0;
characterSetOrientationIndex++;
fpData[position] = data[index];
}
-
position++;
}
}
- /**
- * Process the font index details for the character set orientation.
- *
- * @param structuredFieldReader the structured field reader
- * @param cso the CharacterSetOrientation object to populate
- * @param codepage the map of code pages
- * @param metricNormalizationFactor factor to apply to the metrics to get normalized
- * font metric values
- * @throws IOException if an I/O exception of some sort has occurred.
- */
- private void processFontIndex(StructuredFieldReader structuredFieldReader,
- CharacterSetOrientation cso, Map<String, String> codepage,
- double metricNormalizationFactor)
- throws IOException {
+
+ private void processFontIndex(StructuredFieldReader structuredFieldReader, CharacterSetOrientation cso,
+ Map<String, String> codepage, ValueNormalizer normalizer)
+ throws IOException {
byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF);
@@ -543,8 +541,6 @@ public abstract class CharacterSetBuilder {
byte[] gcgid = new byte[8];
byte[] fiData = new byte[20];
- char lowest = 255;
- char highest = 0;
String firstABCMismatch = null;
// Read data, ignoring bytes 0 - 2
@@ -569,13 +565,15 @@ public abstract class CharacterSetBuilder {
char cidx = idx.charAt(0);
int width = getUBIN(fiData, 0);
+ int ascendHt = getSBIN(fiData, 2);
+ int descendDp = getSBIN(fiData, 4);
int a = getSBIN(fiData, 10);
int b = getUBIN(fiData, 12);
int c = getSBIN(fiData, 14);
int abc = a + b + c;
int diff = Math.abs(abc - width);
if (diff != 0 && width != 0) {
- double diffPercent = 100 * diff / (double)width;
+ double diffPercent = 100 * diff / (double) width;
if (diffPercent > 2) {
if (LOG.isTraceEnabled()) {
LOG.trace(gcgiString + ": "
@@ -587,27 +585,16 @@ public abstract class CharacterSetBuilder {
}
}
}
-
- if (cidx < lowest) {
- lowest = cidx;
- }
-
- if (cidx > highest) {
- highest = cidx;
- }
-
- int normalizedWidth = (int)Math.round(width * metricNormalizationFactor);
-
- cso.setWidth(cidx, normalizedWidth);
-
+ int normalizedWidth = normalizer.normalize(width);
+ int x0 = normalizer.normalize(a);
+ int y0 = normalizer.normalize(-descendDp);
+ int dx = normalizer.normalize(b);
+ int dy = normalizer.normalize(ascendHt + descendDp);
+ cso.setCharacterMetrics(cidx, normalizedWidth, new Rectangle(x0, y0, dx, dy));
}
-
}
}
- cso.setFirstChar(lowest);
- cso.setLastChar(highest);
-
if (LOG.isDebugEnabled() && firstABCMismatch != null) {
//Debug level because it usually is no problem.
LOG.debug("Font has metrics inconsitencies where A+B+C doesn't equal the"
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
index a730525d2..5fe524536 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetOrientation.java
@@ -19,7 +19,7 @@
package org.apache.fop.afp.fonts;
-import java.util.Arrays;
+import java.awt.Rectangle;
/**
* The IBM Font Object Content Architecture (FOCA) supports presentation
@@ -60,23 +60,13 @@ public class CharacterSetOrientation {
/**
* The character widths in the character set (indexed using Unicode codepoints)
*/
- private int[] charsWidths;
+ private IntegerKeyStore<CharacterMetrics> characterMetrics;
/**
* The height of lowercase letters
*/
private int xHeight;
- /**
- * The first character (Unicode codepoint)
- */
- private char firstChar;
-
- /**
- * The last character (Unicode codepoint)
- */
- private char lastChar;
-
/** The character set orientation */
private final int orientation;
/** space increment */
@@ -86,6 +76,10 @@ public class CharacterSetOrientation {
/** Nominal Character Increment */
private final int nomCharIncrement;
+ private int underscoreWidth;
+
+ private int underscorePosition;
+
/**
* Constructor for the CharacterSetOrientation, the orientation is
* expressed as the degrees rotation (i.e 0, 90, 180, 270)
@@ -97,8 +91,7 @@ public class CharacterSetOrientation {
this.spaceIncrement = spaceIncrement;
this.emSpaceIncrement = emSpaceIncrement;
this.nomCharIncrement = nomCharIncrement;
- charsWidths = new int[256];
- Arrays.fill(charsWidths, -1);
+ this.characterMetrics = new IntegerKeyStore<CharacterMetrics>();
}
/**
@@ -138,19 +131,17 @@ public class CharacterSetOrientation {
}
/**
- * The first character in the character set
- * @return the first character (Unicode codepoint)
+ * TODO
*/
- public char getFirstChar() {
- return firstChar;
+ public int getUnderscoreWidth() {
+ return underscoreWidth;
}
/**
- * The last character in the character set
- * @return the last character (Unicode codepoint)
+ * TODO
*/
- public char getLastChar() {
- return lastChar;
+ public int getUnderscorePosition() {
+ return underscorePosition;
}
/**
@@ -162,17 +153,6 @@ public class CharacterSetOrientation {
}
/**
- * Get the width (in 1/1000ths of a point size) of all characters
- * in this character set.
- * @return the widths of all characters
- */
- public int[] getWidths() {
- int[] arr = new int[(getLastChar() - getFirstChar()) + 1];
- System.arraycopy(charsWidths, getFirstChar(), arr, 0, (getLastChar() - getFirstChar()) + 1);
- return arr;
- }
-
- /**
* XHeight refers to the height of the lower case letters above
* the baseline.
* @return heightX the typical height of characters
@@ -187,13 +167,38 @@ public class CharacterSetOrientation {
* @param character the Unicode character to evaluate
* @return the widths of the character
*/
- public int getWidth(char character) {
- if (character >= charsWidths.length) {
- throw new IllegalArgumentException("Invalid character: "
- + character + " (" + Integer.toString(character)
- + "), maximum is " + (charsWidths.length - 1));
+ public int getWidth(char character, int size) {
+ CharacterMetrics cm = getCharacterMetrics(character);
+ return cm == null ? -1 : size * cm.width;
+ }
+
+ private CharacterMetrics getCharacterMetrics(char character) {
+ return characterMetrics.get((int) character);
+ }
+
+ /**
+ * Get the character box (rectangle with dimensions in 1/1000ths of a point size) of the character
+ * identified by the parameter passed.
+ * @param character the Unicode character to evaluate
+ * @return the character box
+ */
+ public Rectangle getCharacterBox(char character, int size) {
+ CharacterMetrics cm = getCharacterMetrics(character);
+ return scale(cm == null ? getFallbackCharacterBox() : cm.characterBox, size);
+ }
+
+ private static Rectangle scale(Rectangle rectangle, int size) {
+ if (rectangle == null) {
+ return null;
+ } else {
+ return new Rectangle((int) (size * rectangle.getX()), (int) (size * rectangle.getY()),
+ (int) (size * rectangle.getWidth()), (int) (size * rectangle.getHeight()));
}
- return charsWidths[character];
+ }
+
+ private Rectangle getFallbackCharacterBox() {
+ // TODO replace with something sensible
+ return new Rectangle(0, 0, 0, 0);
}
/**
@@ -233,19 +238,19 @@ public class CharacterSetOrientation {
}
/**
- * The first character in the character set
- * @param firstChar the first character
+ * TODO
+ * @param underscoreWidth the underscore width value in millipoints
*/
- public void setFirstChar(char firstChar) {
- this.firstChar = firstChar;
+ public void setUnderscoreWidth(int underscoreWidth) {
+ this.underscoreWidth = underscoreWidth;
}
/**
- * The last character in the character set
- * @param lastChar the last character
+ * TODO
+ * @param underscorePosition the underscore position value in millipoints
*/
- public void setLastChar(char lastChar) {
- this.lastChar = lastChar;
+ public void setUnderscorePosition(int underscorePosition) {
+ this.underscorePosition = underscorePosition;
}
/**
@@ -254,17 +259,8 @@ public class CharacterSetOrientation {
* @param character the Unicode character for which the width is being set
* @param width the widths of the character
*/
- public void setWidth(char character, int width) {
- if (character >= charsWidths.length) {
- // Increase the size of the array if necessary
- // TODO Can we remove firstChar? surely firstChar==0 at this stage?
- int[] arr = new int[(character - firstChar) + 1];
- System.arraycopy(charsWidths, 0, arr, 0, charsWidths.length);
- Arrays.fill(arr, charsWidths.length, character - firstChar, -1);
- charsWidths = arr;
- }
- charsWidths[character] = width;
-
+ public void setCharacterMetrics(char character, int width, Rectangle characterBox) {
+ characterMetrics.put((int) character, new CharacterMetrics(width, characterBox));
}
/**
@@ -299,4 +295,16 @@ public class CharacterSetOrientation {
public int getNominalCharIncrement() {
return this.nomCharIncrement;
}
+
+ private static class CharacterMetrics {
+
+ public final int width;
+
+ public final Rectangle characterBox;
+
+ public CharacterMetrics(int width, Rectangle characterBox) {
+ this.width = width;
+ this.characterBox = characterBox;
+ }
+ }
}
diff --git a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
index 78da6ea82..5b9bf6101 100644
--- a/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
+++ b/src/java/org/apache/fop/afp/fonts/DoubleByteFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.lang.Character.UnicodeBlock;
import java.util.HashSet;
import java.util.Set;
@@ -68,7 +69,7 @@ public class DoubleByteFont extends AbstractOutlineFont {
public int getWidth(int character, int size) {
int charWidth;
try {
- charWidth = charSet.getWidth(toUnicodeCodepoint(character));
+ charWidth = charSet.getWidth(toUnicodeCodepoint(character), size);
} catch (IllegalArgumentException e) {
if (!charsProcessed.contains(character)) {
charsProcessed.add(character);
@@ -80,9 +81,9 @@ public class DoubleByteFont extends AbstractOutlineFont {
}
if (charWidth == -1) {
- charWidth = getDefaultCharacterWidth(character);
+ charWidth = getDefaultCharacterWidth(character) * size;
}
- return charWidth * size;
+ return charWidth;
}
private int getDefaultCharacterWidth(int character) {
@@ -94,6 +95,33 @@ public class DoubleByteFont extends AbstractOutlineFont {
}
}
+ @Override
+ public Rectangle getBoundingBox(int character, int size) {
+ Rectangle characterBox = getBoundingBoxOrNull(character, size);
+ if (characterBox == null) {
+ characterBox = getDefaultCharacterBox(character, size);
+ }
+ return characterBox;
+ }
+
+ private Rectangle getBoundingBoxOrNull(int character, int size) {
+ Rectangle characterBox = null;
+ try {
+ characterBox = charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+ } catch (IllegalArgumentException e) {
+ if (!charsProcessed.contains(character)) {
+ charsProcessed.add(character);
+ getAFPEventProducer().charactersetMissingMetrics(this, (char) character,
+ charSet.getName().trim());
+ }
+ }
+ return characterBox;
+ }
+
+ private Rectangle getDefaultCharacterBox(int character, int size) {
+ return getBoundingBoxOrNull('-', size);
+ }
+
private int inferCharWidth(int character) {
//Is this character an ideograph?
diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
index 7c2b68506..b729a8995 100644
--- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
+
import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.fonts.Typeface;
@@ -84,45 +86,31 @@ public class FopCharacterSet extends CharacterSet {
}
/**
- * The first character in the character set
- * @return the first character
+ * XHeight refers to the height of the lower case letters above the baseline.
+ * @return the typical height of characters
*/
- public char getFirstChar() {
- return 0;
+ public int getXHeight() {
+ return charSet.getXHeight(1);
}
- /**
- * The last character in the character set
- * @return the last character
- */
- public char getLastChar() {
- return 0;
+ @Override
+ public int getWidth(char character, int size) {
+ return charSet.getWidth(character, size);
}
- /**
- * Get the width (in 1/1000ths of a point size) of all characters
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return charSet.getWidths();
- }
+ @Override
+ public Rectangle getCharacterBox(char character, int size) {
+ return charSet.getBoundingBox(character, size);
+ };
- /**
- * XHeight refers to the height of the lower case letters above the baseline.
- * @return the typical height of characters
- */
- public int getXHeight() {
- return charSet.getXHeight(1);
+ @Override
+ public int getUnderscoreWidth() {
+ return charSet.getUnderlineThickness(1);
}
- /**
- * Get the width (in 1/1000ths of a point size) of the character
- * identified by the parameter passed.
- * @param character the character from which the width will be calculated
- * @return the width of the character
- */
- public int getWidth(char character) {
- return charSet.getWidth(character, 1);
+ @Override
+ public int getUnderscorePosition() {
+ return charSet.getUnderlinePosition(1);
}
/**
diff --git a/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java
new file mode 100644
index 000000000..7e73b5b9f
--- /dev/null
+++ b/src/java/org/apache/fop/afp/fonts/IntegerKeyStore.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.afp.fonts;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A simple compact data structure to model a sparse array
+ */
+class IntegerKeyStore<T> {
+
+ private static final int RANGE_BIT_SIZE = 8;
+
+ private static final int RANGE_SIZE = 1 << RANGE_BIT_SIZE;
+
+ private final Map<Integer, ArrayList<T>> arrays = new HashMap<Integer, ArrayList<T>>();
+
+ /**
+ *
+ * @param index a positive integer
+ * @param value value to store
+ */
+ public void put(Integer index, T value) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int rangeKey = index >> RANGE_BIT_SIZE;
+ int rangeIndex = index % RANGE_SIZE;
+ ArrayList<T> range = arrays.get(rangeKey);
+ if (range == null) {
+ range = new ArrayList<T>(Collections.<T>nCopies(RANGE_SIZE, null));
+ arrays.put(rangeKey, range);
+ }
+ range.set(rangeIndex, value);
+ }
+
+ /**
+ *
+ * @param index a positive integer
+ * @return value the value associated with the index or null
+ */
+ public T get(Integer index) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException();
+ }
+ int rangeKey = index >> RANGE_BIT_SIZE;
+ int rangeIndex = index % RANGE_SIZE;
+ ArrayList<T> range = arrays.get(rangeKey);
+ return range == null ? null : range.get(rangeIndex);
+ }
+}
diff --git a/src/java/org/apache/fop/afp/fonts/OutlineFont.java b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
index e9cdf5ba4..fc2332ce9 100644
--- a/src/java/org/apache/fop/afp/fonts/OutlineFont.java
+++ b/src/java/org/apache/fop/afp/fonts/OutlineFont.java
@@ -19,6 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
+
import org.apache.fop.afp.AFPEventProducer;
/**
@@ -38,4 +40,18 @@ public class OutlineFont extends AbstractOutlineFont {
super(name, embeddable, charSet, eventProducer);
}
+ /**
+ * Obtain the width of the character for the specified point size.
+ * @param character the character
+ * @param size the font size (in mpt)
+ * @return the width of the character for the specified point size
+ */
+ public int getWidth(int character, int size) {
+ return charSet.getWidth(toUnicodeCodepoint(character), size);
+ }
+
+ @Override
+ public Rectangle getBoundingBox(int character, int size) {
+ return charSet.getCharacterBox(toUnicodeCodepoint(character), size);
+ }
}
diff --git a/src/java/org/apache/fop/afp/fonts/RasterFont.java b/src/java/org/apache/fop/afp/fonts/RasterFont.java
index 5c4c38dc5..1fd30e0ba 100644
--- a/src/java/org/apache/fop/afp/fonts/RasterFont.java
+++ b/src/java/org/apache/fop/afp/fonts/RasterFont.java
@@ -19,8 +19,8 @@
package org.apache.fop.afp.fonts;
+import java.awt.Rectangle;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -135,46 +135,21 @@ public class RasterFont extends AFPFont {
}
- /**
- * Get the first character in this font.
- * @return the first character in this font.
- */
- public int getFirstChar() {
- Iterator<CharacterSet> it = charSets.values().iterator();
- if (it.hasNext()) {
- CharacterSet csm = it.next();
- return csm.getFirstChar();
- } else {
- String msg = "getFirstChar() - No character set found for font:" + getFontName();
- LOG.error(msg);
- throw new FontRuntimeException(msg);
- }
- }
-
- /**
- * Get the last character in this font.
- * @return the last character in this font.
- */
- public int getLastChar() {
-
- Iterator<CharacterSet> it = charSets.values().iterator();
- if (it.hasNext()) {
- CharacterSet csm = it.next();
- return csm.getLastChar();
+ private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+ int nominalVerticalSize = cs.getNominalVerticalSize();
+ if (nominalVerticalSize != 0) {
+ return value * nominalVerticalSize;
} else {
- String msg = "getLastChar() - No character set found for font:" + getFontName();
- LOG.error(msg);
- throw new FontRuntimeException(msg);
+ return value * givenSize;
}
-
}
- private int metricsToAbsoluteSize(CharacterSet cs, int value, int givenSize) {
+ private int metricsToAbsoluteSize(CharacterSet cs, double value, int givenSize) {
int nominalVerticalSize = cs.getNominalVerticalSize();
if (nominalVerticalSize != 0) {
- return value * nominalVerticalSize;
+ return (int) (value * nominalVerticalSize);
} else {
- return value * givenSize;
+ return (int) (value * givenSize);
}
}
@@ -191,6 +166,20 @@ public class RasterFont extends AFPFont {
return metricsToAbsoluteSize(cs, cs.getAscender(), size);
}
+ /** {@inheritDoc} */
+ public int getUnderlinePosition(int size) {
+ CharacterSet cs = getCharacterSet(size);
+ return metricsToAbsoluteSize(cs, cs.getUnderscorePosition(), size);
+ }
+
+ @Override
+ public int getUnderlineThickness(int size) {
+ CharacterSet cs = getCharacterSet(size);
+ int underscoreWidth = cs.getUnderscoreWidth();
+ return underscoreWidth == 0 ? super.getUnderlineThickness(size)
+ : metricsToAbsoluteSize(cs, underscoreWidth, size);
+ }
+
/**
* Obtains the height of capital letters for the specified point size.
*
@@ -234,33 +223,20 @@ public class RasterFont extends AFPFont {
*/
public int getWidth(int character, int size) {
CharacterSet cs = getCharacterSet(size);
- return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character)), size);
+ return metricsToAbsoluteSize(cs, cs.getWidth(toUnicodeCodepoint(character), 1), size);
}
/**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @param size the font size (in mpt)
- * @return the widths of all characters
+ * TODO
*/
- public int[] getWidths(int size) {
+ public Rectangle getBoundingBox(int character, int size) {
CharacterSet cs = getCharacterSet(size);
- int[] widths = cs.getWidths();
- for (int i = 0, c = widths.length; i < c; i++) {
- widths[i] = metricsToAbsoluteSize(cs, widths[i], size);
- }
- return widths;
- }
-
- /**
- * Get the getWidth (in 1/1000ths of a point size) of all characters in this
- * character set.
- *
- * @return the widths of all characters
- */
- public int[] getWidths() {
- return getWidths(1000);
+ Rectangle characterBox = cs.getCharacterBox(toUnicodeCodepoint(character), 1);
+ int x = metricsToAbsoluteSize(cs, characterBox.getX(), size);
+ int y = metricsToAbsoluteSize(cs, characterBox.getY(), size);
+ int w = metricsToAbsoluteSize(cs, characterBox.getWidth(), size);
+ int h = metricsToAbsoluteSize(cs, characterBox.getHeight(), size);
+ return new Rectangle(x, y, w, h);
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
index 77ad7e806..d41adf867 100644
--- a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
+++ b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
@@ -67,7 +67,11 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
/** {@inheritDoc} */
public int getDataLength() {
- return super.getDataLength() + str.length();
+ try {
+ return super.getDataLength() + getStringAsBytes().length;
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
index 2c6668454..5c13b9d92 100644
--- a/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
+++ b/src/java/org/apache/fop/afp/svg/AFPBridgeContext.java
@@ -25,13 +25,17 @@ import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.gvt.TextPainter;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
+import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.fop.afp.AFPGraphics2D;
+import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.AbstractFOPBridgeContext;
+import org.apache.fop.svg.font.AggregatingFontFamilyResolver;
/**
* An AFP specific implementation of a Batik BridgeContext
@@ -40,6 +44,8 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
private final AFPGraphics2D g2d;
+ private final EventBroadcaster eventBroadCaster;
+
/**
* Constructs a new bridge context.
*
@@ -54,47 +60,35 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
*/
public AFPBridgeContext(UserAgent userAgent, FontInfo fontInfo,
ImageManager imageManager, ImageSessionContext imageSessionContext,
- AffineTransform linkTransform, AFPGraphics2D g2d) {
+ AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
super(userAgent, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
+ this.eventBroadCaster = eventBroadCaster;
}
- /**
- * Constructs a new bridge context.
- * @param userAgent the user agent
- * @param documentLoader the Document Loader to use for referenced documents.
- * @param fontInfo the font list for the text painter, may be null
- * in which case text is painted as shapes
- * @param imageManager an image manager
- * @param imageSessionContext an image session context
- * @param linkTransform AffineTransform to properly place links,
- * may be null
- * @param g2d an AFPGraphics 2D implementation
- */
- public AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
+ private AFPBridgeContext(UserAgent userAgent, DocumentLoader documentLoader,
FontInfo fontInfo, ImageManager imageManager,
ImageSessionContext imageSessionContext,
- AffineTransform linkTransform, AFPGraphics2D g2d) {
- super(userAgent, documentLoader, fontInfo, imageManager,
- imageSessionContext, linkTransform);
+ AffineTransform linkTransform, AFPGraphics2D g2d, EventBroadcaster eventBroadCaster) {
+ super(userAgent, documentLoader, fontInfo, imageManager, imageSessionContext, linkTransform);
this.g2d = g2d;
+ this.eventBroadCaster = eventBroadCaster;
}
/** {@inheritDoc} */
@Override
public void registerSVGBridges() {
super.registerSVGBridges();
-
if (fontInfo != null) {
AFPTextHandler textHandler = new AFPTextHandler(fontInfo, g2d.getResourceManager());
g2d.setCustomTextHandler(textHandler);
-
- TextPainter textPainter = new AFPTextPainter(textHandler);
- setTextPainter(textPainter);
-
+ //TODO
+ FontFamilyResolver fontFamilyResolver = new AggregatingFontFamilyResolver(
+ new AFPFontFamilyResolver(fontInfo, eventBroadCaster), DefaultFontFamilyResolver.SINGLETON);
+ TextPainter textPainter = new AFPTextPainter(textHandler, fontFamilyResolver);
+ setTextPainter(new AFPTextPainter(textHandler, fontFamilyResolver));
putBridge(new AFPTextElementBridge(textPainter));
}
-
putBridge(new AFPImageElementBridge());
}
@@ -105,7 +99,7 @@ public class AFPBridgeContext extends AbstractFOPBridgeContext {
fontInfo,
getImageManager(),
getImageSessionContext(),
- linkTransform, g2d);
+ linkTransform, g2d, eventBroadCaster);
}
}
diff --git a/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.java
new file mode 100644
index 000000000..a8217088b
--- /dev/null
+++ b/src/java/org/apache/fop/afp/svg/AFPFontFamilyResolver.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.afp.svg;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.batik.gvt.font.GVTFontFace;
+
+import org.apache.fop.afp.AFPEventProducer;
+import org.apache.fop.afp.fonts.DoubleByteFont;
+import org.apache.fop.events.EventBroadcaster;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.Typeface;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
+import org.apache.fop.svg.font.FOPGVTFontFamily;
+import org.apache.fop.svg.font.FilteringFontFamilyResolver;
+
+public class AFPFontFamilyResolver extends FilteringFontFamilyResolver {
+
+ private final FontInfo fontInfo;
+
+ private final AFPEventProducer eventProducer;
+
+
+ public AFPFontFamilyResolver(FontInfo fontInfo, EventBroadcaster eventBroadCaster) {
+ super(new FOPFontFamilyResolverImpl(fontInfo));
+ this.fontInfo = fontInfo;
+ this.eventProducer = AFPEventProducer.Provider.get(eventBroadCaster);
+ }
+
+ @Override
+ public FOPGVTFontFamily resolve(String familyName) {
+ FOPGVTFontFamily fopGVTFontFamily = super.resolve(familyName);
+ // TODO why don't DB fonts work with GOCA?!?
+ if (fopGVTFontFamily != null && fopGVTFontFamily.deriveFont(1, new HashMap())
+ .getFont().getFontMetrics() instanceof DoubleByteFont) {
+ notifyDBFontRejection(fopGVTFontFamily.getFamilyName());
+ fopGVTFontFamily = null;
+ }
+ return fopGVTFontFamily;
+ }
+
+ @Override
+ public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
+ Map<String, Typeface> fonts = fontInfo.getFonts();
+ for (Typeface font : fonts.values()) {
+ // TODO why don't DB fonts work with GOCA?!?
+ if (font.hasChar(c) && !(font instanceof DoubleByteFont)) {
+ String fontFamily = font.getFamilyNames().iterator().next();
+ if (font instanceof DoubleByteFont) {
+ notifyDBFontRejection(font.getFontName());
+ } else {
+ return new FOPGVTFontFamily(fontInfo, fontFamily,
+ new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL),
+ new GVTFontFace(fontFamily));
+ }
+
+ }
+ }
+ return null;
+ }
+
+ private void notifyDBFontRejection(String fontFamily) {
+ eventProducer.invalidDBFontInSVG(this, fontFamily);
+ }
+
+}
diff --git a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
index 2bb4cb60e..e8e391bdb 100644
--- a/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextHandler.java
@@ -120,9 +120,8 @@ public class AFPTextHandler extends FOPTextHandlerAdapter {
// set the color
AFPPaintingState paintingState = g2d.getPaintingState();
- if (paintingState.setColor(color)) {
- graphicsObj.setColor(color);
- }
+ paintingState.setColor(color);
+ graphicsObj.setColor(color);
// set the character set
int fontReference = 0;
@@ -135,27 +134,18 @@ public class AFPTextHandler extends FOPTextHandlerAdapter {
if (log.isDebugEnabled()) {
log.debug(" with overriding font: " + internalFontName + ", " + fontSize);
}
- } else {
- java.awt.Font awtFont = g2d.getFont();
- Font fopFont = fontInfo.getFontInstanceForAWTFont(awtFont);
- if (log.isDebugEnabled()) {
- log.debug(" with font: " + fopFont);
- }
- internalFontName = fopFont.getFontName();
- fontSize = fopFont.getFontSize();
+ fontSize = (int) Math.round(g2d.convertToAbsoluteLength(fontSize));
+ fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
+ // TODO: re-think above registerPageFont code...
+ AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
+ final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
+ // Work-around for InfoPrint's AFP which loses character set state
+ // over Graphics Data
+ // boundaries.
+ graphicsObj.setCharacterSet(fontReference);
+ // add the character string
+ graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
}
- fontSize = (int)Math.round(
- g2d.convertToAbsoluteLength(fontSize));
- fontReference = registerPageFont(pageFonts, internalFontName, fontSize);
- // TODO: re-think above registerPageFont code...
- AFPFont afpFont = (AFPFont) fontInfo.getFonts().get(internalFontName);
- final CharacterSet charSet = afpFont.getCharacterSet(fontSize);
- // Work-around for InfoPrint's AFP which loses character set state
- // over Graphics Data
- // boundaries.
- graphicsObj.setCharacterSet(fontReference);
- // add the character string
- graphicsObj.addString(str, Math.round(x), Math.round(y), charSet);
} else {
//Inside Batik's SVG filter operations, you won't get an AFPGraphics2D
g.drawString(str, x, y);
diff --git a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
index 3815c9eae..996ae8691 100644
--- a/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
+++ b/src/java/org/apache/fop/afp/svg/AFPTextPainter.java
@@ -21,6 +21,9 @@ package org.apache.fop.afp.svg;
import java.awt.Graphics2D;
+import org.apache.batik.gvt.font.FontFamilyResolver;
+import org.apache.batik.gvt.renderer.StrokingTextPainter;
+
import org.apache.fop.afp.AFPGraphics2D;
import org.apache.fop.svg.AbstractFOPTextPainter;
import org.apache.fop.svg.FOPTextHandler;
@@ -39,8 +42,8 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
* Create a new text painter with the given font information.
* @param nativeTextHandler the NativeTextHandler instance used for text painting
*/
- public AFPTextPainter(FOPTextHandler nativeTextHandler) {
- super(nativeTextHandler);
+ public AFPTextPainter(FOPTextHandler nativeTextHandler, FontFamilyResolver fopFontFamilyResolver) {
+ super(nativeTextHandler, new FOPStrokingTextPainter(fopFontFamilyResolver));
}
/** {@inheritDoc} */
@@ -48,4 +51,18 @@ public class AFPTextPainter extends AbstractFOPTextPainter {
return g2d instanceof AFPGraphics2D;
}
+ private static class FOPStrokingTextPainter extends StrokingTextPainter {
+
+ private final FontFamilyResolver fopFontFontFamily;
+
+ FOPStrokingTextPainter(FontFamilyResolver fopFontFontFamily) {
+ this.fopFontFontFamily = fopFontFontFamily;
+ }
+
+ @Override
+ protected FontFamilyResolver getFontFamilyResolver() {
+ return fopFontFontFamily;
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java
index f6de99dd0..640f04335 100644
--- a/src/java/org/apache/fop/area/AreaTreeParser.java
+++ b/src/java/org/apache/fop/area/AreaTreeParser.java
@@ -62,6 +62,7 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.Trait.Background;
import org.apache.fop.area.Trait.InternalLink;
import org.apache.fop.area.inline.AbstractTextArea;
+import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.Image;
import org.apache.fop.area.inline.InlineArea;
@@ -195,6 +196,7 @@ public class AreaTreeParser {
makers.put("space", new SpaceMaker());
makers.put("leader", new LeaderMaker());
makers.put("viewport", new InlineViewportMaker());
+ makers.put("container", new ContainerMaker());
makers.put("image", new ImageMaker());
makers.put("foreignObject", new ForeignObjectMaker());
makers.put("bookmarkTree", new BookmarkTreeMaker());
@@ -863,6 +865,21 @@ public class AreaTreeParser {
}
}
+ private class ContainerMaker extends AbstractMaker {
+
+ public void startElement(Attributes attributes) {
+ Container container = new Container();
+ transferForeignObjects(attributes, container);
+ InlineViewport parent = (InlineViewport) areaStack.peek();
+ parent.setContent(container);
+ areaStack.push(container);
+ }
+
+ public void endElement() {
+ assertObjectOfClass(areaStack.pop(), Container.class);
+ }
+ }
+
private class InlineViewportMaker extends AbstractMaker {
public void startElement(Attributes attributes) {
diff --git a/src/java/org/apache/fop/area/inline/Container.java b/src/java/org/apache/fop/area/inline/Container.java
index bc2acaa28..3d0060007 100644
--- a/src/java/org/apache/fop/area/inline/Container.java
+++ b/src/java/org/apache/fop/area/inline/Container.java
@@ -51,13 +51,12 @@ public class Container extends Area {
public Container() {
}
- /**
- * Add the block to this area.
- *
- * @param block the block area to add
- */
- public void addBlock(Block block) {
- blocks.add(block);
+ @Override
+ public void addChildArea(Area child) {
+ if (!(child instanceof Block)) {
+ throw new IllegalArgumentException("Container only accepts block areas");
+ }
+ blocks.add((Block) child);
}
/**
@@ -65,7 +64,7 @@ public class Container extends Area {
*
* @return the list of block areas
*/
- public List getBlocks() {
+ public List<Block> getBlocks() {
return blocks;
}
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index ad8019a7d..b559e90b8 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -124,6 +124,8 @@ public class CommandLineOptions {
private boolean conserveMemoryPolicy = false;
/* true if a complex script features are enabled */
private boolean useComplexScriptFeatures = true;
+ /* set to true if -dpi used in command line */
+ private boolean overrideTargetResolution = false;
private FopFactory factory;
private FOUserAgent foUserAgent;
@@ -440,6 +442,7 @@ public class CommandLineOptions {
"if you use '-dpi', you must specify a resolution (dots per inch)");
} else {
this.targetResolution = Integer.parseInt(args[i + 1]);
+ this.overrideTargetResolution = true;
return 1;
}
}
@@ -1017,6 +1020,9 @@ public class CommandLineOptions {
try {
FopConfParser fopConfParser = new FopConfParser(userConfigFile, baseURI);
fopFactoryBuilder = fopConfParser.getFopFactoryBuilder();
+ if (this.overrideTargetResolution) {
+ fopFactoryBuilder.setTargetResolution(targetResolution);
+ }
} catch (SAXException e) {
throw new FOPException(e);
}
diff --git a/src/java/org/apache/fop/fo/FOText.java b/src/java/org/apache/fop/fo/FOText.java
index 2fc998c63..0b7dde212 100644
--- a/src/java/org/apache/fop/fo/FOText.java
+++ b/src/java/org/apache/fop/fo/FOText.java
@@ -21,7 +21,6 @@ package org.apache.fop.fo;
import java.awt.Color;
import java.nio.CharBuffer;
-import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Stack;
@@ -38,12 +37,13 @@ import org.apache.fop.fo.properties.CommonTextDecoration;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.SpaceProperty;
+import org.apache.fop.fonts.TextFragment;
import org.apache.fop.util.CharUtilities;
/**
* A text node (PCDATA) in the formatting object tree.
*/
-public class FOText extends FONode implements CharSequence {
+public class FOText extends FONode implements CharSequence, TextFragment {
/** the <code>CharBuffer</code> containing the text */
private CharBuffer charBuffer;
@@ -93,9 +93,6 @@ public class FOText extends FONode implements CharSequence {
/* bidi levels */
private int[] bidiLevels;
- /* advanced script processing state */
- private Map/*<MapRange,String>*/ mappings;
-
private static final int IS_WORD_CHAR_FALSE = 0;
private static final int IS_WORD_CHAR_TRUE = 1;
private static final int IS_WORD_CHAR_MAYBE = 2;
@@ -804,93 +801,6 @@ public class FOText extends FONode implements CharSequence {
}
}
- /**
- * Add characters mapped by script substitution processing.
- * @param start index in character buffer
- * @param end index in character buffer
- * @param mappedChars sequence of character codes denoting substituted characters
- */
- public void addMapping(int start, int end, CharSequence mappedChars) {
- if (mappings == null) {
- mappings = new java.util.HashMap();
- }
- mappings.put(new MapRange(start, end), mappedChars.toString());
- }
-
- /**
- * Determine if characters over specific interval have a mapping.
- * @param start index in character buffer
- * @param end index in character buffer
- * @return true if a mapping exist such that the mapping's interval is coincident to
- * [start,end)
- */
- public boolean hasMapping(int start, int end) {
- return (mappings != null) && (mappings.containsKey(new MapRange(start, end)));
- }
-
- /**
- * Obtain mapping of characters over specific interval.
- * @param start index in character buffer
- * @param end index in character buffer
- * @return a string of characters representing the mapping over the interval
- * [start,end)
- */
- public String getMapping(int start, int end) {
- if (mappings != null) {
- return (String) mappings.get(new MapRange(start, end));
- } else {
- return null;
- }
- }
-
- /**
- * Obtain length of mapping of characters over specific interval.
- * @param start index in character buffer
- * @param end index in character buffer
- * @return the length of the mapping (if present) or zero
- */
- public int getMappingLength(int start, int end) {
- if (mappings != null) {
- return ((String) mappings.get(new MapRange(start, end))) .length();
- } else {
- return 0;
- }
- }
-
- /**
- * Obtain bidirectional levels of mapping of characters over specific interval.
- * @param start index in character buffer
- * @param end index in character buffer
- * @return a (possibly empty) array of bidi levels or null
- * in case no bidi levels have been assigned
- */
- public int[] getMappingBidiLevels(int start, int end) {
- if (hasMapping(start, end)) {
- int nc = end - start;
- int nm = getMappingLength(start, end);
- int[] la = getBidiLevels(start, end);
- if (la == null) {
- return null;
- } else if (nm == nc) { // mapping is same length as mapped range
- return la;
- } else if (nm > nc) { // mapping is longer than mapped range
- int[] ma = new int [ nm ];
- System.arraycopy(la, 0, ma, 0, la.length);
- for (int i = la.length,
- n = ma.length, l = (i > 0) ? la [ i - 1 ] : 0; i < n; i++) {
- ma [ i ] = l;
- }
- return ma;
- } else { // mapping is shorter than mapped range
- int[] ma = new int [ nm ];
- System.arraycopy(la, 0, ma, 0, ma.length);
- return ma;
- }
- } else {
- return getBidiLevels(start, end);
- }
- }
-
@Override
protected Stack collectDelimitedTextRanges(Stack ranges, DelimitedTextRange currentRange) {
if (currentRange != null) {
diff --git a/src/java/org/apache/fop/fo/flow/InlineContainer.java b/src/java/org/apache/fop/fo/flow/InlineContainer.java
index cf970c325..5c95fa34e 100644
--- a/src/java/org/apache/fop/fo/flow/InlineContainer.java
+++ b/src/java/org/apache/fop/fo/flow/InlineContainer.java
@@ -37,49 +37,38 @@ import org.apache.fop.traits.Direction;
import org.apache.fop.traits.WritingMode;
import org.apache.fop.traits.WritingModeTraits;
-/**
- * Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_inline-container">
- * <code>fo:inline-container</code></a> object.
- */
public class InlineContainer extends FObj {
- // The value of FO traits (refined properties) that apply to fo:inline-container.
- private Length alignmentAdjust;
- private int alignmentBaseline;
- private Length baselineShift;
+ private LengthRangeProperty inlineProgressionDimension;
private LengthRangeProperty blockProgressionDimension;
+ private int overflow;
private CommonBorderPaddingBackground commonBorderPaddingBackground;
private CommonMarginInline commonMarginInline;
- private int clip;
- private int dominantBaseline;
- private LengthRangeProperty inlineProgressionDimension;
+ private Numeric referenceOrientation;
+ private int displayAlign;
private KeepProperty keepTogether;
+ private KeepProperty keepWithNext;
+ private KeepProperty keepWithPrevious;
private SpaceProperty lineHeight;
- private int overflow;
- private Numeric referenceOrientation;
+ private Length alignmentAdjust;
+ private int alignmentBaseline;
+ private Length baselineShift;
+ private int dominantBaseline;
private WritingModeTraits writingModeTraits;
- // Unused but valid items, commented out for performance:
- // private CommonRelativePosition commonRelativePosition;
- // private int displayAlign;
- // private Length height;
- // private KeepProperty keepWithNext;
- // private KeepProperty keepWithPrevious;
- // private Length width;
- // End of FO trait values
/** used for FO validation */
- private boolean blockItemFound = false;
+ private boolean blockItemFound;
/**
- * Base constructor
+ * Creates a new instance.
*
- * @param parent {@link FONode} that is the parent of this object
+ * @param parent the parent of this inline-container
*/
public InlineContainer(FONode parent) {
super(parent);
}
- /** {@inheritDoc} */
+ @Override
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
alignmentAdjust = pList.get(PR_ALIGNMENT_ADJUST).getLength();
@@ -88,28 +77,31 @@ public class InlineContainer extends FObj {
blockProgressionDimension = pList.get(PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
commonBorderPaddingBackground = pList.getBorderPaddingBackgroundProps();
commonMarginInline = pList.getMarginInlineProps();
- clip = pList.get(PR_CLIP).getEnum();
+ displayAlign = pList.get(PR_DISPLAY_ALIGN).getEnum();
dominantBaseline = pList.get(PR_DOMINANT_BASELINE).getEnum();
inlineProgressionDimension = pList.get(PR_INLINE_PROGRESSION_DIMENSION).getLengthRange();
keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
+ keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
+ keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
lineHeight = pList.get(PR_LINE_HEIGHT).getSpace();
overflow = pList.get(PR_OVERFLOW).getEnum();
referenceOrientation = pList.get(PR_REFERENCE_ORIENTATION).getNumeric();
writingModeTraits = new WritingModeTraits(
- WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
- pList.getExplicit(PR_WRITING_MODE) != null);
+ WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()),
+ pList.getExplicit(PR_WRITING_MODE) != null);
}
/**
* {@inheritDoc}
* <br>XSL Content Model: marker* (%block;)+
*/
+ @Override
protected void validateChildNode(Locator loc, String nsURI, String localName)
throws ValidationException {
if (FO_URI.equals(nsURI)) {
if (localName.equals("marker")) {
if (blockItemFound) {
- nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
+ nodesOutOfOrderError(loc, "fo:marker", "(%block;)+");
}
} else if (!isBlockItem(nsURI, localName)) {
invalidChildError(loc, nsURI, localName);
@@ -119,153 +111,129 @@ public class InlineContainer extends FObj {
}
}
- /** {@inheritDoc} */
+ @Override
public void endOfNode() throws FOPException {
if (!blockItemFound) {
missingChildElementError("marker* (%block;)+");
}
}
- /** @return the "alignment-adjust" FO trait */
- public Length getAlignmentAdjust() {
- return alignmentAdjust;
+ /** {@inheritDoc} */
+ public String getLocalName() {
+ return "inline-container";
}
- /** @return the "alignment-baseline" FO trait */
- public int getAlignmentBaseline() {
- return alignmentBaseline;
+ /**
+ * {@inheritDoc}
+ * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
+ */
+ public int getNameId() {
+ return FO_INLINE_CONTAINER;
}
- /** @return the "baseline-shift" FO trait */
- public Length getBaselineShift() {
- return baselineShift;
+ public LengthRangeProperty getInlineProgressionDimension() {
+ return inlineProgressionDimension;
}
- /** @return the "block-progression-dimension" FO trait */
public LengthRangeProperty getBlockProgressionDimension() {
return blockProgressionDimension;
}
- /** @return the "clip" FO trait */
- public int getClip() {
- return clip;
+ public int getOverflow() {
+ return overflow;
}
- /**@return Returns the {@link CommonBorderPaddingBackground} */
public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
return this.commonBorderPaddingBackground;
}
- /** @return Returns the {@link CommonMarginInline} */
public CommonMarginInline getCommonMarginInline() {
return this.commonMarginInline;
}
- /** @return the "dominant-baseline" FO trait */
- public int getDominantBaseline() {
- return dominantBaseline;
+ public int getReferenceOrientation() {
+ return referenceOrientation.getValue();
+ }
+
+ public int getDisplayAlign() {
+ return this.displayAlign;
+ }
+
+ public KeepProperty getKeepWithPrevious() {
+ return keepWithPrevious;
}
- /** @return the "keep-together" FO trait */
public KeepProperty getKeepTogether() {
return keepTogether;
}
- /** @return the "inline-progression-dimension" FO trait */
- public LengthRangeProperty getInlineProgressionDimension() {
- return inlineProgressionDimension;
+ public KeepProperty getKeepWithNext() {
+ return keepWithNext;
}
- /** @return the "line-height" FO trait */
public SpaceProperty getLineHeight() {
return lineHeight;
}
- /** @return the "overflow" FO trait */
- public int getOverflow() {
- return overflow;
+ public Length getAlignmentAdjust() {
+ return alignmentAdjust;
}
- /** @return the "reference-orientation" FO trait */
- public int getReferenceOrientation() {
- return referenceOrientation.getValue();
+ public int getAlignmentBaseline() {
+ return alignmentBaseline;
+ }
+
+ public Length getBaselineShift() {
+ return baselineShift;
+ }
+
+ public int getDominantBaseline() {
+ return dominantBaseline;
+ }
+
+ public WritingMode getWritingMode() {
+ return writingModeTraits.getWritingMode();
}
/**
- * Obtain inline progression direction.
- * @return the inline progression direction
+ * Obtain writing mode explicit indicator.
+ * @return the writing mode explicit indicator
*/
+ public boolean getExplicitWritingMode() {
+ return writingModeTraits.getExplicitWritingMode();
+ }
+
public Direction getInlineProgressionDirection() {
return writingModeTraits.getInlineProgressionDirection();
}
- /**
- * Obtain block progression direction.
- * @return the block progression direction
- */
public Direction getBlockProgressionDirection() {
return writingModeTraits.getBlockProgressionDirection();
}
- /**
- * Obtain column progression direction.
- * @return the column progression direction
- */
public Direction getColumnProgressionDirection() {
return writingModeTraits.getColumnProgressionDirection();
}
- /**
- * Obtain row progression direction.
- * @return the row progression direction
- */
public Direction getRowProgressionDirection() {
return writingModeTraits.getRowProgressionDirection();
}
- /**
- * Obtain (baseline) shift direction.
- * @return the (baseline) shift direction
- */
public Direction getShiftDirection() {
return writingModeTraits.getShiftDirection();
}
- /**
- * Obtain writing mode.
- * @return the writing mode
- */
- public WritingMode getWritingMode() {
- return writingModeTraits.getWritingMode();
- }
-
- /**
- * Obtain writing mode explicit indicator.
- * @return the writing mode explicit indicator
- */
- public boolean getExplicitWritingMode() {
- return writingModeTraits.getExplicitWritingMode();
- }
-
- /** {@inheritDoc} */
- public String getLocalName() {
- return "inline-container";
- }
-
- /**
- * {@inheritDoc}
- * @return {@link org.apache.fop.fo.Constants#FO_INLINE_CONTAINER}
- */
- public int getNameId() {
- return FO_INLINE_CONTAINER;
- }
-
@Override
public boolean isDelimitedTextRangeBoundary(int boundary) {
return false;
}
@Override
+ public boolean generatesReferenceAreas() {
+ return true;
+ }
+
+ @Override
protected boolean isBidiBoundary(boolean propagate) {
return getExplicitWritingMode();
}
diff --git a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java
index 72884a177..fe9c64cb7 100644
--- a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java
+++ b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java
@@ -105,6 +105,9 @@ public class FontSizePropertyMaker
// than the last caculated step
lastStepFontSize = nextStepFontSize;
nextStepFontSize = (int)Math.round(lastStepFontSize * scale);
+ if (nextStepFontSize == lastStepFontSize) {
+ break;
+ }
}
// baseFontSize is between last and next step font size
// Return the step value closer to the baseFontSize
diff --git a/src/java/org/apache/fop/fonts/Base14Font.java b/src/java/org/apache/fop/fonts/Base14Font.java
index 9b2e95bc7..fdefd0cdd 100644
--- a/src/java/org/apache/fop/fonts/Base14Font.java
+++ b/src/java/org/apache/fop/fonts/Base14Font.java
@@ -25,4 +25,15 @@ package org.apache.fop.fonts;
*/
public abstract class Base14Font extends Typeface {
+ /** Thickness for underline and strikeout. */
+ private static final int LINE_THICKNESS = 50;
+
+ public int getStrikeoutPosition(int size) {
+ return getXHeight(size) / 2;
+ }
+
+ public int getStrikeoutThickness(int size) {
+ return size * LINE_THICKNESS;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/CustomFont.java b/src/java/org/apache/fop/fonts/CustomFont.java
index 70961a55c..96b70feea 100644
--- a/src/java/org/apache/fop/fonts/CustomFont.java
+++ b/src/java/org/apache/fop/fonts/CustomFont.java
@@ -37,6 +37,9 @@ import org.apache.fop.apps.io.InternalResourceResolver;
public abstract class CustomFont extends Typeface
implements FontDescriptor, MutableFont {
+ /** Fallback thickness for underline and strikeout when not provided by the font. */
+ private static final int DEFAULT_LINE_THICKNESS = 50;
+
private String fontName;
private String fullName;
private Set<String> familyNames;
@@ -60,6 +63,14 @@ public abstract class CustomFont extends Typeface
private int firstChar;
private int lastChar = 255;
+ private int underlinePosition;
+
+ private int underlineThickness;
+
+ private int strikeoutPosition;
+
+ private int strikeoutThickness;
+
private Map<Integer, Map<Integer, Integer>> kerning;
private boolean useKerning = true;
@@ -507,4 +518,40 @@ public abstract class CustomFont extends Typeface
return copy;
}
+ public int getUnderlinePosition(int size) {
+ return (underlinePosition == 0)
+ ? getDescender(size) / 2
+ : size * underlinePosition;
+ }
+
+ public void setUnderlinePosition(int underlinePosition) {
+ this.underlinePosition = underlinePosition;
+ }
+
+ public int getUnderlineThickness(int size) {
+ return size * ((underlineThickness == 0) ? DEFAULT_LINE_THICKNESS : underlineThickness);
+ }
+
+ public void setUnderlineThickness(int underlineThickness) {
+ this.underlineThickness = underlineThickness;
+ }
+
+ public int getStrikeoutPosition(int size) {
+ return (strikeoutPosition == 0)
+ ? getXHeight(size) / 2
+ : size * strikeoutPosition;
+ }
+
+ public void setStrikeoutPosition(int strikeoutPosition) {
+ this.strikeoutPosition = strikeoutPosition;
+ }
+
+ public int getStrikeoutThickness(int size) {
+ return (strikeoutThickness == 0) ? getUnderlineThickness(size) : size * strikeoutThickness;
+ }
+
+ public void setStrikeoutThickness(int strikeoutThickness) {
+ this.strikeoutThickness = strikeoutThickness;
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
index 472567eec..720531205 100644
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ b/src/java/org/apache/fop/fonts/FontInfo.java
@@ -30,6 +30,7 @@ import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
/**
* The FontInfo holds font information for the layout and rendering of a fo document.
* This stores the list of available fonts that are setup by
@@ -135,12 +136,10 @@ public class FontInfo {
if (oldName != null) {
int oldPriority = tripletPriorities.get(triplet).intValue();
if (oldPriority < newPriority) {
- logDuplicateFont(triplet, false, oldName, oldPriority,
- internalFontKey, newPriority);
+ logDuplicateFont(triplet, false, oldName, oldPriority, internalFontKey, newPriority);
return;
} else {
- logDuplicateFont(triplet, true, oldName, oldPriority,
- internalFontKey, newPriority);
+ logDuplicateFont(triplet, true, oldName, oldPriority, internalFontKey, newPriority);
}
}
this.triplets.put(triplet, internalFontKey);
@@ -157,9 +156,8 @@ public class FontInfo {
* @param newKey the new internal font name
* @param newPriority the priority of the duplicate font mapping
*/
- private void logDuplicateFont(FontTriplet triplet, boolean replacing,
- String oldKey, int oldPriority,
- String newKey, int newPriority) {
+ private void logDuplicateFont(FontTriplet triplet, boolean replacing, String oldKey, int oldPriority,
+ String newKey, int newPriority) {
if (log.isDebugEnabled()) {
log.debug(triplet
+ (replacing ? ": Replacing " : ": Not replacing ")
@@ -198,8 +196,7 @@ public class FontInfo {
* default font if not found
* @return internal font triplet key
*/
- private FontTriplet fontLookup(String family, String style,
- int weight, boolean substitutable) {
+ private FontTriplet fontLookup(String family, String style, int weight, boolean substitutable) {
if (log.isTraceEnabled()) {
log.trace("Font lookup: " + family + " " + style + " " + weight
+ (substitutable ? " substitutable" : ""));
@@ -302,8 +299,7 @@ public class FontInfo {
* @return the requested Font instance
*/
public Font getFontInstance(FontTriplet triplet, int fontSize) {
- Map<Integer, Font> sizes
- = getFontInstanceCache().get(triplet);
+ Map<Integer, Font> sizes = getFontInstanceCache().get(triplet);
if (sizes == null) {
sizes = new HashMap<Integer, Font>();
getFontInstanceCache().put(triplet, sizes);
@@ -379,13 +375,11 @@ public class FontInfo {
* @param weight font weight
* @return the font triplet of the font chosen
*/
- public FontTriplet fontLookup(String family, String style,
- int weight) {
+ public FontTriplet fontLookup(String family, String style, int weight) {
return fontLookup(family, style, weight, true);
}
- private List<FontTriplet> fontLookup(String[] families, String style,
- int weight, boolean substitutable) {
+ private List<FontTriplet> fontLookup(String[] families, String style, int weight, boolean substitutable) {
List<FontTriplet> matchingTriplets = new ArrayList<FontTriplet>();
FontTriplet triplet = null;
for (int i = 0; i < families.length; i++) {
@@ -410,8 +404,7 @@ public class FontInfo {
* @return the set of font triplets of all supported and chosen font-families
* in the specified style and weight.
*/
- public FontTriplet[] fontLookup(String[] families, String style,
- int weight) {
+ public FontTriplet[] fontLookup(String[] families, String style, int weight) {
if (families.length == 0) {
throw new IllegalArgumentException("Specify at least one font family");
}
@@ -434,8 +427,8 @@ public class FontInfo {
sb.append(families[i]);
}
throw new IllegalStateException(
- "fontLookup must return an array with at least one "
- + "FontTriplet on the last call. Lookup: " + sb.toString());
+ "fontLookup must return an array with at least one "
+ + "FontTriplet on the last call. Lookup: " + sb.toString());
}
FontTriplet[] fontTriplets = new FontTriplet[matchedTriplets.size()];
@@ -469,8 +462,7 @@ public class FontInfo {
* @param weight font weight
* @return internal key
*/
- public FontTriplet findAdjustWeight(String family, String style,
- int weight) {
+ public FontTriplet findAdjustWeight(String family, String style, int weight) {
FontTriplet key = null;
String f = null;
int newWeight = weight;
@@ -542,8 +534,7 @@ public class FontInfo {
* @param weight font weight
* @return internal key
*/
- public static FontTriplet createFontKey(String family, String style,
- int weight) {
+ public static FontTriplet createFontKey(String family, String style, int weight) {
return new FontTriplet(family, style, weight);
}
diff --git a/src/java/org/apache/fop/fonts/FontMetrics.java b/src/java/org/apache/fop/fonts/FontMetrics.java
index ff32d7305..159d321f7 100644
--- a/src/java/org/apache/fop/fonts/FontMetrics.java
+++ b/src/java/org/apache/fop/fonts/FontMetrics.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts;
+import java.awt.Rectangle;
import java.util.Map;
import java.util.Set;
@@ -120,6 +121,15 @@ public interface FontMetrics {
int[] getWidths();
/**
+ * Returns the bounding box of the glyph at the given index, for the given font size.
+ *
+ * @param glyphIndex glyph index
+ * @param size font size
+ * @return the scaled bounding box scaled in 1/1000ths of the given size
+ */
+ Rectangle getBoundingBox(int glyphIndex, int size);
+
+ /**
* Indicates if the font has kering information.
* @return True, if kerning is available.
*/
@@ -131,4 +141,38 @@ public interface FontMetrics {
*/
Map<Integer, Map<Integer, Integer>> getKerningInfo();
+ /**
+ * Returns the distance from the baseline to the center of the underline (negative
+ * value indicates below baseline).
+ *
+ * @param size font size
+ * @return the position in 1/1000ths of the font size
+ */
+ int getUnderlinePosition(int size);
+
+ /**
+ * Returns the thickness of the underline.
+ *
+ * @param size font size
+ * @return the thickness in 1/1000ths of the font size
+ */
+ int getUnderlineThickness(int size);
+
+ /**
+ * Returns the distance from the baseline to the center of the strikeout line
+ * (negative value indicates below baseline).
+ *
+ * @param size font size
+ * @return the position in 1/1000ths of the font size
+ */
+ int getStrikeoutPosition(int size);
+
+ /**
+ * Returns the thickness of the strikeout line.
+ *
+ * @param size font size
+ * @return the thickness in 1/1000ths of the font size
+ */
+ int getStrikeoutThickness(int size);
+
}
diff --git a/src/java/org/apache/fop/fonts/GlyphMapping.java b/src/java/org/apache/fop/fonts/GlyphMapping.java
new file mode 100644
index 000000000..a8a82085e
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/GlyphMapping.java
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.fonts;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
+import org.apache.fop.complexscripts.util.CharScript;
+import org.apache.fop.traits.MinOptMax;
+import org.apache.fop.util.CharUtilities;
+
+/**
+ * Stores the mapping of a text fragment to glyphs, along with various information.
+ */
+public class GlyphMapping {
+
+ private static final Log LOG = LogFactory.getLog(GlyphMapping.class);
+ /** Inclusive. */
+ public final int startIndex;
+ /** Exclusive. */
+ public final int endIndex;
+ private int wordCharLength;
+ public final int wordSpaceCount;
+ public int letterSpaceCount;
+ public MinOptMax areaIPD;
+ public final boolean isHyphenated;
+ public final boolean isSpace;
+ public boolean breakOppAfter;
+ public final Font font;
+ public final int level;
+ public final int[][] gposAdjustments;
+ public final String mapping;
+
+ public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
+ MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
+ Font font, int level, int[][] gposAdjustments) {
+ this(startIndex, endIndex, wordSpaceCount, letterSpaceCount, areaIPD, isHyphenated,
+ isSpace, breakOppAfter, font, level, gposAdjustments, null);
+ }
+
+ public GlyphMapping(int startIndex, int endIndex, int wordSpaceCount, int letterSpaceCount,
+ MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
+ Font font, int level, int[][] gposAdjustments, String mapping) {
+ assert startIndex <= endIndex;
+ this.startIndex = startIndex;
+ this.endIndex = endIndex;
+ this.wordCharLength = -1;
+ this.wordSpaceCount = wordSpaceCount;
+ this.letterSpaceCount = letterSpaceCount;
+ this.areaIPD = areaIPD;
+ this.isHyphenated = isHyphenated;
+ this.isSpace = isSpace;
+ this.breakOppAfter = breakOppAfter;
+ this.font = font;
+ this.level = level;
+ this.gposAdjustments = gposAdjustments;
+ this.mapping = mapping;
+ }
+
+ public static GlyphMapping doGlyphMapping(TextFragment text, int startIndex, int endIndex,
+ Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
+ char precedingChar, char breakOpportunityChar, final boolean endsWithHyphen, int level) {
+ GlyphMapping mapping;
+ if (font.performsSubstitution() || font.performsPositioning()) {
+ mapping = processWordMapping(text, startIndex, endIndex, font,
+ breakOpportunityChar, endsWithHyphen, level);
+ } else {
+ mapping = processWordNoMapping(text, startIndex, endIndex, font,
+ letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen,
+ level);
+ }
+ return mapping;
+ }
+
+ private static GlyphMapping processWordMapping(TextFragment text, int startIndex,
+ int endIndex, final Font font, final char breakOpportunityChar,
+ final boolean endsWithHyphen, int level) {
+ int e = endIndex; // end index of word in FOText character buffer
+ int nLS = 0; // # of letter spaces
+ String script = text.getScript();
+ String language = text.getLanguage();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
+ + " +M"
+ + ", level = " + level
+ + " }");
+ }
+
+ // 1. extract unmapped character sequence
+ CharSequence ics = text.subSequence(startIndex, e);
+
+ // 2. if script is not specified (by FO property) or it is specified as 'auto',
+ // then compute dominant script
+ if ((script == null) || "auto".equals(script)) {
+ script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
+ }
+ if ((language == null) || "none".equals(language)) {
+ language = "dflt";
+ }
+
+ // 3. perform mapping of chars to glyphs ... to glyphs ... to chars
+ CharSequence mcs = font.performSubstitution(ics, script, language);
+
+ // 4. compute glyph position adjustments on (substituted) characters
+ int[][] gpa;
+ if (font.performsPositioning()) {
+ // handle GPOS adjustments
+ gpa = font.performPositioning(mcs, script, language);
+ } else if (font.hasKerning()) {
+ // handle standard (non-GPOS) kerning adjustments
+ gpa = getKerningAdjustments(mcs, font);
+ } else {
+ gpa = null;
+ }
+
+ // 5. reorder combining marks so that they precede (within the mapped char sequence) the
+ // base to which they are applied; N.B. position adjustments (gpa) are reordered in place
+ mcs = font.reorderCombiningMarks(mcs, gpa, script, language);
+
+ // 6. compute word ipd based on final position adjustments
+ MinOptMax ipd = MinOptMax.ZERO;
+ for (int i = 0, n = mcs.length(); i < n; i++) {
+ int c = mcs.charAt(i);
+ // TODO !BMP
+ int w = font.getCharWidth(c);
+ if (w < 0) {
+ w = 0;
+ }
+ if (gpa != null) {
+ w += gpa[i][GlyphPositioningTable.Value.IDX_X_ADVANCE];
+ }
+ ipd = ipd.plus(w);
+ }
+
+ // [TBD] - handle letter spacing
+
+ return new GlyphMapping(startIndex, e, 0, nLS, ipd, endsWithHyphen, false,
+ breakOpportunityChar != 0, font, level, gpa,
+ CharUtilities.isSameSequence(mcs, ics) ? null : mcs.toString());
+ }
+
+ /**
+ * Given a mapped character sequence MCS, obtain glyph position adjustments from the
+ * font's kerning data.
+ *
+ * @param mcs mapped character sequence
+ * @param font applicable font
+ * @return glyph position adjustments (or null if no kerning)
+ */
+ private static int[][] getKerningAdjustments(CharSequence mcs, final Font font) {
+ int nc = mcs.length();
+ // extract kerning array
+ int[] ka = new int[nc]; // kerning array
+ for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
+ int c = mcs.charAt(i);
+ // TODO !BMP
+ if (cPrev >= 0) {
+ ka[i] = font.getKernValue(cPrev, c);
+ }
+ cPrev = c;
+ }
+ // was there a non-zero kerning?
+ boolean hasKerning = false;
+ for (int i = 0, n = nc; i < n; i++) {
+ if (ka[i] != 0) {
+ hasKerning = true;
+ break;
+ }
+ }
+ // if non-zero kerning, then create and return glyph position adjustment array
+ if (hasKerning) {
+ int[][] gpa = new int[nc][4];
+ for (int i = 0, n = nc; i < n; i++) {
+ if (i > 0) {
+ gpa [i - 1][GlyphPositioningTable.Value.IDX_X_ADVANCE] = ka[i];
+ }
+ }
+ return gpa;
+ } else {
+ return null;
+ }
+ }
+
+ private static GlyphMapping processWordNoMapping(TextFragment text, int startIndex, int endIndex,
+ final Font font, MinOptMax letterSpaceIPD, MinOptMax[] letterSpaceAdjustArray,
+ char precedingChar, final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
+ boolean kerning = font.hasKerning();
+ MinOptMax wordIPD = MinOptMax.ZERO;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("PW: [" + startIndex + "," + endIndex + "]: {"
+ + " -M"
+ + ", level = " + level
+ + " }");
+ }
+
+ for (int i = startIndex; i < endIndex; i++) {
+ char currentChar = text.charAt(i);
+
+ // character width
+ int charWidth = font.getCharWidth(currentChar);
+ wordIPD = wordIPD.plus(charWidth);
+
+ // kerning
+ if (kerning) {
+ int kern = 0;
+ if (i > startIndex) {
+ char previousChar = text.charAt(i - 1);
+ kern = font.getKernValue(previousChar, currentChar);
+ } else if (precedingChar != 0) {
+ kern = font.getKernValue(precedingChar, currentChar);
+ }
+ if (kern != 0) {
+ addToLetterAdjust(letterSpaceAdjustArray, i, kern);
+ wordIPD = wordIPD.plus(kern);
+ }
+ }
+ }
+ if (kerning
+ && (breakOpportunityChar != 0)
+ && !isSpace(breakOpportunityChar)
+ && endIndex > 0
+ && endsWithHyphen) {
+ int kern = font.getKernValue(text.charAt(endIndex - 1), breakOpportunityChar);
+ if (kern != 0) {
+ addToLetterAdjust(letterSpaceAdjustArray, endIndex, kern);
+ // TODO: add kern to wordIPD?
+ }
+ }
+ // shy+chars at start of word: wordLength == 0 && breakOpportunity
+ // shy only characters in word: wordLength == 0 && !breakOpportunity
+ int wordLength = endIndex - startIndex;
+ int letterSpaces = 0;
+ if (wordLength != 0) {
+ letterSpaces = wordLength - 1;
+ // if there is a break opportunity and the next one (break character)
+ // is not a space, it could be used as a line end;
+ // add one more letter space, in case other text follows
+ if ((breakOpportunityChar != 0) && !isSpace(breakOpportunityChar)) {
+ letterSpaces++;
+ }
+ }
+ assert letterSpaces >= 0;
+ wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));
+
+ // create and return the AreaInfo object
+ return new GlyphMapping(startIndex, endIndex, 0,
+ letterSpaces, wordIPD,
+ endsWithHyphen,
+ false, breakOpportunityChar != 0, font, level, null);
+ }
+
+ private static void addToLetterAdjust(MinOptMax[] letterSpaceAdjustArray, int index, int width) {
+ if (letterSpaceAdjustArray[index] == null) {
+ letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
+ } else {
+ letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
+ }
+ }
+
+ /**
+ * Indicates whether a character is a space in terms of this layout manager.
+ *
+ * @param ch the character
+ * @return true if it's a space
+ */
+ public static boolean isSpace(final char ch) {
+ return ch == CharUtilities.SPACE
+ || CharUtilities.isNonBreakableSpace(ch)
+ || CharUtilities.isFixedWidthSpace(ch);
+ }
+
+ /**
+ * Obtain number of 'characters' contained in word. If word is mapped, then this
+ * number may be less than or greater than the original length (breakIndex -
+ * startIndex). We compute and memoize thius length upon first invocation of this
+ * method.
+ */
+ public int getWordLength() {
+ if (wordCharLength == -1) {
+ if (mapping != null) {
+ wordCharLength = mapping.length();
+ } else {
+ assert endIndex >= startIndex;
+ wordCharLength = endIndex - startIndex;
+ }
+ }
+ return wordCharLength;
+ }
+
+ public void addToAreaIPD(MinOptMax idp) {
+ areaIPD = areaIPD.plus(idp);
+ }
+
+ public String toString() {
+ return super.toString() + "{"
+ + "interval = [" + startIndex + "," + endIndex + "]"
+ + ", isSpace = " + isSpace
+ + ", level = " + level
+ + ", areaIPD = " + areaIPD
+ + ", letterSpaceCount = " + letterSpaceCount
+ + ", wordSpaceCount = " + wordSpaceCount
+ + ", isHyphenated = " + isHyphenated
+ + ", font = " + font
+ + "}";
+ }
+
+}
diff --git a/src/java/org/apache/fop/fonts/LazyFont.java b/src/java/org/apache/fop/fonts/LazyFont.java
index 49b2e0457..1877a895e 100644
--- a/src/java/org/apache/fop/fonts/LazyFont.java
+++ b/src/java/org/apache/fop/fonts/LazyFont.java
@@ -18,6 +18,7 @@
/* $Id$ */
package org.apache.fop.fonts;
+import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -250,6 +251,26 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
return realFont.getXHeight(size);
}
+ public int getUnderlinePosition(int size) {
+ load(true);
+ return realFont.getUnderlinePosition(size);
+ }
+
+ public int getUnderlineThickness(int size) {
+ load(true);
+ return realFont.getUnderlineThickness(size);
+ }
+
+ public int getStrikeoutPosition(int size) {
+ load(true);
+ return realFont.getStrikeoutPosition(size);
+ }
+
+ public int getStrikeoutThickness(int size) {
+ load(true);
+ return realFont.getStrikeoutThickness(size);
+ }
+
/**
* {@inheritDoc}
*/
@@ -268,6 +289,11 @@ public class LazyFont extends Typeface implements FontDescriptor, Substitutable,
return realFont.getWidths();
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ load(true);
+ return realFont.getBoundingBox(glyphIndex, size);
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java
index 68be7bed8..cc3d06650 100644
--- a/src/java/org/apache/fop/fonts/MultiByteFont.java
+++ b/src/java/org/apache/fop/fonts/MultiByteFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts;
+import java.awt.Rectangle;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.BitSet;
@@ -68,6 +69,9 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
private int firstUnmapped;
private int lastUnmapped;
+ /** Contains the character bounding boxes for all characters in the font */
+ protected Rectangle[] boundingBoxes;
+
private boolean isOTFFile = false;
// since for most users the most likely glyphs are in the first cmap segments we store their mapping.
@@ -196,6 +200,12 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
return arr;
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ int index = isEmbeddable() ? cidSet.getOriginalGlyphIndex(glyphIndex) : glyphIndex;
+ Rectangle bbox = boundingBoxes[index];
+ return new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
+ }
+
/**
* Returns the glyph index for a Unicode character. The method returns 0 if there's no
* such glyph in the character map.
@@ -401,6 +411,14 @@ public class MultiByteFont extends CIDFont implements Substitutable, Positionabl
}
/**
+ * Sets the bounding boxes array.
+ * @param boundingBoxes array of bounding boxes.
+ */
+ public void setBBoxArray(Rectangle[] boundingBoxes) {
+ this.boundingBoxes = boundingBoxes;
+ }
+
+ /**
* Returns a Map of used Glyphs.
* @return Map Map of used Glyphs
*/
diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java
index a61d846e6..2a6b04761 100644
--- a/src/java/org/apache/fop/fonts/SingleByteFont.java
+++ b/src/java/org/apache/fop/fonts/SingleByteFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts;
+import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -47,6 +48,8 @@ public class SingleByteFont extends CustomFont {
private int[] width = null;
+ private Rectangle[] boundingBoxes;
+
private Map<Character, UnencodedCharacter> unencodedCharacters;
private List<SimpleSingleByteEncoding> additionalEncodings;
private Map<Character, Character> alternativeCodes;
@@ -111,6 +114,24 @@ public class SingleByteFont extends CustomFont {
return arr;
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ Rectangle bbox = null;
+ if (glyphIndex < 256) {
+ int idx = glyphIndex - getFirstChar();
+ if (idx >= 0 && idx < boundingBoxes.length) {
+ bbox = boundingBoxes[idx];
+ }
+ } else if (this.additionalEncodings != null) {
+ int encodingIndex = (glyphIndex / 256) - 1;
+ SimpleSingleByteEncoding encoding = getAdditionalEncoding(encodingIndex);
+ int codePoint = glyphIndex % 256;
+ NamedCharacter nc = encoding.getCharacterForIndex(codePoint);
+ UnencodedCharacter uc = this.unencodedCharacters.get(Character.valueOf(nc.getSingleUnicodeValue()));
+ bbox = uc.getBBox();
+ }
+ return bbox == null ? null : new Rectangle(bbox.x * size, bbox.y * size, bbox.width * size, bbox.height * size);
+ }
+
/**
* Lookup a character using its alternative names. If found, cache it so we
* can speed up lookups.
@@ -292,17 +313,24 @@ public class SingleByteFont extends CustomFont {
this.width[index - getFirstChar()] = w;
}
+ public void setBoundingBox(int index, Rectangle bbox) {
+ if (this.boundingBoxes == null) {
+ this.boundingBoxes = new Rectangle[getLastChar() - getFirstChar() + 1];
+ }
+ this.boundingBoxes[index - getFirstChar()] = bbox;
+ }
+
/**
* Adds an unencoded character (one that is not supported by the primary encoding).
* @param ch the named character
* @param width the width of the character
*/
- public void addUnencodedCharacter(NamedCharacter ch, int width) {
+ public void addUnencodedCharacter(NamedCharacter ch, int width, Rectangle bbox) {
if (this.unencodedCharacters == null) {
this.unencodedCharacters = new HashMap<Character, UnencodedCharacter>();
}
if (ch.hasSingleUnicodeValue()) {
- UnencodedCharacter uc = new UnencodedCharacter(ch, width);
+ UnencodedCharacter uc = new UnencodedCharacter(ch, width, bbox);
this.unencodedCharacters.put(Character.valueOf(ch.getSingleUnicodeValue()), uc);
} else {
//Cannot deal with unicode sequences, so ignore this character
@@ -381,10 +409,12 @@ public class SingleByteFont extends CustomFont {
private final NamedCharacter character;
private final int width;
+ private final Rectangle bbox;
- public UnencodedCharacter(NamedCharacter character, int width) {
+ public UnencodedCharacter(NamedCharacter character, int width, Rectangle bbox) {
this.character = character;
this.width = width;
+ this.bbox = bbox;
}
public NamedCharacter getCharacter() {
@@ -395,6 +425,10 @@ public class SingleByteFont extends CustomFont {
return this.width;
}
+ public Rectangle getBBox() {
+ return bbox;
+ }
+
/** {@inheritDoc} */
@Override
public String toString() {
diff --git a/src/java/org/apache/fop/fonts/TextFragment.java b/src/java/org/apache/fop/fonts/TextFragment.java
new file mode 100644
index 000000000..ad72db8e0
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/TextFragment.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public interface TextFragment {
+
+ String getScript();
+
+ String getLanguage();
+
+ char charAt(int index);
+
+ CharSequence subSequence(int startIndex, int endIndex);
+}
diff --git a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java b/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
index f15837bb8..7168389ff 100644
--- a/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
+++ b/src/java/org/apache/fop/fonts/truetype/OFFontLoader.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts.truetype;
+import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
@@ -149,6 +150,10 @@ public class OFFontLoader extends FontLoader {
returnFont.setAscender(otf.getLowerCaseAscent());
returnFont.setDescender(otf.getLowerCaseDescent());
returnFont.setFontBBox(otf.getFontBBox());
+ returnFont.setUnderlinePosition(otf.getUnderlinePosition() - otf.getUnderlineThickness() / 2);
+ returnFont.setUnderlineThickness(otf.getUnderlineThickness());
+ returnFont.setStrikeoutPosition(otf.getStrikeoutPosition() - otf.getStrikeoutThickness() / 2);
+ returnFont.setStrikeoutThickness(otf.getStrikeoutThickness());
returnFont.setFlags(otf.getFlags());
returnFont.setStemV(Integer.parseInt(otf.getStemV())); //not used for TTF
returnFont.setItalicAngle(Integer.parseInt(otf.getItalicAngle()));
@@ -161,15 +166,15 @@ public class OFFontLoader extends FontLoader {
} else {
multiFont.setCIDType(CIDFontType.CIDTYPE2);
}
- int[] wx = otf.getWidths();
- multiFont.setWidthArray(wx);
+ multiFont.setWidthArray(otf.getWidths());
+ multiFont.setBBoxArray(otf.getBoundingBoxes());
} else {
singleFont.setFontType(FontType.TRUETYPE);
singleFont.setEncoding(otf.getCharSetName());
returnFont.setFirstChar(otf.getFirstChar());
returnFont.setLastChar(otf.getLastChar());
singleFont.setTrueTypePostScriptVersion(otf.getPostScriptVersion());
- copyWidthsSingleByte(otf);
+ copyGlyphMetricsSingleByte(otf);
}
returnFont.setCMap(getCMap(otf));
@@ -195,10 +200,14 @@ public class OFFontLoader extends FontLoader {
return otf.getCMaps().toArray(array);
}
- private void copyWidthsSingleByte(OpenFont otf) {
+ private void copyGlyphMetricsSingleByte(OpenFont otf) {
int[] wx = otf.getWidths();
+ Rectangle[] bboxes = otf.getBoundingBoxes();
for (int i = singleFont.getFirstChar(); i <= singleFont.getLastChar(); i++) {
singleFont.setWidth(i, otf.getCharWidth(i));
+ int[] bbox = otf.getBBox(i);
+ singleFont.setBoundingBox(i,
+ new Rectangle(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]));
}
for (CMapSegment segment : otf.getCMaps()) {
@@ -214,7 +223,7 @@ public class OFFontLoader extends FontLoader {
if (glyphName.length() > 0) {
String unicode = Character.toString(u);
NamedCharacter nc = new NamedCharacter(glyphName, unicode);
- singleFont.addUnencodedCharacter(nc, wx[glyphIndex]);
+ singleFont.addUnencodedCharacter(nc, wx[glyphIndex], bboxes[glyphIndex]);
}
}
}
diff --git a/src/java/org/apache/fop/fonts/truetype/OTFFile.java b/src/java/org/apache/fop/fonts/truetype/OTFFile.java
index 3976b5994..ab9654beb 100644
--- a/src/java/org/apache/fop/fonts/truetype/OTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/OTFFile.java
@@ -20,11 +20,17 @@
package org.apache.fop.fonts.truetype;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import org.apache.fontbox.cff.CFFDataInput;
import org.apache.fontbox.cff.CFFFont;
-import org.apache.fontbox.cff.CFFFont.Mapping;
import org.apache.fontbox.cff.CFFParser;
+import org.apache.fontbox.cff.charset.CFFCharset;
public class OTFFile extends OpenFont {
@@ -45,17 +51,77 @@ public class OTFFile extends OpenFont {
@Override
protected void updateBBoxAndOffset() throws IOException {
+ List<Mapping> gidMappings = getGIDMappings(fileFont);
+ Map<Integer, String> sidNames = constructNameMap(gidMappings);
UnicodeMapping[] mappings = unicodeMappings.toArray(new UnicodeMapping[0]);
for (int i = 0; i < mappings.length; i++) {
int glyphIdx = mappings[i].getGlyphIndex();
- Mapping m = fileFont.getGIDMappings().get(glyphIdx);
- int[] bbox = fileFont.getBoundingBox(m.getSID());
- String name = fileFont.getNameOfCharFromCode(m.getSID());
- mtxTab[glyphIdx].setBoundingBox(bbox);
+ Mapping m = gidMappings.get(glyphIdx);
+ String name = sidNames.get(m.getSID());
mtxTab[glyphIdx].setName(name);
}
}
+ private List<Mapping> getGIDMappings(CFFFont font) {
+ List<Mapping> gidMappings = new ArrayList<Mapping>();
+ Mapping notdef = new Mapping();
+ gidMappings.add(notdef);
+ for (CFFCharset.Entry entry : font.getCharset().getEntries()) {
+ String name = entry.getName();
+ byte[] bytes = font.getCharStringsDict().get(name);
+ if (bytes == null) {
+ continue;
+ }
+ Mapping mapping = new Mapping();
+ mapping.setSID(entry.getSID());
+ mapping.setName(name);
+ mapping.setBytes(bytes);
+ gidMappings.add(mapping);
+ }
+ return gidMappings;
+ }
+
+ private Map<Integer, String> constructNameMap(Collection<Mapping> mappings) {
+ Map<Integer, String> sidNames = new HashMap<Integer, String>();
+ Iterator<Mapping> it = mappings.iterator();
+ while (it.hasNext()) {
+ Mapping mapping = it.next();
+ sidNames.put(mapping.getSID(), mapping.getName());
+ }
+ return sidNames;
+ }
+
+ private static class Mapping {
+ private int sid;
+ private String name;
+ private byte[] bytes;
+
+ public void setSID(int sid) {
+ this.sid = sid;
+ }
+
+ public int getSID() {
+ return sid;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setBytes(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ public byte[] getBytes() {
+ return bytes;
+ }
+ }
+
+
@Override
protected void initializeFont(FontFileReader in) throws IOException {
fontFile = in;
diff --git a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java b/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
index 4d0cce67a..9cb3458c8 100644
--- a/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/OTFSubSetFile.java
@@ -861,7 +861,6 @@ public class OTFSubSetFile extends OTFFile {
return hdrTotal + total;
}
-
private BytesNumber readNumber(int b0, byte[] input, int curPos) throws IOException {
if (b0 == 28) {
int b1 = input[curPos + 1] & 0xff;
@@ -887,7 +886,7 @@ public class OTFSubSetFile extends OTFFile {
/**
* A class used to store the last number operand and also it's size in bytes
*/
- private static final class BytesNumber {
+ static class BytesNumber {
private int number;
private int numBytes;
@@ -908,6 +907,26 @@ public class OTFSubSetFile extends OTFFile {
this.number = -1;
this.numBytes = -1;
}
+
+ public String toString() {
+ return Integer.toString(number);
+ }
+
+ @Override
+ public boolean equals(Object entry) {
+ assert entry instanceof BytesNumber;
+ BytesNumber bnEntry = (BytesNumber)entry;
+ return this.number == bnEntry.getNumber()
+ && this.numBytes == bnEntry.getNumBytes();
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ hash = hash * 17 + number;
+ hash = hash * 31 + numBytes;
+ return hash;
+ }
}
private void writeCharsetTable(boolean cidFont) throws IOException {
@@ -1094,4 +1113,12 @@ public class OTFSubSetFile extends OTFFile {
System.arraycopy(output, 0, ret, 0, realSize);
return ret;
}
+
+ /**
+ * Returns the parsed CFF data for the original font.
+ * @return The CFFDataReader contaiing the parsed data
+ */
+ public CFFDataReader getCFFReader() {
+ return cffReader;
+ }
}
diff --git a/src/java/org/apache/fop/fonts/truetype/OpenFont.java b/src/java/org/apache/fop/fonts/truetype/OpenFont.java
index ce9a2b388..3f4765cdc 100644
--- a/src/java/org/apache/fop/fonts/truetype/OpenFont.java
+++ b/src/java/org/apache/fop/fonts/truetype/OpenFont.java
@@ -19,6 +19,7 @@
package org.apache.fop.fonts.truetype;
+import java.awt.Rectangle;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -195,6 +196,10 @@ public abstract class OpenFont {
private int fontBBox4 = 0;
private int capHeight = 0;
private int os2CapHeight = 0;
+ private int underlinePosition;
+ private int underlineThickness;
+ private int strikeoutPosition;
+ private int strikeoutThickness;
private int xHeight = 0;
private int os2xHeight = 0;
//Effective ascender/descender
@@ -995,10 +1000,22 @@ public abstract class OpenFont {
for (int i = 0; i < wx.length; i++) {
wx[i] = convertTTFUnit2PDFUnit(mtxTab[i].getWx());
}
-
return wx;
}
+ public Rectangle[] getBoundingBoxes() {
+ Rectangle[] boundingBoxes = new Rectangle[mtxTab.length];
+ for (int i = 0; i < boundingBoxes.length; i++) {
+ int[] boundingBox = mtxTab[i].getBoundingBox();
+ boundingBoxes[i] = new Rectangle(
+ convertTTFUnit2PDFUnit(boundingBox[0]),
+ convertTTFUnit2PDFUnit(boundingBox[1]),
+ convertTTFUnit2PDFUnit(boundingBox[2] - boundingBox[0]),
+ convertTTFUnit2PDFUnit(boundingBox[3] - boundingBox[1]));
+ }
+ return boundingBoxes;
+ }
+
/**
* Returns an array (xMin, yMin, xMax, yMax) for a glyph.
*
@@ -1039,6 +1056,22 @@ public abstract class OpenFont {
return ansiKerningTab;
}
+ public int getUnderlinePosition() {
+ return convertTTFUnit2PDFUnit(underlinePosition);
+ }
+
+ public int getUnderlineThickness() {
+ return convertTTFUnit2PDFUnit(underlineThickness);
+ }
+
+ public int getStrikeoutPosition() {
+ return convertTTFUnit2PDFUnit(strikeoutPosition);
+ }
+
+ public int getStrikeoutThickness() {
+ return convertTTFUnit2PDFUnit(strikeoutThickness);
+ }
+
/**
* Indicates if the font may be embedded.
* @return boolean True if it may be embedded
@@ -1215,10 +1248,8 @@ public abstract class OpenFont {
seekTab(fontFile, OFTableName.POST, 0);
int postFormat = fontFile.readTTFLong();
italicAngle = fontFile.readTTFULong();
- //underlinePosition
- fontFile.readTTFShort();
- //underlineThickness
- fontFile.readTTFShort();
+ underlinePosition = fontFile.readTTFShort();
+ underlineThickness = fontFile.readTTFShort();
isFixedPitch = fontFile.readTTFULong();
//Skip memory usage values
@@ -1322,7 +1353,10 @@ public abstract class OpenFont {
} else {
isEmbeddable = true;
}
- fontFile.skip(11 * 2);
+ fontFile.skip(8 * 2);
+ strikeoutThickness = fontFile.readTTFShort();
+ strikeoutPosition = fontFile.readTTFShort();
+ fontFile.skip(2);
fontFile.skip(10); //panose array
fontFile.skip(4 * 4); //unicode ranges
fontFile.skip(4);
diff --git a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java b/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
index 4906f2c31..8d9f4238b 100644
--- a/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
+++ b/src/java/org/apache/fop/fonts/type1/AFMCharMetrics.java
@@ -19,7 +19,7 @@
package org.apache.fop.fonts.type1;
-import java.awt.geom.RectangularShape;
+import java.awt.Rectangle;
import org.apache.fop.fonts.NamedCharacter;
@@ -33,7 +33,7 @@ public class AFMCharMetrics {
private NamedCharacter character;
private double widthX;
private double widthY;
- private RectangularShape bBox;
+ private Rectangle bBox;
/**
* Returns the character code.
@@ -137,7 +137,7 @@ public class AFMCharMetrics {
* Returns the character's bounding box.
* @return the bounding box (or null if it isn't available)
*/
- public RectangularShape getBBox() {
+ public Rectangle getBBox() {
return bBox;
}
@@ -145,7 +145,7 @@ public class AFMCharMetrics {
* Sets the character's bounding box.
* @param box the bounding box
*/
- public void setBBox(RectangularShape box) {
+ public void setBBox(Rectangle box) {
bBox = box;
}
diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
index 716faa61e..260ef209f 100644
--- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
+++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java
@@ -217,12 +217,16 @@ public class Type1FontLoader extends FontLoader {
for (AFMCharMetrics metrics : charMetrics) {
String charName = metrics.getCharName();
if (charName != null && !glyphNames.contains(charName)) {
- singleFont.addUnencodedCharacter(metrics.getCharacter(),
- (int)Math.round(metrics.getWidthX()));
+ addUnencodedCharacter(singleFont, metrics);
}
}
}
+ private static void addUnencodedCharacter(SingleByteFont font, AFMCharMetrics metrics) {
+ font.addUnencodedCharacter(metrics.getCharacter(),
+ (int) Math.round(metrics.getWidthX()), metrics.getBBox());
+ }
+
/**
* Adds characters not encoded in the font's primary encoding. This method is used when
* the primary encoding is built based on the character codes in the AFM rather than
@@ -234,8 +238,7 @@ public class Type1FontLoader extends FontLoader {
for (int i = 0, c = afm.getCharCount(); i < c; i++) {
AFMCharMetrics metrics = (AFMCharMetrics)charMetrics.get(i);
if (!metrics.hasCharCode() && metrics.getCharacter() != null) {
- singleFont.addUnencodedCharacter(metrics.getCharacter(),
- (int)Math.round(metrics.getWidthX()));
+ addUnencodedCharacter(singleFont, metrics);
}
}
}
@@ -281,7 +284,10 @@ public class Type1FontLoader extends FontLoader {
} else {
returnFont.setStemV(80); // Arbitrary value
}
- returnFont.setItalicAngle((int) afm.getWritingDirectionMetrics(0).getItalicAngle());
+ AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
+ returnFont.setItalicAngle((int) metrics.getItalicAngle());
+ returnFont.setUnderlinePosition(metrics.getUnderlinePosition().intValue());
+ returnFont.setUnderlineThickness(metrics.getUnderlineThickness().intValue());
} else {
returnFont.setFontBBox(pfm.getFontBBox());
returnFont.setStemV(pfm.getStemV());
@@ -383,6 +389,7 @@ public class Type1FontLoader extends FontLoader {
for (AFMCharMetrics chm : afm.getCharMetrics()) {
if (chm.hasCharCode()) {
singleFont.setWidth(chm.getCharCode(), (int) Math.round(chm.getWidthX()));
+ singleFont.setBoundingBox(chm.getCharCode(), chm.getBBox());
}
}
if (useKerning) {
diff --git a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
index 79592efd1..ec187b8d0 100644
--- a/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
+++ b/src/java/org/apache/fop/image/loader/batik/ImageConverterSVG2G2D.java
@@ -33,6 +33,7 @@ import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.xmlgraphics.image.GraphicsConstants;
import org.apache.xmlgraphics.image.loader.Image;
@@ -123,10 +124,8 @@ public class ImageConverterSVG2G2D extends AbstractImageConverter {
* @return the newly created user agent
*/
protected SimpleSVGUserAgent createBatikUserAgent(float pxToMillimeter) {
- return new SimpleSVGUserAgent(
- pxToMillimeter,
- new AffineTransform()) {
-
+ return new SimpleSVGUserAgent(pxToMillimeter, new AffineTransform(),
+ DefaultFontFamilyResolver.SINGLETON) {
/** {@inheritDoc} */
public void displayMessage(String message) {
//TODO Refine and pipe through to caller
diff --git a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
index 3aa340a4a..58daadc52 100644
--- a/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
+++ b/src/java/org/apache/fop/image/loader/batik/PreloaderSVG.java
@@ -38,6 +38,7 @@ import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGOMDocument;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.xmlgraphics.image.loader.ImageContext;
import org.apache.xmlgraphics.image.loader.ImageInfo;
@@ -162,7 +163,7 @@ public class PreloaderSVG extends AbstractImagePreloader {
Element e = doc.getRootElement();
float pxUnitToMillimeter = UnitConv.IN2MM / context.getSourceResolution();
UserAgent userAg = new SimpleSVGUserAgent(pxUnitToMillimeter,
- new AffineTransform()) {
+ new AffineTransform(), DefaultFontFamilyResolver.SINGLETON) {
/** {@inheritDoc} */
public void displayMessage(String message) {
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
index 5d7cc0b64..635e267c1 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBaseLayoutManager.java
@@ -65,9 +65,6 @@ public abstract class AbstractBaseLayoutManager
public AbstractBaseLayoutManager(FObj fo) {
this.fobj = fo;
setGeneratesReferenceArea(fo.generatesReferenceAreas());
- if (getGeneratesReferenceArea()) {
- setGeneratesBlockArea(true);
- }
}
// --------- Property Resolution related functions --------- //
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
index 0285a41e7..2dd18e4ee 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
@@ -342,6 +342,34 @@ public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager im
&& isFinished());
}
+ public boolean hasLineAreaDescendant() {
+ if (childLMs == null || childLMs.isEmpty()) {
+ return false;
+ } else {
+ for (LayoutManager childLM : childLMs) {
+ if (childLM.hasLineAreaDescendant()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public int getBaselineOffset() {
+ if (childLMs != null) {
+ for (LayoutManager childLM : childLMs) {
+ if (childLM.hasLineAreaDescendant()) {
+ return childLM.getBaselineOffset();
+ }
+ }
+ }
+ throw newNoLineAreaDescendantException();
+ }
+
+ protected IllegalStateException newNoLineAreaDescendantException() {
+ return new IllegalStateException("getBaselineOffset called on an object that has no line-area descendant");
+ }
+
/**
* Transfers foreign attributes from the formatting object to the area.
* @param targetArea the area to set the attributes on
diff --git a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
index 0ed6cb69b..d731ab62a 100644
--- a/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
+++ b/src/java/org/apache/fop/layoutmgr/AreaAdditionUtil.java
@@ -33,11 +33,11 @@ public final class AreaAdditionUtil {
/**
* Creates the child areas for the given layout manager.
- * @param bslm the BlockStackingLayoutManager instance for which "addAreas" is performed.
+ * @param parentLM the parent layout manager
* @param parentIter the position iterator
* @param layoutContext the layout context
*/
- public static void addAreas(BlockStackingLayoutManager bslm,
+ public static void addAreas(AbstractLayoutManager parentLM,
PositionIterator parentIter, LayoutContext layoutContext) {
LayoutManager childLM;
LayoutContext lc = LayoutContext.offspringOf(layoutContext);
@@ -46,8 +46,8 @@ public final class AreaAdditionUtil {
Position firstPos = null;
Position lastPos = null;
- if (bslm != null) {
- bslm.addId();
+ if (parentLM != null) {
+ parentLM.addId();
}
// "unwrap" the NonLeafPositions stored in parentIter
@@ -86,11 +86,11 @@ public final class AreaAdditionUtil {
//doesn't give us that info.
}
- if (bslm != null) {
- bslm.registerMarkers(
+ if (parentLM != null) {
+ parentLM.registerMarkers(
true,
- bslm.isFirst(firstPos),
- bslm.isLast(lastPos));
+ parentLM.isFirst(firstPos),
+ parentLM.isLast(lastPos));
}
PositionIterator childPosIter = new PositionIterator(positionList.listIterator());
@@ -113,11 +113,11 @@ public final class AreaAdditionUtil {
childLM.addAreas(childPosIter, lc);
}
- if (bslm != null) {
- bslm.registerMarkers(
+ if (parentLM != null) {
+ parentLM.registerMarkers(
false,
- bslm.isFirst(firstPos),
- bslm.isLast(lastPos));
+ parentLM.isFirst(firstPos),
+ parentLM.isLast(lastPos));
}
diff --git a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
index b5b712a33..c59c9d607 100644
--- a/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
+++ b/src/java/org/apache/fop/layoutmgr/BestFitLayoutUtils.java
@@ -20,12 +20,11 @@ package org.apache.fop.layoutmgr;
import java.util.LinkedList;
import java.util.List;
-import org.apache.fop.fo.flow.MultiSwitch;
import org.apache.fop.layoutmgr.BestFitPenalty.Variant;
/**
* Utility class used in {@link MultiSwitchLayoutManager}
- * to handle the <i>best-fit</i> property value if specified in {@link MultiSwitch}
+ * to handle the <i>best-fit</i> property value if specified in {@link org.apache.fop.fo.flow.MultiSwitch}
*/
public final class BestFitLayoutUtils {
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index eced48939..3da6974a6 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -37,6 +37,7 @@ import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.flow.BlockContainer;
import org.apache.fop.fo.properties.CommonAbsolutePosition;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
@@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block-container FO.
*/
-public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements
- ConditionalElementListener, BreakOpportunity {
+public class BlockContainerLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+ implements BreakOpportunity {
/**
* logging instance
@@ -79,13 +80,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
private MinOptMax foBlockSpaceBefore;
private MinOptMax foBlockSpaceAfter;
- private boolean discardBorderBefore;
- private boolean discardBorderAfter;
- private boolean discardPaddingBefore;
- private boolean discardPaddingAfter;
- private MinOptMax effSpaceBefore;
- private MinOptMax effSpaceAfter;
-
private int horizontalOverflow;
private double contentRectOffsetX = 0;
private double contentRectOffsetY = 0;
@@ -96,6 +90,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
*/
public BlockContainerLayoutManager(BlockContainer node) {
super(node);
+ setGeneratesBlockArea(true);
}
/** {@inheritDoc} */
@@ -128,6 +123,11 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
.spaceAfter.getSpace().getOptimum(this).getLength().getValue(this);
}
+ @Override
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return getBlockContainerFO().getCommonBorderPaddingBackground();
+ }
+
private void resetSpaces() {
this.discardBorderBefore = false;
this.discardBorderAfter = false;
@@ -995,51 +995,6 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager impl
}
/** {@inheritDoc} */
- public void notifySpace(RelSide side, MinOptMax effectiveLength) {
- if (RelSide.BEFORE == side) {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceBefore + "-> " + effectiveLength);
- }
- this.effSpaceBefore = effectiveLength;
- } else {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceAfter + "-> " + effectiveLength);
- }
- this.effSpaceAfter = effectiveLength;
- }
- }
-
- /** {@inheritDoc} */
- public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardBorderBefore = true;
- } else {
- this.discardBorderAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Border " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
- public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardPaddingBefore = true;
- } else {
- this.discardPaddingAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Padding " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
public boolean handleOverflow(int milliPoints) {
if (milliPoints > this.horizontalOverflow) {
this.horizontalOverflow = milliPoints;
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index b29b95cb1..d3bdc7b85 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -32,6 +32,7 @@ import org.apache.fop.area.Block;
import org.apache.fop.area.LineArea;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
@@ -44,8 +45,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block FO.
*/
-public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
- BreakOpportunity {
+public class BlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+ implements BreakOpportunity {
/** logging instance */
private static Log log = LogFactory.getLog(BlockLayoutManager.class);
@@ -60,13 +61,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
private int follow = 2000;
//private int middleShift = 0;
- private boolean discardBorderBefore;
- private boolean discardBorderAfter;
- private boolean discardPaddingBefore;
- private boolean discardPaddingAfter;
- private MinOptMax effSpaceBefore;
- private MinOptMax effSpaceAfter;
-
/**
* Creates a new BlockLayoutManager.
* @param inBlock the block FO object to create the layout manager for.
@@ -100,6 +94,11 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
.getOptimum(this).getLength().getValue(this);
}
+ @Override
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return getBlockFO().getCommonBorderPaddingBackground();
+ }
+
/** {@inheritDoc} */
@Override
public List getNextKnuthElements(LayoutContext context, int alignment) {
@@ -458,51 +457,6 @@ public class BlockLayoutManager extends BlockStackingLayoutManager implements Co
}
/** {@inheritDoc} */
- public void notifySpace(RelSide side, MinOptMax effectiveLength) {
- if (RelSide.BEFORE == side) {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceBefore + "-> " + effectiveLength);
- }
- this.effSpaceBefore = effectiveLength;
- } else {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceAfter + "-> " + effectiveLength);
- }
- this.effSpaceAfter = effectiveLength;
- }
- }
-
- /** {@inheritDoc} */
- public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardBorderBefore = true;
- } else {
- this.discardBorderAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Border " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
- public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardPaddingBefore = true;
- } else {
- this.discardPaddingAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Padding " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
@Override
public boolean isRestartable() {
return true;
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index d11f062cb..250e07727 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -36,6 +36,7 @@ import org.apache.fop.fo.properties.BreakPropertySet;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.SpaceProperty;
+import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.util.ListUtil;
@@ -1246,6 +1247,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
public boolean handleOverflow(int milliPoints) {
if (getParent() instanceof BlockStackingLayoutManager) {
return ((BlockStackingLayoutManager) getParent()).handleOverflow(milliPoints);
+ } else if (getParent() instanceof InlineContainerLayoutManager) {
+ return ((InlineContainerLayoutManager) getParent()).handleOverflow(milliPoints);
}
return false;
}
diff --git a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
index 2a39700e2..75c61b94f 100644
--- a/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/FlowLayoutManager.java
@@ -58,6 +58,7 @@ public class FlowLayoutManager extends BlockStackingLayoutManager
*/
public FlowLayoutManager(PageSequenceLayoutManager pslm, Flow node) {
super(node);
+ setGeneratesBlockArea(true);
setParent(pslm);
}
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManager.java b/src/java/org/apache/fop/layoutmgr/LayoutManager.java
index 985131bf1..8d1e4001c 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutManager.java
@@ -178,6 +178,25 @@ public interface LayoutManager extends PercentBaseContext {
List getChangedKnuthElements(List oldList, int alignment);
/**
+ * Whether the FO handled by this layout manager has a descendant (including itself)
+ * that will generate a line-area.
+ *
+ * @return {@code true} if a descendant line-area will be generated, {@code false} otherwise
+ */
+ boolean hasLineAreaDescendant();
+
+ /**
+ * Returns the position of the dominant-baseline of this FO's first descendant
+ * line-area. <p>The behavior of this method is undefined if this FO has no descendant
+ * line-area, and an exception may be thrown. See {@link #hasLineAreaDescendant()}</p>
+ *
+ * @return this FO's space-before plus the distance from the before-edge of its
+ * allocation-rectangle to the dominant-baseline of the first line-area descendant
+ * @see #hasLineAreaDescendant()
+ */
+ int getBaselineOffset();
+
+ /**
* Returns the IPD of the content area
* @return the IPD of the content area
*/
diff --git a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
index cf8b74cc0..2ffb48675 100644
--- a/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
+++ b/src/java/org/apache/fop/layoutmgr/LayoutManagerMapping.java
@@ -75,7 +75,7 @@ import org.apache.fop.layoutmgr.inline.CharacterLayoutManager;
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
import org.apache.fop.layoutmgr.inline.ExternalGraphicLayoutManager;
import org.apache.fop.layoutmgr.inline.FootnoteLayoutManager;
-import org.apache.fop.layoutmgr.inline.ICLayoutManager;
+import org.apache.fop.layoutmgr.inline.InlineContainerLayoutManager;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.layoutmgr.inline.InstreamForeignObjectLM;
import org.apache.fop.layoutmgr.inline.LeaderLayoutManager;
@@ -261,9 +261,9 @@ public class LayoutManagerMapping implements LayoutManagerMaker {
/** a layout manager maker */
public static class InlineLayoutManagerMaker extends Maker {
/** {@inheritDoc} */
- public void make(FONode node, List lms) {
- lms.add(new InlineLayoutManager((InlineLevel) node));
- }
+ public void make(FONode node, List lms) {
+ lms.add(new InlineLayoutManager((InlineLevel) node));
+ }
}
/** a layout manager maker */
@@ -278,9 +278,7 @@ public class LayoutManagerMapping implements LayoutManagerMaker {
public static class InlineContainerLayoutManagerMaker extends Maker {
/** {@inheritDoc} */
public void make(FONode node, List lms) {
- ArrayList childList = new ArrayList();
- super.make(node, childList);
- lms.add(new ICLayoutManager((InlineContainer) node, childList));
+ lms.add(new InlineContainerLayoutManager((InlineContainer) node));
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java
new file mode 100644
index 000000000..2ac41e96a
--- /dev/null
+++ b/src/java/org/apache/fop/layoutmgr/SpacedBorderedPaddedBlockLayoutManager.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.layoutmgr;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.traits.MinOptMax;
+
+/**
+ * A block-stacking layout manager for an FO that supports spaces, border and padding.
+ */
+public abstract class SpacedBorderedPaddedBlockLayoutManager extends BlockStackingLayoutManager
+ implements ConditionalElementListener {
+
+ private static final Log LOG = LogFactory.getLog(BlockLayoutManager.class);
+
+ protected MinOptMax effSpaceBefore;
+
+ protected MinOptMax effSpaceAfter;
+
+ protected boolean discardBorderBefore;
+ protected boolean discardBorderAfter;
+ protected boolean discardPaddingBefore;
+ protected boolean discardPaddingAfter;
+
+ public SpacedBorderedPaddedBlockLayoutManager(FObj node) {
+ super(node);
+ }
+
+ public void notifySpace(RelSide side, MinOptMax effectiveLength) {
+ if (RelSide.BEFORE == side) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this + ": Space " + side + ", "
+ + this.effSpaceBefore + "-> " + effectiveLength);
+ }
+ this.effSpaceBefore = effectiveLength;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this + ": Space " + side + ", "
+ + this.effSpaceAfter + "-> " + effectiveLength);
+ }
+ this.effSpaceAfter = effectiveLength;
+ }
+ }
+
+ public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
+ if (effectiveLength == null) {
+ if (RelSide.BEFORE == side) {
+ this.discardBorderBefore = true;
+ } else {
+ this.discardBorderAfter = true;
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this + ": Border " + side + " -> " + effectiveLength);
+ }
+ }
+
+ public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
+ if (effectiveLength == null) {
+ if (RelSide.BEFORE == side) {
+ this.discardPaddingBefore = true;
+ } else {
+ this.discardPaddingAfter = true;
+ }
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(this + ": Padding " + side + " -> " + effectiveLength);
+ }
+ }
+
+ @Override
+ public int getBaselineOffset() {
+ int baselineOffset = super.getBaselineOffset();
+ if (effSpaceBefore != null) {
+ baselineOffset += effSpaceBefore.getOpt();
+ }
+ if (!discardBorderBefore) {
+ baselineOffset += getCommonBorderPaddingBackground().getBorderBeforeWidth(false);
+ }
+ if (!discardPaddingBefore) {
+ baselineOffset += getCommonBorderPaddingBackground().getPaddingBefore(false, this);
+ }
+ return baselineOffset;
+ }
+
+ /**
+ * Returns the {@link CommonBorderPaddingBackground} instance from the FO handled by this layout manager.
+ */
+ protected abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();
+
+}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java
index c1992965c..192956abc 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/AlignmentContext.java
@@ -295,7 +295,7 @@ public class AlignmentContext implements Constants {
* Return the dominant baseline identifier.
* @return the dominant baseline identifier
*/
- private int getDominantBaselineIdentifier() {
+ public int getDominantBaselineIdentifier() {
return actualBaselineTable.getDominantBaselineIdentifier();
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index b3c768987..c067b040f 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -332,6 +332,15 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
return parentLM.getPSLM();
}
+
+ public boolean hasLineAreaDescendant() {
+ return true;
+ }
+
+ public int getBaselineOffset() {
+ return childLM.getBaselineOffset();
+ }
+
// --------- Property Resolution related functions --------- //
/**
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java
deleted file mode 100644
index 7fe90f63c..000000000
--- a/src/java/org/apache/fop/layoutmgr/inline/ICLayoutManager.java
+++ /dev/null
@@ -1,54 +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.layoutmgr.inline;
-
-// Java
-import java.util.List;
-
-// FOP
-import org.apache.fop.area.inline.InlineArea;
-import org.apache.fop.fo.flow.InlineContainer;
-/**
- * This creates a single inline container area after
- * laying out the child block areas. All footnotes, floats
- * and id areas are maintained for later retrieval.
- */
-public class ICLayoutManager extends LeafNodeLayoutManager {
- private List childrenLM;
-
- /**
- * Construct inline container layout manager.
- * @param node inline container FO node
- * @param childLM child layout manager
- */
- public ICLayoutManager(InlineContainer node, List childLM) {
- super(node);
- childrenLM = childLM;
- }
-
- /**
- * @param index an integer
- * @return an inline area or null
- */
- public InlineArea get(int index) {
- return null;
- }
-
-}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java
new file mode 100644
index 000000000..54237a914
--- /dev/null
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineContainerLayoutManager.java
@@ -0,0 +1,326 @@
+/*
+ * 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.layoutmgr.inline;
+
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.fop.area.Area;
+import org.apache.fop.area.Trait;
+import org.apache.fop.area.inline.Container;
+import org.apache.fop.area.inline.InlineViewport;
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.LengthBase;
+import org.apache.fop.datatypes.SimplePercentBaseContext;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.flow.InlineContainer;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
+import org.apache.fop.fo.properties.LengthRangeProperty;
+import org.apache.fop.fo.properties.Property;
+import org.apache.fop.layoutmgr.AbstractLayoutManager;
+import org.apache.fop.layoutmgr.AreaAdditionUtil;
+import org.apache.fop.layoutmgr.BlockLevelEventProducer;
+import org.apache.fop.layoutmgr.ElementListUtils;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
+import org.apache.fop.layoutmgr.KnuthPossPosIter;
+import org.apache.fop.layoutmgr.KnuthSequence;
+import org.apache.fop.layoutmgr.LayoutContext;
+import org.apache.fop.layoutmgr.LayoutManager;
+import org.apache.fop.layoutmgr.ListElement;
+import org.apache.fop.layoutmgr.NonLeafPosition;
+import org.apache.fop.layoutmgr.Position;
+import org.apache.fop.layoutmgr.PositionIterator;
+import org.apache.fop.layoutmgr.SpaceResolver;
+import org.apache.fop.layoutmgr.TraitSetter;
+
+/**
+ * This creates a single inline container area after
+ * laying out the child block areas. All footnotes, floats
+ * and id areas are maintained for later retrieval.
+ */
+public class InlineContainerLayoutManager extends AbstractLayoutManager implements InlineLevelLayoutManager {
+
+ private CommonBorderPaddingBackground borderProps;
+ private int contentAreaIPD;
+ private int contentAreaBPD;
+
+ private List<ListElement> childElements;
+ private int ipdOverflow;
+ private AlignmentContext alignmentContext;
+ private InlineViewport currentViewport;
+ private Container referenceArea;
+
+ public InlineContainerLayoutManager(InlineContainer node) {
+ super(node);
+ setGeneratesReferenceArea(true);
+ }
+
+ @Override
+ public void initialize() {
+ InlineContainer node = (InlineContainer) fobj;
+ borderProps = node.getCommonBorderPaddingBackground();
+ }
+
+ private InlineContainer getInlineContainer() {
+ assert fobj instanceof InlineContainer;
+ return (InlineContainer) fobj;
+ }
+
+ @Override
+ public List<KnuthSequence> getNextKnuthElements(LayoutContext context, int alignment) {
+ determineIPD(context);
+ childElements = getChildKnuthElements(context, alignment);
+ determineBPD();
+ alignmentContext = makeAlignmentContext(context);
+ Position position = new Position(this, 0);
+ KnuthSequence knuthSequence = new InlineKnuthSequence();
+ knuthSequence.add(new KnuthInlineBox(contentAreaIPD, alignmentContext, position, false));
+ List<KnuthSequence> knuthElements = new ArrayList<KnuthSequence>(1);
+ knuthElements.add(knuthSequence);
+ setFinished(true);
+ return knuthElements;
+ }
+
+ private void determineIPD(LayoutContext layoutContext) {
+ LengthRangeProperty ipd = getInlineContainer().getInlineProgressionDimension();
+ Property optimum = ipd.getOptimum(this);
+ if (optimum.isAuto()) {
+ contentAreaIPD = layoutContext.getRefIPD();
+ InlineLevelEventProducer eventProducer = InlineLevelEventProducer.Provider.get(
+ fobj.getUserAgent().getEventBroadcaster());
+ eventProducer.inlineContainerAutoIPDNotSupported(this, contentAreaIPD / 1000f);
+ } else {
+ contentAreaIPD = optimum.getLength().getValue(this);
+ }
+ }
+
+ private List<ListElement> getChildKnuthElements(LayoutContext layoutContext, int alignment) {
+ List<ListElement> allChildElements = new LinkedList<ListElement>();
+ LayoutManager childLM;
+ while ((childLM = getChildLM()) != null) {
+ LayoutContext childLC = LayoutContext.offspringOf(layoutContext);
+ childLC.setRefIPD(contentAreaIPD);
+ @SuppressWarnings("unchecked")
+ List<ListElement> childElements = childLM.getNextKnuthElements(childLC, alignment);
+ allChildElements.addAll(childElements);
+ }
+ handleIPDOverflow();
+ wrapPositions(allChildElements);
+ SpaceResolver.resolveElementList(allChildElements);
+ SpaceResolver.performConditionalsNotification(allChildElements, 0, allChildElements.size() - 1, -1);
+ return allChildElements;
+ }
+
+ private void determineBPD() {
+ LengthRangeProperty bpd = getInlineContainer().getBlockProgressionDimension();
+ Property optimum = bpd.getOptimum(this);
+ int actualBPD = ElementListUtils.calcContentLength(childElements);
+ if (optimum.isAuto()) {
+ contentAreaBPD = actualBPD;
+ } else {
+ double bpdValue = optimum.getLength().getNumericValue(this);
+ if (bpdValue < 0) {
+ contentAreaBPD = actualBPD;
+ } else {
+ contentAreaBPD = (int) Math.round(bpdValue);
+ if (contentAreaBPD < actualBPD) {
+ BlockLevelEventProducer eventProducer = getBlockLevelEventProducer();
+ eventProducer.viewportBPDOverflow(this, fobj.getName(),
+ actualBPD - contentAreaBPD, needClip(), canRecoverFromOverflow(),
+ fobj.getLocator());
+ }
+ }
+ }
+ }
+
+ protected AlignmentContext makeAlignmentContext(LayoutContext context) {
+ InlineContainer ic = (InlineContainer) fobj;
+ AlignmentContext ac = new AlignmentContext(contentAreaBPD,
+ ic.getAlignmentAdjust(), ic.getAlignmentBaseline(),
+ ic.getBaselineShift(), ic.getDominantBaseline(),
+ context.getAlignmentContext());
+ int baselineOffset = getAlignmentPoint(ac.getDominantBaselineIdentifier());
+ ac.resizeLine(contentAreaBPD, baselineOffset);
+ return ac;
+ }
+
+ private void handleIPDOverflow() {
+ if (ipdOverflow > 0) {
+ BlockLevelEventProducer eventProducer = getBlockLevelEventProducer();
+ eventProducer.viewportIPDOverflow(this, fobj.getName(),
+ ipdOverflow, needClip(), canRecoverFromOverflow(),
+ fobj.getLocator());
+ }
+ }
+
+ private void wrapPositions(List<ListElement> elements) {
+ for (ListElement element : elements) {
+ Position position = new NonLeafPosition(this, element.getPosition());
+ notifyPos(position);
+ element.setPosition(position);
+ }
+ }
+
+ private BlockLevelEventProducer getBlockLevelEventProducer() {
+ return BlockLevelEventProducer.Provider.get(fobj.getUserAgent().getEventBroadcaster());
+ }
+
+ private boolean canRecoverFromOverflow() {
+ return getInlineContainer().getOverflow() != EN_ERROR_IF_OVERFLOW;
+ }
+
+ private int getAlignmentPoint(int dominantBaseline) {
+ Length alignmentAdjust = getInlineContainer().getAlignmentAdjust();
+ int baseline = alignmentAdjust.getEnum();
+ if (baseline == Constants.EN_AUTO) {
+ return getInlineContainerBaselineOffset(getInlineContainer().getAlignmentBaseline());
+ } else if (baseline == Constants.EN_BASELINE) {
+ return getInlineContainerBaselineOffset(dominantBaseline);
+ } else if (baseline != 0) {
+ return getInlineContainerBaselineOffset(baseline);
+ } else {
+ int baselineOffset = getInlineContainerBaselineOffset(dominantBaseline);
+ int lineHeight = getInlineContainer().getLineHeight().getOptimum(this).getLength().getValue(this);
+ int adjust = alignmentAdjust.getValue(
+ new SimplePercentBaseContext(null, LengthBase.ALIGNMENT_ADJUST, lineHeight));
+ return baselineOffset + adjust;
+ }
+ }
+
+ private int getInlineContainerBaselineOffset(int property) {
+ switch (property) {
+ case Constants.EN_BEFORE_EDGE:
+ case Constants.EN_TEXT_BEFORE_EDGE:
+ return 0;
+ case Constants.EN_AFTER_EDGE:
+ case Constants.EN_TEXT_AFTER_EDGE:
+ return contentAreaBPD;
+ case Constants.EN_MIDDLE:
+ case Constants.EN_CENTRAL:
+ case Constants.EN_MATHEMATICAL:
+ return contentAreaBPD / 2;
+ case Constants.EN_IDEOGRAPHIC:
+ return contentAreaBPD * 7 / 10;
+ case Constants.EN_ALPHABETIC:
+ return contentAreaBPD * 6 / 10;
+ case Constants.EN_HANGING:
+ return contentAreaBPD * 2 / 10;
+ case Constants.EN_AUTO:
+ case Constants.EN_BASELINE:
+ return hasLineAreaDescendant() ? getBaselineOffset() : contentAreaBPD;
+ default:
+ throw new AssertionError("Unknown baseline value: " + property);
+ }
+ }
+
+ @Override
+ public void addAreas(PositionIterator posIter, LayoutContext context) {
+ Position inlineContainerPosition = null;
+ while (posIter.hasNext()) {
+ /*
+ * Should iterate only once, but hasNext must be called twice for its
+ * side-effects to apply and the iterator to switch to the next LM.
+ */
+ assert inlineContainerPosition == null;
+ inlineContainerPosition = posIter.next();
+ assert inlineContainerPosition.getLM() == this;
+ }
+ assert inlineContainerPosition != null;
+ KnuthPossPosIter childPosIter = new KnuthPossPosIter(childElements);
+ AreaAdditionUtil.addAreas(this, childPosIter, context);
+ }
+
+ @Override
+ public Area getParentArea(Area childArea) {
+ if (referenceArea == null) {
+ referenceArea = new Container();
+ referenceArea.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
+ TraitSetter.setProducerID(referenceArea, fobj.getId());
+ referenceArea.setIPD(contentAreaIPD);
+ currentViewport = new InlineViewport(referenceArea);
+ currentViewport.addTrait(Trait.IS_VIEWPORT_AREA, Boolean.TRUE);
+ TraitSetter.setProducerID(currentViewport, fobj.getId());
+ currentViewport.setBlockProgressionOffset(alignmentContext.getOffset());
+ currentViewport.setIPD(getContentAreaIPD());
+ currentViewport.setBPD(getContentAreaBPD());
+ TraitSetter.addBackground(currentViewport, borderProps, this);
+ currentViewport.setClip(needClip());
+ currentViewport.setContentPosition(
+ new Rectangle2D.Float(0, 0, getContentAreaIPD(), getContentAreaBPD()));
+ getParent().addChildArea(currentViewport);
+ }
+ return referenceArea;
+ }
+
+ @Override
+ public int getContentAreaIPD() {
+ return contentAreaIPD;
+ }
+
+ @Override
+ public int getContentAreaBPD() {
+ return contentAreaBPD;
+ }
+
+ @Override
+ public void addChildArea(Area childArea) {
+ referenceArea.addChildArea(childArea);
+ }
+
+ private boolean needClip() {
+ int overflow = getInlineContainer().getOverflow();
+ return (overflow == EN_HIDDEN || overflow == EN_ERROR_IF_OVERFLOW);
+ }
+
+ public boolean handleOverflow(int milliPoints) {
+ ipdOverflow = Math.max(ipdOverflow, milliPoints);
+ return true;
+ }
+
+ public List addALetterSpaceTo(List oldList) {
+ return oldList;
+ }
+
+ public List addALetterSpaceTo(List oldList, int depth) {
+ return oldList;
+ }
+
+ public String getWordChars(Position pos) {
+ return "";
+ }
+
+ public void hyphenate(Position pos, HyphContext hyphContext) {
+ }
+
+ public boolean applyChanges(List oldList) {
+ return false;
+ }
+
+ public boolean applyChanges(List oldList, int depth) {
+ return false;
+ }
+
+ public List getChangedKnuthElements(List oldList, int alignment, int depth) {
+ return oldList;
+ }
+
+}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java
index 15284ae0a..332e14935 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.java
@@ -67,4 +67,13 @@ public interface InlineLevelEventProducer extends EventProducer {
*/
void lineOverflows(Object source, String elementName, int line, int overflowLength, Locator loc);
+ /**
+ * Auto IPD on inline-container is not supported.
+ *
+ * @param source the event source
+ * @param fallback the value in points that will be used as a fallback
+ * @event.severity WARN
+ */
+ void inlineContainerAutoIPDNotSupported(Object source, float fallback);
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml
index 66d352eb7..8d699f6bc 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLevelEventProducer.xml
@@ -20,4 +20,5 @@
<message key="locator">[ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]</message>
<message key="leaderWithoutContent">fo:leader is set to "use-content" but has no content.{{locator}}</message>
<message key="lineOverflows">The contents of {elementName} line {line} exceed the available area in the inline-progression direction by {overflowLength,choice,50000#{overflowLength} millipoints|50000&lt;more than 50 points}.{{locator}}</message>
+ <message key="inlineContainerAutoIPDNotSupported">A value of "auto" for the inline-progression-dimension property on fo:inline-container is not supported. Falling back to {fallback}pt.{{locator}}</message>
</catalogue>
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index b3987a075..25d8c0872 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -160,6 +160,8 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private final int follow;
private AlignmentContext alignmentContext;
+ private int baselineOffset = -1;
+
private List<KnuthSequence> knuthParagraphs;
private LineLayoutPossibilities lineLayouts;
@@ -556,7 +558,6 @@ public class LineLayoutManager extends InlineStackingLayoutManager
private int constantLineHeight = 12000;
-
/**
* Create a new Line Layout Manager.
* This is used by the block layout manager to create
@@ -939,7 +940,11 @@ public class LineLayoutManager extends InlineStackingLayoutManager
while (listIter.hasNext()) {
ListElement tempElement;
tempElement = (ListElement) listIter.next();
- if (tempElement.getLayoutManager() != this) {
+ LayoutManager lm = tempElement.getLayoutManager();
+ if (baselineOffset < 0 && lm != null && lm.hasLineAreaDescendant()) {
+ baselineOffset = lm.getBaselineOffset();
+ }
+ if (lm != this) {
tempElement.setPosition(notifyPos(new NonLeafPosition(this,
tempElement.getPosition())));
}
@@ -987,6 +992,9 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
startIndex = endIndex + 1;
LineBreakPosition lbp = (LineBreakPosition) llPoss.getChosenPosition(i);
+ if (baselineOffset < 0) {
+ baselineOffset = lbp.spaceBefore + lbp.baseline;
+ }
returnList.add(new KnuthBlockBox(
lbp.lineHeight + lbp.spaceBefore + lbp.spaceAfter,
footnoteList, lbp, false));
@@ -1424,6 +1432,16 @@ public class LineLayoutManager extends InlineStackingLayoutManager
}
}
+ @Override
+ public boolean hasLineAreaDescendant() {
+ return true;
+ }
+
+ @Override
+ public int getBaselineOffset() {
+ return baselineOffset;
+ }
+
/**
* Add the areas with the break points.
*
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index 53f51cd32..625b43ee5 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -30,12 +30,11 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.TextArea;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.util.CharScript;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FOText;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontSelector;
+import org.apache.fop.fonts.GlyphMapping;
import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
@@ -65,91 +64,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private static final int SOFT_HYPHEN_PENALTY = 1;
/**
- * Store information about each potential text area.
- * Index of character which ends the area, IPD of area, including
- * any word-space and letter-space.
- * Number of word-spaces?
- */
- private class AreaInfo {
-
- private final int startIndex;
- private final int breakIndex;
- private int wordCharLength;
- private final int wordSpaceCount;
- private int letterSpaceCount;
- private MinOptMax areaIPD;
- private final boolean isHyphenated;
- private final boolean isSpace;
- private boolean breakOppAfter;
- private final Font font;
- private final int level;
- private final int[][] gposAdjustments;
-
- AreaInfo(
- int startIndex, int breakIndex, int wordSpaceCount, int letterSpaceCount,
- MinOptMax areaIPD, boolean isHyphenated, boolean isSpace, boolean breakOppAfter,
- Font font, int level, int[][] gposAdjustments) {
- assert startIndex <= breakIndex;
- this.startIndex = startIndex;
- this.breakIndex = breakIndex;
- this.wordCharLength = -1;
- this.wordSpaceCount = wordSpaceCount;
- this.letterSpaceCount = letterSpaceCount;
- this.areaIPD = areaIPD;
- this.isHyphenated = isHyphenated;
- this.isSpace = isSpace;
- this.breakOppAfter = breakOppAfter;
- this.font = font;
- this.level = level;
- this.gposAdjustments = gposAdjustments;
- }
-
- /**
- * Obtain number of 'characters' contained in word. If word
- * is mapped, then this number may be less than or greater than the
- * original length (breakIndex - startIndex). We compute and
- * memoize thius length upon first invocation of this method.
- */
- private int getWordLength() {
- if (wordCharLength == -1) {
- if (foText.hasMapping(startIndex, breakIndex)) {
- wordCharLength = foText.getMapping(startIndex, breakIndex).length();
- } else {
- assert breakIndex >= startIndex;
- wordCharLength = breakIndex - startIndex;
- }
- }
- return wordCharLength;
- }
-
- private void addToAreaIPD(MinOptMax idp) {
- areaIPD = areaIPD.plus(idp);
- }
-
- public String toString() {
- return super.toString() + "{"
- + "interval = [" + startIndex + "," + breakIndex + "]"
- + ", isSpace = " + isSpace
- + ", level = " + level
- + ", areaIPD = " + areaIPD
- + ", letterSpaceCount = " + letterSpaceCount
- + ", wordSpaceCount = " + wordSpaceCount
- + ", isHyphenated = " + isHyphenated
- + ", font = " + font
- + "}";
- }
- }
-
- /**
* this class stores information about changes in vecAreaInfo which are not yet applied
*/
private final class PendingChange {
- private final AreaInfo areaInfo;
+ private final GlyphMapping mapping;
private final int index;
- private PendingChange(final AreaInfo areaInfo, final int index) {
- this.areaInfo = areaInfo;
+ private PendingChange(final GlyphMapping mapping, final int index) {
+ this.mapping = mapping;
this.index = index;
}
}
@@ -160,7 +83,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private static final Log LOG = LogFactory.getLog(TextLayoutManager.class);
// Hold all possible breaks for the text in this LM's FO.
- private final List areaInfos;
+ private final List<GlyphMapping> mappings;
/** Non-space characters on which we can end a line. */
private static final String BREAK_CHARS = "-/";
@@ -216,7 +139,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public TextLayoutManager(FOText node) {
foText = node;
letterSpaceAdjustArray = new MinOptMax[node.length() + 1];
- areaInfos = new ArrayList();
+ mappings = new ArrayList<GlyphMapping>();
}
private KnuthPenalty makeZeroWidthPenalty(int penaltyValue) {
@@ -274,61 +197,61 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public void addAreas(final PositionIterator posIter, final LayoutContext context) {
// Add word areas
- AreaInfo areaInfo;
+ GlyphMapping mapping;
int wordSpaceCount = 0;
int letterSpaceCount = 0;
- int firstAreaInfoIndex = -1;
- int lastAreaInfoIndex = 0;
+ int firstMappingIndex = -1;
+ int lastMappingIndex = 0;
MinOptMax realWidth = MinOptMax.ZERO;
/* On first area created, add any leading space.
* Calculate word-space stretch value.
*/
- AreaInfo lastAreaInfo = null;
+ GlyphMapping lastMapping = null;
while (posIter.hasNext()) {
final LeafPosition tbpNext = (LeafPosition) posIter.next();
if (tbpNext == null) {
continue; //Ignore elements without Positions
}
if (tbpNext.getLeafPos() != -1) {
- areaInfo = (AreaInfo) areaInfos.get(tbpNext.getLeafPos());
- if (lastAreaInfo == null
- || (areaInfo.font != lastAreaInfo.font)
- || (areaInfo.level != lastAreaInfo.level)) {
- if (lastAreaInfo != null) {
- addAreaInfoAreas(lastAreaInfo, wordSpaceCount,
- letterSpaceCount, firstAreaInfoIndex,
- lastAreaInfoIndex, realWidth, context);
+ mapping = mappings.get(tbpNext.getLeafPos());
+ if (lastMapping == null
+ || (mapping.font != lastMapping.font)
+ || (mapping.level != lastMapping.level)) {
+ if (lastMapping != null) {
+ addMappingAreas(lastMapping, wordSpaceCount,
+ letterSpaceCount, firstMappingIndex,
+ lastMappingIndex, realWidth, context);
}
- firstAreaInfoIndex = tbpNext.getLeafPos();
+ firstMappingIndex = tbpNext.getLeafPos();
wordSpaceCount = 0;
letterSpaceCount = 0;
realWidth = MinOptMax.ZERO;
}
- wordSpaceCount += areaInfo.wordSpaceCount;
- letterSpaceCount += areaInfo.letterSpaceCount;
- realWidth = realWidth.plus(areaInfo.areaIPD);
- lastAreaInfoIndex = tbpNext.getLeafPos();
- lastAreaInfo = areaInfo;
+ wordSpaceCount += mapping.wordSpaceCount;
+ letterSpaceCount += mapping.letterSpaceCount;
+ realWidth = realWidth.plus(mapping.areaIPD);
+ lastMappingIndex = tbpNext.getLeafPos();
+ lastMapping = mapping;
}
}
- if (lastAreaInfo != null) {
- addAreaInfoAreas(lastAreaInfo, wordSpaceCount, letterSpaceCount, firstAreaInfoIndex,
- lastAreaInfoIndex, realWidth, context);
+ if (lastMapping != null) {
+ addMappingAreas(lastMapping, wordSpaceCount, letterSpaceCount, firstMappingIndex,
+ lastMappingIndex, realWidth, context);
}
}
- private void addAreaInfoAreas(AreaInfo areaInfo, int wordSpaceCount, int letterSpaceCount,
- int firstAreaInfoIndex, int lastAreaInfoIndex,
+ private void addMappingAreas(GlyphMapping mapping, int wordSpaceCount, int letterSpaceCount,
+ int firstMappingIndex, int lastMappingIndex,
MinOptMax realWidth, LayoutContext context) {
// TODO: These two statements (if, for) were like this before my recent
- // changes. However, it seems as if they should use the AreaInfo from
- // firstAreaInfoIndex.. lastAreaInfoIndex rather than just the last areaInfo.
+ // changes. However, it seems as if they should use the GlyphMapping from
+ // firstMappingIndex.. lastMappingIndex rather than just the last mapping.
// This needs to be checked.
- int textLength = areaInfo.getWordLength();
- if (areaInfo.letterSpaceCount == textLength && !areaInfo.isHyphenated
+ int textLength = mapping.getWordLength();
+ if (mapping.letterSpaceCount == textLength && !mapping.isHyphenated
&& context.isLastArea()) {
// the line ends at a character like "/" or "-";
// remove the letter space after the last character
@@ -336,7 +259,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
letterSpaceCount--;
}
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
MinOptMax letterSpaceAdjustment = letterSpaceAdjustArray[i + 1];
if (letterSpaceAdjustment != null && letterSpaceAdjustment.isElastic()) {
letterSpaceCount++;
@@ -344,7 +267,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
// add hyphenation character if the last word is hyphenated
- if (context.isLastArea() && areaInfo.isHyphenated) {
+ if (context.isLastArea() && mapping.isHyphenated) {
realWidth = realWidth.plus(hyphIPD);
}
@@ -385,8 +308,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
totalAdjust = difference;
}
- TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstAreaInfoIndex,
- lastAreaInfoIndex, context.isLastArea(), areaInfo.font).build();
+ TextArea textArea = new TextAreaBuilder(realWidth, totalAdjust, context, firstMappingIndex,
+ lastMappingIndex, context.isLastArea(), mapping.font).build();
// wordSpaceDim is computed in relation to wordSpaceIPD.opt
// but the renderer needs to know the adjustment in relation
@@ -417,15 +340,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
private final MinOptMax width; // content ipd
private final int adjust; // content ipd adjustment
private final LayoutContext context; // layout context
- private final int firstIndex; // index of first AreaInfo
- private final int lastIndex; // index of last AreaInfo
+ private final int firstIndex; // index of first GlyphMapping
+ private final int lastIndex; // index of last GlyphMapping
private final boolean isLastArea; // true if last inline area in line area
private final Font font; // applicable font
// other, non-constructor state
private TextArea textArea; // text area being constructed
private int blockProgressionDimension; // calculated bpd
- private AreaInfo areaInfo; // current area info when iterating over words
+ private GlyphMapping mapping; // current mapping when iterating over words
private StringBuffer wordChars; // current word's character buffer
private int[] letterSpaceAdjust; // current word's letter space adjustments
private int letterSpaceAdjustIndex; // last written letter space adjustment index
@@ -442,8 +365,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* @param width the MinOptMax width of the content
* @param adjust the total ipd adjustment with respect to the optimal width
* @param context the layout context
- * @param firstIndex the index of the first AreaInfo used for the TextArea
- * @param lastIndex the index of the last AreaInfo used for the TextArea
+ * @param firstIndex the index of the first GlyphMapping used for the TextArea
+ * @param lastIndex the index of the last GlyphMapping used for the TextArea
* @param isLastArea is this TextArea the last in a line?
* @param font Font to be used in this particular TextArea
*/
@@ -516,30 +439,30 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* Sets the text of the TextArea, split into words and spaces.
*/
private void setText() {
- int areaInfoIndex = -1;
+ int mappingIndex = -1;
int wordCharLength = 0;
for (int wordIndex = firstIndex; wordIndex <= lastIndex; wordIndex++) {
- areaInfo = getAreaInfo(wordIndex);
- if (areaInfo.isSpace) {
+ mapping = getGlyphMapping(wordIndex);
+ if (mapping.isSpace) {
addSpaces();
} else {
- // areaInfo stores information about a word fragment
- if (areaInfoIndex == -1) {
+ // mapping stores information about a word fragment
+ if (mappingIndex == -1) {
// here starts a new word
- areaInfoIndex = wordIndex;
+ mappingIndex = wordIndex;
wordCharLength = 0;
}
- wordCharLength += areaInfo.getWordLength();
+ wordCharLength += mapping.getWordLength();
if (isWordEnd(wordIndex)) {
- addWord(areaInfoIndex, wordIndex, wordCharLength);
- areaInfoIndex = -1;
+ addWord(mappingIndex, wordIndex, wordCharLength);
+ mappingIndex = -1;
}
}
}
}
- private boolean isWordEnd(int areaInfoIndex) {
- return areaInfoIndex == lastIndex || getAreaInfo(areaInfoIndex + 1).isSpace;
+ private boolean isWordEnd(int mappingIndex) {
+ return mappingIndex == lastIndex || getGlyphMapping(mappingIndex + 1).isSpace;
}
/**
@@ -564,10 +487,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// iterate over word's fragments, adding word chars (with bidi
// levels), letter space adjustments, and glyph position adjustments
for (int i = startIndex; i <= endIndex; i++) {
- AreaInfo wordAreaInfo = getAreaInfo(i);
- addWordChars(wordAreaInfo);
- addLetterAdjust(wordAreaInfo);
- if (addGlyphPositionAdjustments(wordAreaInfo)) {
+ GlyphMapping wordMapping = getGlyphMapping(i);
+ addWordChars(wordMapping);
+ addLetterAdjust(wordMapping);
+ if (addGlyphPositionAdjustments(wordMapping)) {
gposAdjusted = true;
}
}
@@ -617,7 +540,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
private boolean isHyphenated(int endIndex) {
- return isLastArea && endIndex == lastIndex && areaInfo.isHyphenated;
+ return isLastArea && endIndex == lastIndex && mapping.isHyphenated;
}
private void addHyphenationChar() {
@@ -632,21 +555,54 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
* (1) concatenate (possibly mapped) word characters to word character buffer;
* (2) concatenante (possibly mapped) word bidi levels to levels buffer;
* (3) update word's IPD with optimal IPD of fragment.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
*/
- private void addWordChars(AreaInfo wordAreaInfo) {
- int s = wordAreaInfo.startIndex;
- int e = wordAreaInfo.breakIndex;
- if (foText.hasMapping(s, e)) {
- wordChars.append(foText.getMapping(s, e));
- addWordLevels(foText.getMappingBidiLevels(s, e));
+ private void addWordChars(GlyphMapping wordMapping) {
+ int s = wordMapping.startIndex;
+ int e = wordMapping.endIndex;
+ if (wordMapping.mapping != null) {
+ wordChars.append(wordMapping.mapping);
+ addWordLevels(getMappingBidiLevels(wordMapping));
} else {
for (int i = s; i < e; i++) {
wordChars.append(foText.charAt(i));
}
addWordLevels(foText.getBidiLevels(s, e));
}
- wordIPD += wordAreaInfo.areaIPD.getOpt();
+ wordIPD += wordMapping.areaIPD.getOpt();
+ }
+
+ /**
+ * Obtain bidirectional levels of mapping of characters over specific interval.
+ * @param start index in character buffer
+ * @param end index in character buffer
+ * @return a (possibly empty) array of bidi levels or null
+ * in case no bidi levels have been assigned
+ */
+ private int[] getMappingBidiLevels(GlyphMapping mapping) {
+ if (mapping.mapping != null) {
+ int nc = mapping.endIndex - mapping.startIndex;
+ int nm = mapping.mapping.length();
+ int[] la = foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+ if (la == null) {
+ return null;
+ } else if (nm == nc) { // mapping is same length as mapped range
+ return la;
+ } else if (nm > nc) { // mapping is longer than mapped range
+ int[] ma = new int[nm];
+ System.arraycopy(la, 0, ma, 0, la.length);
+ for (int i = la.length, n = ma.length, l = (i > 0) ? la[i - 1] : 0; i < n; i++) {
+ ma[i] = l;
+ }
+ return ma;
+ } else { // mapping is shorter than mapped range
+ int[] ma = new int[nm];
+ System.arraycopy(la, 0, ma, 0, ma.length);
+ return ma;
+ }
+ } else {
+ return foText.getBidiLevels(mapping.startIndex, mapping.endIndex);
+ }
}
/**
@@ -672,16 +628,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/**
* Given a word area info associated with a word fragment,
* concatenate letter space adjustments for each (possibly mapped) character.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
*/
- private void addLetterAdjust(AreaInfo wordAreaInfo) {
- int letterSpaceCount = wordAreaInfo.letterSpaceCount;
- int wordLength = wordAreaInfo.getWordLength();
+ private void addLetterAdjust(GlyphMapping wordMapping) {
+ int letterSpaceCount = wordMapping.letterSpaceCount;
+ int wordLength = wordMapping.getWordLength();
int taAdjust = textArea.getTextLetterSpaceAdjust();
for (int i = 0, n = wordLength; i < n; i++) {
int j = letterSpaceAdjustIndex + i;
if (j > 0) {
- int k = wordAreaInfo.startIndex + i;
+ int k = wordMapping.startIndex + i;
MinOptMax adj = (k < letterSpaceAdjustArray.length)
? letterSpaceAdjustArray [ k ] : null;
letterSpaceAdjust [ j ] = (adj == null) ? 0 : adj.getOpt();
@@ -697,14 +653,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/**
* Given a word area info associated with a word fragment,
* concatenate glyph position adjustments for each (possibly mapped) character.
- * @param wordAreaInfo fragment info
+ * @param wordMapping fragment info
* @return true if an adjustment was non-zero
*/
- private boolean addGlyphPositionAdjustments(AreaInfo wordAreaInfo) {
+ private boolean addGlyphPositionAdjustments(GlyphMapping wordMapping) {
boolean adjusted = false;
- int[][] gpa = wordAreaInfo.gposAdjustments;
+ int[][] gpa = wordMapping.gposAdjustments;
int numAdjusts = (gpa != null) ? gpa.length : 0;
- int wordLength = wordAreaInfo.getWordLength();
+ int wordLength = wordMapping.getWordLength();
if (numAdjusts > 0) {
int need = gposAdjustmentsIndex + numAdjusts;
if (need <= gposAdjustments.length) {
@@ -733,7 +689,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
/**
- * The <code>AreaInfo</code> stores information about spaces.
+ * The <code>GlyphMapping</code> stores information about spaces.
* <p/>
* Add the spaces - except zero-width spaces - to the TextArea.
*/
@@ -743,16 +699,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// divide the area info's allocated IPD evenly among the
// non-zero-width space characters
int numZeroWidthSpaces = 0;
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
char spaceChar = foText.charAt(i);
if (CharUtilities.isZeroWidthSpace(spaceChar)) {
numZeroWidthSpaces++;
}
}
- int numSpaces = areaInfo.breakIndex - areaInfo.startIndex - numZeroWidthSpaces;
- int spaceIPD = areaInfo.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
+ int numSpaces = mapping.endIndex - mapping.startIndex - numZeroWidthSpaces;
+ int spaceIPD = mapping.areaIPD.getOpt() / ((numSpaces > 0) ? numSpaces : 1);
// add space area children, one for each non-zero-width space character
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
char spaceChar = foText.charAt(i);
int level = foText.bidiLevelAt(i);
if (!CharUtilities.isZeroWidthSpace(spaceChar)) {
@@ -766,39 +722,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
- private void addAreaInfo(AreaInfo ai) {
- addAreaInfo(areaInfos.size(), ai);
+ private void addGlyphMapping(GlyphMapping mapping) {
+ addGlyphMapping(mappings.size(), mapping);
}
- private void addAreaInfo(int index, AreaInfo ai) {
- areaInfos.add(index, ai);
+ private void addGlyphMapping(int index, GlyphMapping mapping) {
+ mappings.add(index, mapping);
}
- private void removeAreaInfo(int index) {
- areaInfos.remove(index);
+ private void removeGlyphMapping(int index) {
+ mappings.remove(index);
}
- private AreaInfo getAreaInfo(int index) {
- return (AreaInfo) areaInfos.get(index);
- }
-
- private void addToLetterAdjust(int index, int width) {
- if (letterSpaceAdjustArray[index] == null) {
- letterSpaceAdjustArray[index] = MinOptMax.getInstance(width);
- } else {
- letterSpaceAdjustArray[index] = letterSpaceAdjustArray[index].plus(width);
- }
- }
-
- /**
- * Indicates whether a character is a space in terms of this layout manager.
- * @param ch the character
- * @return true if it's a space
- */
- private static boolean isSpace(final char ch) {
- return ch == CharUtilities.SPACE
- || CharUtilities.isNonBreakableSpace(ch)
- || CharUtilities.isFixedWidthSpace(ch);
+ private GlyphMapping getGlyphMapping(int index) {
+ return mappings.get(index);
}
/** {@inheritDoc} */
@@ -810,8 +747,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
final List returnList = new LinkedList();
KnuthSequence sequence = new InlineKnuthSequence();
- AreaInfo areaInfo = null;
- AreaInfo prevAreaInfo = null;
+ GlyphMapping mapping = null;
+ GlyphMapping prevMapping = null;
returnList.add(sequence);
if (LOG.isDebugEnabled()) {
@@ -857,24 +794,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
if (inWord) {
if (breakOpportunity
- || TextLayoutManager.isSpace(ch)
+ || GlyphMapping.isSpace(ch)
|| CharUtilities.isExplicitBreak(ch)
|| ((prevLevel != -1) && (level != prevLevel))) {
// this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN
- prevAreaInfo = processWord(alignment, sequence, prevAreaInfo, ch,
+ prevMapping = processWord(alignment, sequence, prevMapping, ch,
breakOpportunity, true, prevLevel);
}
} else if (inWhitespace) {
if (ch != CharUtilities.SPACE || breakOpportunity) {
- prevAreaInfo = processWhitespace(alignment, sequence,
+ prevMapping = processWhitespace(alignment, sequence,
breakOpportunity, prevLevel);
}
} else {
- if (areaInfo != null) {
- prevAreaInfo = areaInfo;
- processLeftoverAreaInfo(alignment, sequence, areaInfo,
+ if (mapping != null) {
+ prevMapping = mapping;
+ processLeftoverGlyphMapping(alignment, sequence, mapping,
ch == CharUtilities.SPACE || breakOpportunity);
- areaInfo = null;
+ mapping = null;
}
if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
sequence = processLinebreak(returnList, sequence);
@@ -888,15 +825,15 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
this.foText, this);
font.mapChar(ch);
// preserved space or non-breaking space:
- // create the AreaInfo object
- areaInfo = new AreaInfo(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
+ // create the GlyphMapping object
+ mapping = new GlyphMapping(nextStart, nextStart + 1, 1, 0, wordSpaceIPD, false, true,
breakOpportunity, spaceFont, level, null);
thisStart = nextStart + 1;
} else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
- // create the AreaInfo object
+ // create the GlyphMapping object
Font font = FontSelector.selectFontForCharacterInText(ch, foText, this);
MinOptMax ipd = MinOptMax.getInstance(font.getCharWidth(ch));
- areaInfo = new AreaInfo(nextStart, nextStart + 1, 0, 0, ipd, false, true,
+ mapping = new GlyphMapping(nextStart, nextStart + 1, 0, 0, ipd, false, true,
breakOpportunity, font, level, null);
thisStart = nextStart + 1;
} else if (CharUtilities.isExplicitBreak(ch)) {
@@ -904,7 +841,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
thisStart = nextStart + 1;
}
- inWord = !TextLayoutManager.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
+ inWord = !GlyphMapping.isSpace(ch) && !CharUtilities.isExplicitBreak(ch);
inWhitespace = ch == CharUtilities.SPACE
&& foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
prevLevel = level;
@@ -913,11 +850,11 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// Process any last elements
if (inWord) {
- processWord(alignment, sequence, prevAreaInfo, ch, false, false, prevLevel);
+ processWord(alignment, sequence, prevMapping, ch, false, false, prevLevel);
} else if (inWhitespace) {
processWhitespace(alignment, sequence, !keepTogether, prevLevel);
- } else if (areaInfo != null) {
- processLeftoverAreaInfo(alignment, sequence, areaInfo,
+ } else if (mapping != null) {
+ processLeftoverGlyphMapping(alignment, sequence, mapping,
ch == CharUtilities.ZERO_WIDTH_SPACE);
} else if (CharUtilities.isExplicitBreak(ch)) {
this.processLinebreak(returnList, sequence);
@@ -948,15 +885,14 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
return sequence;
}
- private void processLeftoverAreaInfo(int alignment,
- KnuthSequence sequence, AreaInfo areaInfo,
- boolean breakOpportunityAfter) {
- addAreaInfo(areaInfo);
- areaInfo.breakOppAfter = breakOpportunityAfter;
- addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ private void processLeftoverGlyphMapping(int alignment, KnuthSequence sequence,
+ GlyphMapping mapping, boolean breakOpportunityAfter) {
+ addGlyphMapping(mapping);
+ mapping.breakOppAfter = breakOpportunityAfter;
+ addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
}
- private AreaInfo processWhitespace(final int alignment,
+ private GlyphMapping processWhitespace(final int alignment,
final KnuthSequence sequence, final boolean breakOpportunity, int level) {
if (LOG.isDebugEnabled()) {
@@ -964,209 +900,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
// End of whitespace
- // create the AreaInfo object
+ // create the GlyphMapping object
assert nextStart >= thisStart;
- AreaInfo areaInfo = new AreaInfo(
- thisStart, nextStart, nextStart - thisStart, 0,
+ GlyphMapping mapping = new GlyphMapping(
+ thisStart, nextStart, nextStart - thisStart, 0,
wordSpaceIPD.mult(nextStart - thisStart),
false, true, breakOpportunity, spaceFont, level, null);
- addAreaInfo(areaInfo);
+ addGlyphMapping(mapping);
// create the elements
- addElementsForASpace(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ addElementsForASpace(sequence, alignment, mapping, mappings.size() - 1);
thisStart = nextStart;
- return areaInfo;
- }
-
- private AreaInfo processWordMapping(
- int lastIndex, final Font font, AreaInfo prevAreaInfo, final char breakOpportunityChar,
- final boolean endsWithHyphen, int level) {
- int s = this.thisStart; // start index of word in FOText character buffer
- int e = lastIndex; // end index of word in FOText character buffer
- int nLS = 0; // # of letter spaces
- String script = foText.getScript();
- String language = foText.getLanguage();
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
- + " +M"
- + ", level = " + level
- + " }");
- }
-
- // 1. extract unmapped character sequence
- CharSequence ics = foText.subSequence(s, e);
-
- // 2. if script is not specified (by FO property) or it is specified as 'auto',
- // then compute dominant script
- if ((script == null) || "auto".equals(script)) {
- script = CharScript.scriptTagFromCode(CharScript.dominantScript(ics));
- }
- if ((language == null) || "none".equals(language)) {
- language = "dflt";
- }
-
- // 3. perform mapping of chars to glyphs ... to glyphs ... to chars
- CharSequence mcs = font.performSubstitution(ics, script, language);
-
- // 4. compute glyph position adjustments on (substituted) characters
- int[][] gpa;
- if (font.performsPositioning()) {
- // handle GPOS adjustments
- gpa = font.performPositioning(mcs, script, language);
- } else if (font.hasKerning()) {
- // handle standard (non-GPOS) kerning adjustments
- gpa = getKerningAdjustments(mcs, font);
- } else {
- gpa = null;
- }
-
- // 5. reorder combining marks so that they precede (within the mapped char sequence) the
- // base to which they are applied; N.B. position adjustments (gpa) are reordered in place
- mcs = font.reorderCombiningMarks(mcs, gpa, script, language);
-
- // 6. if mapped sequence differs from input sequence, then memoize mapped sequence
- if (!CharUtilities.isSameSequence(mcs, ics)) {
- foText.addMapping(s, e, mcs);
- }
-
- // 7. compute word ipd based on final position adjustments
- MinOptMax ipd = MinOptMax.ZERO;
- for (int i = 0, n = mcs.length(); i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- int w = font.getCharWidth(c);
- if (w < 0) {
- w = 0;
- }
- if (gpa != null) {
- w += gpa [ i ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ];
- }
- ipd = ipd.plus(w);
- }
-
- // [TBD] - handle letter spacing
-
- return new AreaInfo(
- s, e, 0, nLS, ipd, endsWithHyphen, false,
- breakOpportunityChar != 0, font, level, gpa);
- }
-
- /**
- * Given a mapped character sequence MCS, obtain glyph position adjustments
- * from the font's kerning data.
- * @param mcs mapped character sequence
- * @param font applicable font
- * @return glyph position adjustments (or null if no kerning)
- */
- private int[][] getKerningAdjustments(CharSequence mcs, final Font font) {
- int nc = mcs.length();
- // extract kerning array
- int[] ka = new int [ nc ]; // kerning array
- for (int i = 0, n = nc, cPrev = -1; i < n; i++) {
- int c = mcs.charAt(i);
- // TODO !BMP
- if (cPrev >= 0) {
- ka[i] = font.getKernValue(cPrev, c);
- }
- cPrev = c;
- }
- // was there a non-zero kerning?
- boolean hasKerning = false;
- for (int i = 0, n = nc; i < n; i++) {
- if (ka[i] != 0) {
- hasKerning = true;
- break;
- }
- }
- // if non-zero kerning, then create and return glyph position adjustment array
- if (hasKerning) {
- int[][] gpa = new int [ nc ] [ 4 ];
- for (int i = 0, n = nc; i < n; i++) {
- if (i > 0) {
- gpa [ i - 1 ] [ GlyphPositioningTable.Value.IDX_X_ADVANCE ] = ka [ i ];
- }
- }
- return gpa;
- } else {
- return null;
- }
+ return mapping;
}
- private AreaInfo processWordNoMapping(int lastIndex, final Font font, AreaInfo prevAreaInfo,
- final char breakOpportunityChar, final boolean endsWithHyphen, int level) {
- boolean kerning = font.hasKerning();
- MinOptMax wordIPD = MinOptMax.ZERO;
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("PW: [" + thisStart + "," + lastIndex + "]: {"
- + " -M"
- + ", level = " + level
- + " }");
- }
-
- for (int i = thisStart; i < lastIndex; i++) {
- char currentChar = foText.charAt(i);
-
- //character width
- int charWidth = font.getCharWidth(currentChar);
- wordIPD = wordIPD.plus(charWidth);
-
- //kerning
- if (kerning) {
- int kern = 0;
- if (i > thisStart) {
- char previousChar = foText.charAt(i - 1);
- kern = font.getKernValue(previousChar, currentChar);
- } else if (prevAreaInfo != null
- && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
- char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
- kern = font.getKernValue(previousChar, currentChar);
- }
- if (kern != 0) {
- addToLetterAdjust(i, kern);
- wordIPD = wordIPD.plus(kern);
- }
- }
- }
- if (kerning
- && (breakOpportunityChar != 0)
- && !TextLayoutManager.isSpace(breakOpportunityChar)
- && lastIndex > 0
- && endsWithHyphen) {
- int kern = font.getKernValue(foText.charAt(lastIndex - 1), breakOpportunityChar);
- if (kern != 0) {
- addToLetterAdjust(lastIndex, kern);
- //TODO: add kern to wordIPD?
- }
- }
- // shy+chars at start of word: wordLength == 0 && breakOpportunity
- // shy only characters in word: wordLength == 0 && !breakOpportunity
- int wordLength = lastIndex - thisStart;
- int letterSpaces = 0;
- if (wordLength != 0) {
- letterSpaces = wordLength - 1;
- // if there is a break opportunity and the next one (break character)
- // is not a space, it could be used as a line end;
- // add one more letter space, in case other text follows
- if ((breakOpportunityChar != 0) && !TextLayoutManager.isSpace(breakOpportunityChar)) {
- letterSpaces++;
- }
- }
- assert letterSpaces >= 0;
- wordIPD = wordIPD.plus(letterSpaceIPD.mult(letterSpaces));
-
- // create and return the AreaInfo object
- return new AreaInfo(thisStart, lastIndex, 0,
- letterSpaces, wordIPD,
- endsWithHyphen,
- false, breakOpportunityChar != 0, font, level, null);
- }
-
- private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
- AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity,
+ private GlyphMapping processWord(final int alignment, final KnuthSequence sequence,
+ GlyphMapping prevMapping, final char ch, final boolean breakOpportunity,
final boolean checkEndsWithHyphen, int level) {
//Word boundary found, process widths and kerning
@@ -1178,23 +929,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
&& foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
Font font = FontSelector.selectFontForCharactersInText(
foText, thisStart, lastIndex, foText, this);
- AreaInfo areaInfo;
- if (font.performsSubstitution() || font.performsPositioning()) {
- areaInfo = processWordMapping(
- lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
- } else {
- areaInfo = processWordNoMapping(
- lastIndex, font, prevAreaInfo, breakOpportunity ? ch : 0, endsWithHyphen, level);
- }
- prevAreaInfo = areaInfo;
- addAreaInfo(areaInfo);
+ char breakOpportunityChar = breakOpportunity ? ch : 0;
+ char precedingChar = prevMapping != null && !prevMapping.isSpace
+ && prevMapping.endIndex > 0 ? foText.charAt(prevMapping.endIndex - 1) : 0;
+ GlyphMapping mapping = GlyphMapping.doGlyphMapping(foText, thisStart, lastIndex, font,
+ letterSpaceIPD, letterSpaceAdjustArray, precedingChar, breakOpportunityChar, endsWithHyphen, level);
+ prevMapping = mapping;
+ addGlyphMapping(mapping);
tempStart = nextStart;
//add the elements
- addElementsForAWordFragment(sequence, alignment, areaInfo, areaInfos.size() - 1);
+ addElementsForAWordFragment(sequence, alignment, mapping, mappings.size() - 1);
thisStart = nextStart;
- return prevAreaInfo;
+ return prevMapping;
}
/** {@inheritDoc} */
@@ -1214,9 +962,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
int index = leafPos.getLeafPos();
//element could refer to '-1' position, for non-collapsed spaces (?)
if (index > -1) {
- AreaInfo areaInfo = getAreaInfo(index);
- areaInfo.letterSpaceCount++;
- areaInfo.addToAreaIPD(letterSpaceIPD);
+ GlyphMapping mapping = getGlyphMapping(index);
+ mapping.letterSpaceCount++;
+ mapping.addToAreaIPD(letterSpaceIPD);
if (TextLayoutManager.BREAK_CHARS.indexOf(foText.charAt(tempStart - 1)) >= 0) {
// the last character could be used as a line break
// append new elements to oldList
@@ -1227,13 +975,13 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
} else if (letterSpaceIPD.isStiff()) {
// constant letter space: replace the box
// give it the unwrapped position of the replaced element
- oldListIterator.set(new KnuthInlineBox(areaInfo.areaIPD.getOpt(),
+ oldListIterator.set(new KnuthInlineBox(mapping.areaIPD.getOpt(),
alignmentContext, pos, false));
} else {
// adjustable letter space: replace the glue
oldListIterator.next(); // this would return the penalty element
oldListIterator.next(); // this would return the glue element
- oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(areaInfo.letterSpaceCount),
+ oldListIterator.set(new KnuthGlue(letterSpaceIPD.mult(mapping.letterSpaceCount),
auxiliaryPosition, true));
}
}
@@ -1242,26 +990,26 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
/** {@inheritDoc} */
public void hyphenate(Position pos, HyphContext hyphContext) {
- AreaInfo areaInfo = getAreaInfo(((LeafPosition) pos).getLeafPos() + changeOffset);
- int startIndex = areaInfo.startIndex;
+ GlyphMapping mapping = getGlyphMapping(((LeafPosition) pos).getLeafPos() + changeOffset);
+ int startIndex = mapping.startIndex;
int stopIndex;
boolean nothingChanged = true;
- Font font = areaInfo.font;
+ Font font = mapping.font;
- while (startIndex < areaInfo.breakIndex) {
+ while (startIndex < mapping.endIndex) {
MinOptMax newIPD = MinOptMax.ZERO;
boolean hyphenFollows;
stopIndex = startIndex + hyphContext.getNextHyphPoint();
- if (hyphContext.hasMoreHyphPoints() && stopIndex <= areaInfo.breakIndex) {
+ if (hyphContext.hasMoreHyphPoints() && stopIndex <= mapping.endIndex) {
// stopIndex is the index of the first character
// after a hyphenation point
hyphenFollows = true;
} else {
// there are no more hyphenation points,
- // or the next one is after areaInfo.breakIndex
+ // or the next one is after mapping.breakIndex
hyphenFollows = false;
- stopIndex = areaInfo.breakIndex;
+ stopIndex = mapping.endIndex;
}
hyphContext.updateOffset(stopIndex - startIndex);
@@ -1286,18 +1034,18 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// add letter spaces
boolean isWordEnd
- = (stopIndex == areaInfo.breakIndex)
- && (areaInfo.letterSpaceCount < areaInfo.getWordLength());
+ = (stopIndex == mapping.endIndex)
+ && (mapping.letterSpaceCount < mapping.getWordLength());
int letterSpaceCount = isWordEnd ? stopIndex - startIndex - 1 : stopIndex - startIndex;
assert letterSpaceCount >= 0;
newIPD = newIPD.plus(letterSpaceIPD.mult(letterSpaceCount));
- if (!(nothingChanged && stopIndex == areaInfo.breakIndex && !hyphenFollows)) {
- // the new AreaInfo object is not equal to the old one
+ if (!(nothingChanged && stopIndex == mapping.endIndex && !hyphenFollows)) {
+ // the new GlyphMapping object is not equal to the old one
changeList.add(
new PendingChange(
- new AreaInfo(startIndex, stopIndex, 0,
+ new GlyphMapping(startIndex, stopIndex, 0,
letterSpaceCount, newIPD, hyphenFollows,
false, false, font, -1, null),
((LeafPosition) pos).getLeafPos() + changeOffset));
@@ -1324,7 +1072,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
return false;
}
- // Find the first and last positions in oldList that point to an AreaInfo
+ // Find the first and last positions in oldList that point to a GlyphMapping
// (i.e. getLeafPos() != -1)
LeafPosition startPos = null;
LeafPosition endPos = null;
@@ -1349,8 +1097,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
returnedIndices[0] = (startPos != null ? startPos.getLeafPos() : -1) + changeOffset;
returnedIndices[1] = (endPos != null ? endPos.getLeafPos() : -1) + changeOffset;
- int areaInfosAdded = 0;
- int areaInfosRemoved = 0;
+ int mappingsAdded = 0;
+ int mappingsRemoved = 0;
if (!changeList.isEmpty()) {
int oldIndex = -1;
@@ -1360,24 +1108,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
while (changeListIterator.hasNext()) {
currChange = (PendingChange) changeListIterator.next();
if (currChange.index == oldIndex) {
- areaInfosAdded++;
- changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
+ mappingsAdded++;
+ changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
} else {
- areaInfosRemoved++;
- areaInfosAdded++;
+ mappingsRemoved++;
+ mappingsAdded++;
oldIndex = currChange.index;
- changeIndex = currChange.index + areaInfosAdded - areaInfosRemoved;
- removeAreaInfo(changeIndex);
+ changeIndex = currChange.index + mappingsAdded - mappingsRemoved;
+ removeGlyphMapping(changeIndex);
}
- addAreaInfo(changeIndex, currChange.areaInfo);
+ addGlyphMapping(changeIndex, currChange.mapping);
}
changeList.clear();
}
// increase the end index for getChangedKnuthElements()
- returnedIndices[1] += (areaInfosAdded - areaInfosRemoved);
+ returnedIndices[1] += (mappingsAdded - mappingsRemoved);
// increase offset to use for subsequent paragraphs
- changeOffset += (areaInfosAdded - areaInfosRemoved);
+ changeOffset += (mappingsAdded - mappingsRemoved);
return hasChanged;
}
@@ -1391,16 +1139,16 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
final LinkedList returnList = new LinkedList();
for (; returnedIndices[0] <= returnedIndices[1]; returnedIndices[0]++) {
- AreaInfo areaInfo = getAreaInfo(returnedIndices[0]);
- if (areaInfo.wordSpaceCount == 0) {
- // areaInfo refers either to a word or a word fragment
- addElementsForAWordFragment(returnList, alignment, areaInfo, returnedIndices[0]);
+ GlyphMapping mapping = getGlyphMapping(returnedIndices[0]);
+ if (mapping.wordSpaceCount == 0) {
+ // mapping refers either to a word or a word fragment
+ addElementsForAWordFragment(returnList, alignment, mapping, returnedIndices[0]);
} else {
- // areaInfo refers to a space
- addElementsForASpace(returnList, alignment, areaInfo, returnedIndices[0]);
+ // mapping refers to a space
+ addElementsForASpace(returnList, alignment, mapping, returnedIndices[0]);
}
}
- setFinished(returnedIndices[0] == areaInfos.size() - 1);
+ setFinished(returnedIndices[0] == mappings.size() - 1);
//ElementListObserver.observe(returnList, "text-changed", null);
return returnList;
}
@@ -1409,9 +1157,9 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
public String getWordChars(Position pos) {
int leafValue = ((LeafPosition) pos).getLeafPos() + changeOffset;
if (leafValue != -1) {
- AreaInfo areaInfo = getAreaInfo(leafValue);
- StringBuffer buffer = new StringBuffer(areaInfo.getWordLength());
- for (int i = areaInfo.startIndex; i < areaInfo.breakIndex; i++) {
+ GlyphMapping mapping = getGlyphMapping(leafValue);
+ StringBuffer buffer = new StringBuffer(mapping.getWordLength());
+ for (int i = mapping.startIndex; i < mapping.endIndex; i++) {
buffer.append(foText.charAt(i));
}
return buffer.toString();
@@ -1420,41 +1168,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
}
- private void addElementsForASpace(List baseList, int alignment, AreaInfo areaInfo,
+ private void addElementsForASpace(List baseList, int alignment, GlyphMapping mapping,
int leafValue) {
LeafPosition mainPosition = new LeafPosition(this, leafValue);
- if (!areaInfo.breakOppAfter) {
+ if (!mapping.breakOppAfter) {
// a non-breaking space
if (alignment == Constants.EN_JUSTIFY) {
// the space can stretch and shrink, and must be preserved
// when starting a line
baseList.add(makeAuxiliaryZeroWidthBox());
baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
- baseList.add(new KnuthGlue(areaInfo.areaIPD, mainPosition, false));
+ baseList.add(new KnuthGlue(mapping.areaIPD, mainPosition, false));
} else {
// the space does not need to stretch or shrink, and must be
// preserved when starting a line
- baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt(), null, mainPosition,
+ baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt(), null, mainPosition,
true));
}
} else {
- if (foText.charAt(areaInfo.startIndex) != CharUtilities.SPACE
+ if (foText.charAt(mapping.startIndex) != CharUtilities.SPACE
|| foText.getWhitespaceTreatment() == Constants.EN_PRESERVE) {
// a breaking space that needs to be preserved
- baseList
- .addAll(getElementsForBreakingSpace(alignment, areaInfo, auxiliaryPosition, 0,
- mainPosition, areaInfo.areaIPD.getOpt(), true));
+ baseList.addAll(getElementsForBreakingSpace(alignment, mapping, auxiliaryPosition, 0,
+ mainPosition, mapping.areaIPD.getOpt(), true));
} else {
// a (possible block) of breaking spaces
- baseList
- .addAll(getElementsForBreakingSpace(alignment, areaInfo, mainPosition,
- areaInfo.areaIPD.getOpt(), auxiliaryPosition, 0, false));
+ baseList.addAll(getElementsForBreakingSpace(alignment, mapping, mainPosition,
+ mapping.areaIPD.getOpt(), auxiliaryPosition, 0, false));
}
}
}
- private List getElementsForBreakingSpace(int alignment, AreaInfo areaInfo, Position pos2,
+ private List getElementsForBreakingSpace(int alignment, GlyphMapping mapping, Position pos2,
int p2WidthOffset, Position pos3,
int p3WidthOffset, boolean skipZeroCheck) {
List elements = new ArrayList();
@@ -1504,7 +1250,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
elements.add(g);
elements.add(makeZeroWidthPenalty(0));
g = new KnuthGlue(
- areaInfo.areaIPD.getOpt(),
+ mapping.areaIPD.getOpt(),
-3 * LineLayoutManager.DEFAULT_SPACE_WIDTH, 0, pos2, false);
elements.add(g);
}
@@ -1513,25 +1259,24 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
case EN_JUSTIFY:
// justified text:
// the stretch and shrink depends on the space width
- elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
- p3WidthOffset, skipZeroCheck, areaInfo.areaIPD.getShrink()));
+ elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
+ p3WidthOffset, skipZeroCheck, mapping.areaIPD.getShrink()));
break;
default:
// last line justified, the other lines unjustified:
// use only the space stretch
- elements.addAll(getElementsForJustifiedText(areaInfo, pos2, p2WidthOffset, pos3,
+ elements.addAll(getElementsForJustifiedText(mapping, pos2, p2WidthOffset, pos3,
p3WidthOffset, skipZeroCheck, 0));
}
return elements;
}
- private List getElementsForJustifiedText(
- AreaInfo areaInfo, Position pos2, int p2WidthOffset,
- Position pos3, int p3WidthOffset, boolean skipZeroCheck,
- int shrinkability) {
+ private List getElementsForJustifiedText(GlyphMapping mapping, Position pos2, int p2WidthOffset,
+ Position pos3, int p3WidthOffset, boolean skipZeroCheck,
+ int shrinkability) {
- int stretchability = areaInfo.areaIPD.getStretch();
+ int stretchability = mapping.areaIPD.getStretch();
List elements = new ArrayList();
if (skipZeroCheck || lineStartBAP != 0 || lineEndBAP != 0) {
@@ -1543,34 +1288,34 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
elements.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
elements.add(new KnuthGlue(lineStartBAP + p3WidthOffset, 0, 0, pos3, false));
} else {
- elements.add(new KnuthGlue(areaInfo.areaIPD.getOpt(), stretchability, shrinkability,
+ elements.add(new KnuthGlue(mapping.areaIPD.getOpt(), stretchability, shrinkability,
pos2, false));
}
return elements;
}
- private void addElementsForAWordFragment(List baseList, int alignment, AreaInfo areaInfo,
+ private void addElementsForAWordFragment(List baseList, int alignment, GlyphMapping mapping,
int leafValue) {
LeafPosition mainPosition = new LeafPosition(this, leafValue);
// if the last character of the word fragment is '-' or '/',
// the fragment could end a line; in this case, it loses one
// of its letter spaces;
- boolean suppressibleLetterSpace = areaInfo.breakOppAfter && !areaInfo.isHyphenated;
+ boolean suppressibleLetterSpace = mapping.breakOppAfter && !mapping.isHyphenated;
if (letterSpaceIPD.isStiff()) {
// constant letter spacing
baseList.add(new KnuthInlineBox(suppressibleLetterSpace
- ? areaInfo.areaIPD.getOpt() - letterSpaceIPD.getOpt()
- : areaInfo.areaIPD.getOpt(),
+ ? mapping.areaIPD.getOpt() - letterSpaceIPD.getOpt()
+ : mapping.areaIPD.getOpt(),
alignmentContext, notifyPos(mainPosition), false));
} else {
// adjustable letter spacing
int unsuppressibleLetterSpaces = suppressibleLetterSpace
- ? areaInfo.letterSpaceCount - 1
- : areaInfo.letterSpaceCount;
- baseList.add(new KnuthInlineBox(areaInfo.areaIPD.getOpt()
- - areaInfo.letterSpaceCount * letterSpaceIPD.getOpt(),
+ ? mapping.letterSpaceCount - 1
+ : mapping.letterSpaceCount;
+ baseList.add(new KnuthInlineBox(mapping.areaIPD.getOpt()
+ - mapping.letterSpaceCount * letterSpaceIPD.getOpt(),
alignmentContext, notifyPos(mainPosition), false));
baseList.add(makeZeroWidthPenalty(KnuthElement.INFINITE));
baseList.add(new KnuthGlue(letterSpaceIPD.mult(unsuppressibleLetterSpaces),
@@ -1580,19 +1325,19 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
// extra-elements if the word fragment is the end of a syllable,
// or it ends with a character that can be used as a line break
- if (areaInfo.isHyphenated) {
+ if (mapping.isHyphenated) {
MinOptMax widthIfNoBreakOccurs = null;
- if (areaInfo.breakIndex < foText.length()) {
+ if (mapping.endIndex < foText.length()) {
//Add in kerning in no-break condition
- widthIfNoBreakOccurs = letterSpaceAdjustArray[areaInfo.breakIndex];
+ widthIfNoBreakOccurs = letterSpaceAdjustArray[mapping.endIndex];
}
- //if (areaInfo.breakIndex)
+ //if (mapping.breakIndex)
// the word fragment ends at the end of a syllable:
// if a break occurs the content width increases,
// otherwise nothing happens
addElementsForAHyphen(baseList, alignment, hyphIPD, widthIfNoBreakOccurs,
- areaInfo.breakOppAfter && areaInfo.isHyphenated);
+ mapping.breakOppAfter && mapping.isHyphenated);
} else if (suppressibleLetterSpace) {
// the word fragment ends with a character that acts as a hyphen
// if a break occurs the width does not increase,
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
index 5d89b3440..062a67b38 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListBlockLayoutManager.java
@@ -28,16 +28,15 @@ import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.Area;
import org.apache.fop.area.Block;
import org.apache.fop.fo.flow.ListBlock;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.LayoutManager;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
@@ -47,21 +46,13 @@ import org.apache.fop.traits.SpaceVal;
* A list block contains list items which are stacked within
* the list block area..
*/
-public class ListBlockLayoutManager extends BlockStackingLayoutManager
- implements ConditionalElementListener {
+public class ListBlockLayoutManager extends SpacedBorderedPaddedBlockLayoutManager {
/** logging instance */
private static Log log = LogFactory.getLog(ListBlockLayoutManager.class);
private Block curBlockArea;
- private boolean discardBorderBefore;
- private boolean discardBorderAfter;
- private boolean discardPaddingBefore;
- private boolean discardPaddingAfter;
- private MinOptMax effSpaceBefore;
- private MinOptMax effSpaceAfter;
-
/**
* Create a new list block layout manager.
* @param node list-block to create the layout manager for
@@ -70,6 +61,11 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager
super(node);
}
+ @Override
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return getListBlockFO().getCommonBorderPaddingBackground();
+ }
+
/**
* Convenience method.
* @return the ListBlock node
@@ -279,50 +275,5 @@ public class ListBlockLayoutManager extends BlockStackingLayoutManager
return getListBlockFO().getKeepWithNext();
}
- /** {@inheritDoc} */
- public void notifySpace(RelSide side, MinOptMax effectiveLength) {
- if (RelSide.BEFORE == side) {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceBefore + "-> " + effectiveLength);
- }
- this.effSpaceBefore = effectiveLength;
- } else {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceAfter + "-> " + effectiveLength);
- }
- this.effSpaceAfter = effectiveLength;
- }
- }
-
- /** {@inheritDoc} */
- public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardBorderBefore = true;
- } else {
- this.discardBorderAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Border " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
- public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardPaddingBefore = true;
- } else {
- this.discardPaddingAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Padding " + side + " -> " + effectiveLength);
- }
- }
-
}
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index 84dba03ee..773506632 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -32,12 +32,11 @@ import org.apache.fop.area.Block;
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.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakOpportunity;
import org.apache.fop.layoutmgr.BreakOpportunityHelper;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.ElementListObserver;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
@@ -53,10 +52,9 @@ import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.NonLeafPosition;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
import org.apache.fop.layoutmgr.SpaceResolver;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
import org.apache.fop.layoutmgr.TraitSetter;
-import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
import org.apache.fop.util.BreakUtil;
@@ -64,8 +62,8 @@ import org.apache.fop.util.BreakUtil;
* LayoutManager for a list-item FO.
* The list item contains a list item label and a list item body.
*/
-public class ListItemLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
- BreakOpportunity {
+public class ListItemLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+ implements BreakOpportunity {
/** logging instance */
private static Log log = LogFactory.getLog(ListItemLayoutManager.class);
@@ -78,13 +76,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements
private List<ListElement> labelList = null;
private List<ListElement> bodyList = null;
- private boolean discardBorderBefore;
- private boolean discardBorderAfter;
- private boolean discardPaddingBefore;
- private boolean discardPaddingAfter;
- private MinOptMax effSpaceBefore;
- private MinOptMax effSpaceAfter;
-
private Keep keepWithNextPendingOnLabel;
private Keep keepWithNextPendingOnBody;
@@ -145,6 +136,11 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements
setBody(node.getBody());
}
+ @Override
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return getListItemFO().getCommonBorderPaddingBackground();
+ }
+
/**
* Convenience method.
* @return the ListBlock node
@@ -475,6 +471,23 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements
return returnedList;
}
+
+ @Override
+ public boolean hasLineAreaDescendant() {
+ return label.hasLineAreaDescendant() || body.hasLineAreaDescendant();
+ }
+
+ @Override
+ public int getBaselineOffset() {
+ if (label.hasLineAreaDescendant()) {
+ return label.getBaselineOffset();
+ } else if (body.hasLineAreaDescendant()) {
+ return body.getBaselineOffset();
+ } else {
+ throw newNoLineAreaDescendantException();
+ }
+ }
+
/**
* Add the areas for the break points.
*
@@ -655,51 +668,6 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager implements
}
/** {@inheritDoc} */
- public void notifySpace(RelSide side, MinOptMax effectiveLength) {
- if (RelSide.BEFORE == side) {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceBefore + "-> " + effectiveLength);
- }
- this.effSpaceBefore = effectiveLength;
- } else {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceAfter + "-> " + effectiveLength);
- }
- this.effSpaceAfter = effectiveLength;
- }
- }
-
- /** {@inheritDoc} */
- public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardBorderBefore = true;
- } else {
- this.discardBorderAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Border " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
- public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardPaddingBefore = true;
- } else {
- this.discardPaddingAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Padding " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
@Override
public void reset() {
super.reset();
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
index af8e071d5..b2851c1b0 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
@@ -117,6 +117,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
*/
public TableCellLayoutManager(TableCell node, PrimaryGridUnit pgu) {
super(node);
+ setGeneratesBlockArea(true);
this.primaryGridUnit = pgu;
this.isDescendantOfTableHeader = node.getParent().getParent() instanceof TableHeader
|| node.getParent() instanceof TableHeader;
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
index 7f1754064..afb6547c0 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java
@@ -39,12 +39,11 @@ import org.apache.fop.fo.flow.Markers;
import org.apache.fop.fo.flow.RetrieveTableMarker;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.layoutmgr.BlockLevelEventProducer;
-import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakOpportunity;
-import org.apache.fop.layoutmgr.ConditionalElementListener;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.LayoutContext;
@@ -52,7 +51,7 @@ import org.apache.fop.layoutmgr.LeafPosition;
import org.apache.fop.layoutmgr.ListElement;
import org.apache.fop.layoutmgr.Position;
import org.apache.fop.layoutmgr.PositionIterator;
-import org.apache.fop.layoutmgr.RelSide;
+import org.apache.fop.layoutmgr.SpacedBorderedPaddedBlockLayoutManager;
import org.apache.fop.layoutmgr.TraitSetter;
import org.apache.fop.traits.MinOptMax;
import org.apache.fop.traits.SpaceVal;
@@ -66,8 +65,8 @@ import org.apache.fop.util.BreakUtil;
* The table then creates areas for the columns, bodies and rows
* the render background.
*/
-public class TableLayoutManager extends BlockStackingLayoutManager
- implements ConditionalElementListener, BreakOpportunity {
+public class TableLayoutManager extends SpacedBorderedPaddedBlockLayoutManager
+ implements BreakOpportunity {
/**
* logging instance
@@ -82,13 +81,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager
private double tableUnit;
private boolean autoLayout = true;
- private boolean discardBorderBefore;
- private boolean discardBorderAfter;
- private boolean discardPaddingBefore;
- private boolean discardPaddingAfter;
- private MinOptMax effSpaceBefore;
- private MinOptMax effSpaceAfter;
-
private int halfBorderSeparationBPD;
private int halfBorderSeparationIPD;
@@ -132,6 +124,13 @@ public class TableLayoutManager extends BlockStackingLayoutManager
this.columns = new ColumnSetup(node);
}
+
+ @Override
+ protected CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
+ return getTable().getCommonBorderPaddingBackground();
+ }
+
+
/** @return the table FO */
public Table getTable() {
return (Table)this.fobj;
@@ -522,51 +521,6 @@ public class TableLayoutManager extends BlockStackingLayoutManager
}
/** {@inheritDoc} */
- public void notifySpace(RelSide side, MinOptMax effectiveLength) {
- if (RelSide.BEFORE == side) {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceBefore + "-> " + effectiveLength);
- }
- this.effSpaceBefore = effectiveLength;
- } else {
- if (log.isDebugEnabled()) {
- log.debug(this + ": Space " + side + ", "
- + this.effSpaceAfter + "-> " + effectiveLength);
- }
- this.effSpaceAfter = effectiveLength;
- }
- }
-
- /** {@inheritDoc} */
- public void notifyBorder(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardBorderBefore = true;
- } else {
- this.discardBorderAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Border " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
- public void notifyPadding(RelSide side, MinOptMax effectiveLength) {
- if (effectiveLength == null) {
- if (RelSide.BEFORE == side) {
- this.discardPaddingBefore = true;
- } else {
- this.discardPaddingAfter = true;
- }
- }
- if (log.isDebugEnabled()) {
- log.debug(this + ": Padding " + side + " -> " + effectiveLength);
- }
- }
-
- /** {@inheritDoc} */
public void reset() {
super.reset();
curBlockArea = null;
diff --git a/src/java/org/apache/fop/pdf/PDFProfile.java b/src/java/org/apache/fop/pdf/PDFProfile.java
index 6e0cb412e..4ae5ba8df 100644
--- a/src/java/org/apache/fop/pdf/PDFProfile.java
+++ b/src/java/org/apache/fop/pdf/PDFProfile.java
@@ -169,15 +169,28 @@ public class PDFProfile {
* @param context Context information for the user to identify the problem spot
*/
public void verifyTransparencyAllowed(String context) {
- final String err = "{0} does not allow the use of transparency. ({1})";
+ Object profile = isTransparencyAllowed();
+ if (profile != null) {
+ throw new PDFConformanceException(profile + " does not allow the use of transparency. ("
+ + profile + ")");
+ }
+ }
+
+ /**
+ * Returns {@code null} if transparency is allowed, otherwise returns the profile that
+ * prevents it.
+ *
+ * @return {@code null}, or an object whose {@code toString} method returns the name
+ * of the profile that disallows transparency
+ */
+ public Object isTransparencyAllowed() {
if (pdfAMode.isPart1()) {
- throw new PDFConformanceException(MessageFormat.format(err,
- new Object[] {getPDFAMode(), context}));
+ return getPDFAMode();
}
if (isPDFXActive()) {
- throw new PDFConformanceException(MessageFormat.format(err,
- new Object[] {getPDFXMode(), context}));
+ return getPDFXMode();
}
+ return null;
}
/** Checks if the right PDF version is set. */
diff --git a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
index 392eb875e..983a5ad90 100644
--- a/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
+++ b/src/java/org/apache/fop/render/AbstractGenericSVGHandler.java
@@ -31,6 +31,7 @@ import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
@@ -122,7 +123,8 @@ public abstract class AbstractGenericSVGHandler implements XMLHandler, RendererC
//Prepare
FOUserAgent userAgent = rendererContext.getUserAgent();
- SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new AffineTransform());
+ SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, DefaultFontFamilyResolver.SINGLETON,
+ new AffineTransform());
//Create Batik BridgeContext
final BridgeContext bridgeContext = new BridgeContext(svgUserAgent);
diff --git a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
index 4549a26af..e05bc007c 100644
--- a/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPSVGHandler.java
@@ -29,6 +29,7 @@ import org.w3c.dom.Document;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
@@ -43,6 +44,7 @@ import org.apache.fop.afp.AFPResourceInfo;
import org.apache.fop.afp.AFPResourceManager;
import org.apache.fop.afp.AFPUnitConverter;
import org.apache.fop.afp.svg.AFPBridgeContext;
+import org.apache.fop.afp.svg.AFPFontFamilyResolver;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.image.loader.batik.BatikUtil;
@@ -53,6 +55,7 @@ import org.apache.fop.render.RendererContext;
import org.apache.fop.render.RendererContext.RendererContextWrapper;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.svg.font.AggregatingFontFamilyResolver;
/**
* AFP XML handler for SVG. Uses Apache Batik for SVG processing.
@@ -196,15 +199,14 @@ public class AFPSVGHandler extends AbstractGenericSVGHandler {
*/
public static BridgeContext createBridgeContext(FOUserAgent userAgent, AFPGraphics2D g2d) {
ImageManager imageManager = userAgent.getImageManager();
-
- SVGUserAgent svgUserAgent
- = new SVGUserAgent(userAgent, new AffineTransform());
-
- ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
-
FontInfo fontInfo = g2d.getFontInfo();
+ SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent,
+ new AggregatingFontFamilyResolver(new AFPFontFamilyResolver(fontInfo, userAgent.getEventBroadcaster()),
+ DefaultFontFamilyResolver.SINGLETON),
+ new AffineTransform());
+ ImageSessionContext imageSessionContext = userAgent.getImageSessionContext();
return new AFPBridgeContext(svgUserAgent, fontInfo, imageManager, imageSessionContext,
- new AffineTransform(), g2d);
+ new AffineTransform(), g2d, userAgent.getEventBroadcaster());
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
index 2f8865b14..5e9372a75 100644
--- a/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
+++ b/src/java/org/apache/fop/render/java2d/CustomFontMetricsMapper.java
@@ -21,6 +21,7 @@ package org.apache.fop.render.java2d;
import java.awt.Font;
import java.awt.FontFormatException;
+import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -183,11 +184,31 @@ public class CustomFontMetricsMapper extends Typeface implements FontMetricsMapp
return typeface.getWidths();
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ return typeface.getBoundingBox(glyphIndex, size);
+ }
+
/** {@inheritDoc} */
public final int getXHeight(final int size) {
return typeface.getXHeight(size);
}
+ public int getUnderlinePosition(int size) {
+ return typeface.getUnderlinePosition(size);
+ }
+
+ public int getUnderlineThickness(int size) {
+ return typeface.getUnderlineThickness(size);
+ }
+
+ public int getStrikeoutPosition(int size) {
+ return typeface.getStrikeoutPosition(size);
+ }
+
+ public int getStrikeoutThickness(int size) {
+ return typeface.getStrikeoutThickness(size);
+ }
+
/** {@inheritDoc} */
public final boolean hasKerningInfo() {
return typeface.hasKerningInfo();
diff --git a/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java b/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
index fc4af3574..5e681e9e2 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DFontMetrics.java
@@ -223,6 +223,26 @@ public class Java2DFontMetrics {
return xHeight * 1000;
}
+ public int getUnderlinePosition(String family, int style, int size) {
+ setFont(family, style, size);
+ return -Math.round(lineMetrics.getUnderlineOffset());
+ }
+
+ public int getUnderlineThickness(String family, int style, int size) {
+ setFont(family, style, size);
+ return Math.round(lineMetrics.getUnderlineThickness());
+ }
+
+ public int getStrikeoutPosition(String family, int style, int size) {
+ setFont(family, style, size);
+ return -Math.round(lineMetrics.getStrikethroughOffset());
+ }
+
+ public int getStrikeoutThickness(String family, int style, int size) {
+ setFont(family, style, size);
+ return Math.round(lineMetrics.getStrikethroughThickness());
+ }
+
/**
* Returns width (in 1/1000ths of point size) of character at
* code point i
diff --git a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
index 110581f27..f3128c600 100644
--- a/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
+++ b/src/java/org/apache/fop/render/java2d/Java2DSVGHandler.java
@@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.font.DefaultFontFamilyResolver;
import org.apache.fop.image.loader.batik.BatikUtil;
import org.apache.fop.render.AbstractGenericSVGHandler;
@@ -128,8 +129,8 @@ public class Java2DSVGHandler extends AbstractGenericSVGHandler
int x = info.currentXPosition;
int y = info.currentYPosition;
-
- SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+ SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), DefaultFontFamilyResolver.SINGLETON,
+ new AffineTransform());
BridgeContext ctx = new BridgeContext(ua);
diff --git a/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java b/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
index 06c975b86..f922e3f05 100644
--- a/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
+++ b/src/java/org/apache/fop/render/java2d/SystemFontMetricsMapper.java
@@ -20,6 +20,7 @@
package org.apache.fop.render.java2d;
// Java
+import java.awt.Rectangle;
import java.util.Map;
import java.util.Set;
@@ -133,6 +134,22 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp
return java2DFontMetrics.getXHeight(family, style, size);
}
+ public int getUnderlinePosition(int size) {
+ return java2DFontMetrics.getUnderlinePosition(family, style, size);
+ }
+
+ public int getUnderlineThickness(int size) {
+ return java2DFontMetrics.getUnderlineThickness(family, style, size);
+ }
+
+ public int getStrikeoutPosition(int size) {
+ return java2DFontMetrics.getStrikeoutPosition(family, style, size);
+ }
+
+ public int getStrikeoutThickness(int size) {
+ return java2DFontMetrics.getStrikeoutThickness(family, style, size);
+ }
+
/**
* {@inheritDoc}
*/
@@ -148,6 +165,10 @@ public class SystemFontMetricsMapper extends Typeface implements FontMetricsMapp
return java2DFontMetrics.getWidths(family, style, Java2DFontMetrics.FONT_SIZE);
}
+ public Rectangle getBoundingBox(int glyphIndex, int size) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
index 58299c528..471efc567 100644
--- a/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
@@ -23,6 +23,8 @@ import java.awt.color.ICC_Profile;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
+import java.io.IOException;
+import java.util.Arrays;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
@@ -239,24 +241,40 @@ public abstract class AbstractImageAdapter implements PDFImage {
+ " The image may not be handled correctly." + " Base color space: "
+ icm.getColorSpace() + " Image: " + image.getInfo());
}
- indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
+ ByteArrayOutputStream baout = new ByteArrayOutputStream();
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));
+ boolean isDeviceGray = false;
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);
+ byte[] reds = new byte[c];
+ byte[] greens = new byte[c];
+ byte[] blues = new byte[c];
+ icm.getReds(reds);
+ icm.getGreens(greens);
+ icm.getBlues(blues);
+ isDeviceGray = Arrays.equals(reds, blues) && Arrays.equals(blues, greens);
+ if (isDeviceGray) {
+ indexed.add(new PDFName("DeviceGray"));
+ try {
+ baout.write(blues);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ indexed.add(new PDFName(toPDFColorSpace(icm.getColorSpace()).getName()));
+ for (int i = 0; i < c; i++) {
+ int entry = palette[i];
+ baout.write((entry & 0xFF0000) >> 16);
+ baout.write((entry & 0xFF00) >> 8);
+ baout.write(entry & 0xFF);
+ }
}
+ indexed.add(hival);
+
indexed.add(baout.toByteArray());
dict.put("ColorSpace", indexed);
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
index a71ade911..5ab0b700f 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerGraphics2D.java
@@ -86,7 +86,7 @@ public class PDFImageHandlerGraphics2D extends AbstractImageHandlerGraphics2D {
PDFGraphics2D graphics = new PDFGraphics2D(textAsShapes,
pdfContext.getFontInfo(), generator.getDocument(),
generator.getResourceContext(), pdfContext.getPage().referencePDF(),
- "", 0.0f);
+ "", 0.0f, null);
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
AffineTransform transform = new AffineTransform();
diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
index 45d8dff2d..ae282f149 100644
--- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
+++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java
@@ -41,6 +41,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.image.loader.batik.BatikImageFlavors;
import org.apache.fop.image.loader.batik.BatikUtil;
import org.apache.fop.render.ImageHandler;
@@ -52,6 +53,7 @@ import org.apache.fop.svg.PDFBridgeContext;
import org.apache.fop.svg.PDFGraphics2D;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
/**
* Image Handler implementation which handles SVG images.
@@ -76,7 +78,8 @@ public class PDFImageHandlerSVG implements ImageHandler {
}
final float uaResolution = userAgent.getSourceResolution();
- SVGUserAgent ua = new SVGUserAgent(userAgent, new AffineTransform());
+ SVGUserAgent ua = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(pdfContext.getFontInfo()),
+ new AffineTransform());
GVTBuilder builder = new GVTBuilder();
@@ -169,7 +172,7 @@ public class PDFImageHandlerSVG implements ImageHandler {
PDFGraphics2D graphics = new PDFGraphics2D(true, pdfContext.getFontInfo(),
generator.getDocument(),
generator.getResourceContext(), pdfContext.getPage().referencePDF(),
- "", 0);
+ "", 0, new TransparencyIgnoredEventListener(pdfContext, imageSVG));
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
if (!resolutionScaling.isIdentity()) {
@@ -220,6 +223,30 @@ public class PDFImageHandlerSVG implements ImageHandler {
}
}
+ private static class TransparencyIgnoredEventListener
+ implements PDFGraphics2D.TransparencyIgnoredEventListener {
+
+ private final RenderingContext context;
+
+ private final Image image;
+
+ public TransparencyIgnoredEventListener(RenderingContext context, Image image) {
+ this.context = context;
+ this.image = image;
+ }
+
+ private boolean warningIssued;
+
+ public void transparencyIgnored(Object pdfProfile) {
+ if (!warningIssued) {
+ EventBroadcaster broadcaster = context.getUserAgent().getEventBroadcaster();
+ SVGEventProducer producer = SVGEventProducer.Provider.get(broadcaster);
+ producer.transparencyIgnored(this, pdfProfile, image.getInfo().getOriginalURI());
+ warningIssued = true;
+ }
+ }
+ }
+
/** {@inheritDoc} */
public int getPriority() {
return 400;
diff --git a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java
index 1d464cae6..96886910e 100644
--- a/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java
+++ b/src/java/org/apache/fop/render/ps/AbstractPSTranscoder.java
@@ -40,6 +40,7 @@ import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.AbstractFOPTranscoder;
import org.apache.fop.svg.PDFDocumentGraphics2DConfigurator;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
/**
* <p>This class enables to transcode an input to a PostScript document.</p>
@@ -115,6 +116,8 @@ public abstract class AbstractPSTranscoder extends AbstractFOPTranscoder {
this.fontInfo = PDFDocumentGraphics2DConfigurator.createFontInfo(
getEffectiveConfiguration(), useComplexScriptFeatures);
graphics.setCustomTextHandler(new NativeTextHandler(graphics, fontInfo));
+ ((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver(
+ new FOPFontFamilyResolverImpl(fontInfo));
} catch (FOPException fe) {
throw new TranscoderException(fe);
}
diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
index cadc28267..4d215926b 100644
--- a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
+++ b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java
@@ -65,6 +65,7 @@ import org.apache.fop.render.RenderingContext;
import org.apache.fop.render.ps.svg.PSSVGGraphics2D;
import org.apache.fop.svg.SVGEventProducer;
import org.apache.fop.svg.SVGUserAgent;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
/**
* Image handler implementation which handles SVG images for PostScript output.
@@ -107,8 +108,8 @@ public class PSImageHandlerSVG implements ImageHandler {
boolean strokeText = false;
//TODO Configure text stroking
- SVGUserAgent ua
- = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+ SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(),
+ new FOPFontFamilyResolverImpl(psContext.getFontInfo()), new AffineTransform());
PSSVGGraphics2D graphics = new PSSVGGraphics2D(strokeText, gen);
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
diff --git a/src/java/org/apache/fop/render/ps/PSSVGHandler.java b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
index e30f6391b..dfbaf60b7 100644
--- a/src/java/org/apache/fop/render/ps/PSSVGHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSSVGHandler.java
@@ -249,8 +249,7 @@ public class PSSVGHandler extends AbstractGenericSVGHandler
strokeText = cfg.getChild("stroke-text", true).getValueAsBoolean(strokeText);
}
- SVGUserAgent ua
- = new SVGUserAgent(context.getUserAgent(), new AffineTransform());
+ SVGUserAgent ua = new SVGUserAgent(context.getUserAgent(), null /* TODO */, new AffineTransform());
PSGraphics2D graphics = new PSGraphics2D(strokeText, gen);
graphics.setGraphicContext(new org.apache.xmlgraphics.java2d.GraphicContext());
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index eb2188026..44b7b08a3 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -19,25 +19,21 @@
package org.apache.fop.render.ps;
-import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
+import java.awt.geom.Point2D.Double;
import java.io.IOException;
-import java.text.AttributedCharacterIterator;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
-import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.text.TextPaintInfo;
-import org.apache.batik.gvt.text.TextSpanLayout;
import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
import org.apache.xmlgraphics.ps.PSGenerator;
@@ -48,7 +44,6 @@ 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;
/**
@@ -62,10 +57,20 @@ import org.apache.fop.util.HexEncoder;
*/
public class PSTextPainter extends NativeTextPainter {
- private static final boolean DEBUG = false;
-
private FontResourceCache fontResources;
+ private PSGraphics2D ps;
+
+ private PSGenerator gen;
+
+ private TextUtil textUtil;
+
+ private boolean flushCurrentRun;
+
+ private PSTextRun psRun;
+
+ private Double relPos;
+
private static final AffineTransform IDENTITY_TRANSFORM = new AffineTransform();
/**
@@ -82,165 +87,26 @@ public class PSTextPainter extends NativeTextPainter {
return g2d instanceof PSGraphics2D;
}
- /** {@inheritDoc} */
- protected void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException {
- AttributedCharacterIterator runaci = textRun.getACI();
- runaci.first();
-
- TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
- if (tpi == null || !tpi.visible) {
- return;
- }
- if ((tpi != null) && (tpi.composite != null)) {
- g2d.setComposite(tpi.composite);
- }
-
- //------------------------------------
- TextSpanLayout layout = textRun.getLayout();
- logTextRun(runaci, layout);
- CharSequence chars = collectCharacters(runaci);
- runaci.first(); //Reset ACI
-
- final PSGraphics2D ps = (PSGraphics2D)g2d;
- final PSGenerator gen = ps.getPSGenerator();
+ @Override
+ protected void preparePainting(Graphics2D g2d) {
+ ps = (PSGraphics2D) g2d;
+ gen = ps.getPSGenerator();
ps.preparePainting();
+ }
- if (DEBUG) {
- log.debug("Text: " + chars);
- gen.commentln("%Text: " + chars);
- }
-
- GeneralPath debugShapes = null;
- if (DEBUG) {
- debugShapes = new GeneralPath();
- }
-
- TextUtil textUtil = new TextUtil(gen);
- textUtil.setupFonts(runaci);
- if (!textUtil.hasFonts()) {
- //Draw using Java2D when no native fonts are available
- textRun.getLayout().draw(g2d);
- return;
- }
-
+ @Override
+ protected void saveGraphicsState() throws IOException {
gen.saveGraphicsState();
- gen.concatMatrix(g2d.getTransform());
- Shape imclip = g2d.getClip();
- clip(ps, imclip);
-
- gen.writeln("BT"); //beginTextObject()
-
- AffineTransform localTransform = new AffineTransform();
- Point2D prevPos = null;
- GVTGlyphVector gv = layout.getGlyphVector();
- PSTextRun psRun = new PSTextRun(); //Used to split a text run into smaller runs
- for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
- char ch = chars.charAt(index);
- boolean visibleChar = gv.isGlyphVisible(index)
- || (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch));
- logCharacter(ch, layout, index, visibleChar);
- if (!visibleChar) {
- continue;
- }
- Point2D glyphPos = gv.getGlyphPosition(index);
-
- AffineTransform glyphTransform = gv.getGlyphTransform(index);
- if (log.isTraceEnabled()) {
- log.trace("pos " + glyphPos + ", transform " + glyphTransform);
- }
- if (DEBUG) {
- Shape sh = gv.getGlyphLogicalBounds(index);
- if (sh == null) {
- sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
- }
- debugShapes.append(sh, false);
- }
-
- //Exact position of the glyph
- localTransform.setToIdentity();
- localTransform.translate(glyphPos.getX(), glyphPos.getY());
- if (glyphTransform != null) {
- localTransform.concatenate(glyphTransform);
- }
- localTransform.scale(1, -1);
-
- boolean flushCurrentRun = false;
- //Try to optimize by combining characters using the same font and on the same line.
- if (glyphTransform != null) {
- //Happens for text-on-a-path
- flushCurrentRun = true;
- }
- if (psRun.getRunLength() >= 128) {
- //Don't let a run get too long
- flushCurrentRun = true;
- }
-
- //Note the position of the glyph relative to the previous one
- Point2D relPos;
- if (prevPos == null) {
- relPos = new Point2D.Double(0, 0);
- } else {
- relPos = new Point2D.Double(
- glyphPos.getX() - prevPos.getX(),
- glyphPos.getY() - prevPos.getY());
- }
- if (psRun.vertChanges == 0
- && psRun.getHorizRunLength() > 2
- && relPos.getY() != 0) {
- //new line
- flushCurrentRun = true;
- }
-
- //Select the actual character to paint
- char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch);
-
- //Select (sub)font for character
- Font f = textUtil.selectFontForChar(paintChar);
- char mapped = f.mapChar(ch);
- boolean fontChanging = textUtil.isFontChanging(f, mapped);
- if (fontChanging) {
- flushCurrentRun = true;
- }
-
- if (flushCurrentRun) {
- //Paint the current run and reset for the next run
- psRun.paint(ps, textUtil, tpi);
- psRun.reset();
- }
-
- //Track current run
- psRun.addCharacter(paintChar, relPos);
- psRun.noteStartingTransformation(localTransform);
-
- //Change font if necessary
- if (fontChanging) {
- textUtil.setCurrentFont(f, mapped);
- }
+ }
- //Update last position
- prevPos = glyphPos;
- }
- psRun.paint(ps, textUtil, tpi);
- gen.writeln("ET"); //endTextObject()
+ @Override
+ protected void restoreGraphicsState() throws IOException {
gen.restoreGraphicsState();
-
- if (DEBUG) {
- //Paint debug shapes
- g2d.setStroke(new BasicStroke(0));
- g2d.setColor(Color.LIGHT_GRAY);
- g2d.draw(debugShapes);
- }
}
- private void applyColor(Paint paint, final PSGenerator gen) throws IOException {
- if (paint == null) {
- return;
- } else if (paint instanceof Color) {
- Color col = (Color)paint;
- gen.useColor(col);
- } else {
- log.warn("Paint not supported: " + paint.toString());
- }
+ @Override
+ protected void setInitialTransform(AffineTransform transform) throws IOException {
+ gen.concatMatrix(transform);
}
private PSFontResource getResourceForFont(Font f, String postfix) {
@@ -248,7 +114,8 @@ public class PSTextPainter extends NativeTextPainter {
return this.fontResources.getFontResourceForFontKey(key);
}
- private void clip(PSGraphics2D ps, Shape shape) throws IOException {
+ @Override
+ protected void clip(Shape shape) throws IOException {
if (shape == null) {
return;
}
@@ -258,17 +125,76 @@ public class PSTextPainter extends NativeTextPainter {
ps.getPSGenerator().writeln("clip");
}
+ @Override
+ protected void beginTextObject() throws IOException {
+ gen.writeln("BT");
+ textUtil = new TextUtil();
+ psRun = new PSTextRun(); //Used to split a text run into smaller runs
+ }
+
+ @Override
+ protected void endTextObject() throws IOException {
+ psRun.paint(ps, textUtil, tpi);
+ gen.writeln("ET");
+ }
+
+ @Override
+ protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) {
+ flushCurrentRun = false;
+ //Try to optimize by combining characters using the same font and on the same line.
+ if (reposition) {
+ //Happens for text-on-a-path
+ flushCurrentRun = true;
+ }
+ if (psRun.getRunLength() >= 128) {
+ //Don't let a run get too long
+ flushCurrentRun = true;
+ }
+
+ //Note the position of the glyph relative to the previous one
+ if (prevPos == null) {
+ relPos = new Point2D.Double(0, 0);
+ } else {
+ relPos = new Point2D.Double(
+ glyphPos.getX() - prevPos.getX(),
+ glyphPos.getY() - prevPos.getY());
+ }
+ if (psRun.vertChanges == 0
+ && psRun.getHorizRunLength() > 2
+ && relPos.getY() != 0) {
+ //new line
+ flushCurrentRun = true;
+ }
+ }
+
+ @Override
+ protected void writeGlyph(char glyph, AffineTransform localTransform) throws IOException {
+ boolean fontChanging = textUtil.isFontChanging(font, glyph);
+ if (fontChanging) {
+ flushCurrentRun = true;
+ }
+
+ if (flushCurrentRun) {
+ //Paint the current run and reset for the next run
+ psRun.paint(ps, textUtil, tpi);
+ psRun.reset();
+ }
+
+ //Track current run
+ psRun.addGlyph(glyph, relPos);
+ psRun.noteStartingTransformation(localTransform);
+
+ //Change font if necessary
+ if (fontChanging) {
+ textUtil.setCurrentFont(font, glyph);
+ }
+ }
+
private class TextUtil {
- private PSGenerator gen;
- private Font[] fonts;
private Font currentFont;
private int currentEncoding = -1;
- public TextUtil(PSGenerator gen) {
- this.gen = gen;
- }
-
public boolean isMultiByte(Font f) {
FontMetrics metrics = f.getFontMetrics();
boolean multiByte = metrics instanceof MultiByteFont || metrics instanceof LazyFont
@@ -276,15 +202,6 @@ public class PSTextPainter extends NativeTextPainter {
return multiByte;
}
- public Font selectFontForChar(char ch) {
- for (int i = 0, c = fonts.length; i < c; i++) {
- if (fonts[i].hasChar(ch)) {
- return fonts[i];
- }
- }
- return fonts[0]; //TODO Maybe fall back to painting with shapes
- }
-
public void writeTextMatrix(AffineTransform transform) throws IOException {
double[] matrix = new double[6];
transform.getMatrix(matrix);
@@ -335,27 +252,19 @@ public class PSTextPainter extends NativeTextPainter {
setCurrentFont(font, encoding);
}
- public void setupFonts(AttributedCharacterIterator runaci) {
- this.fonts = findFonts(runaci);
- }
-
- public boolean hasFonts() {
- return (fonts != null) && (fonts.length > 0);
- }
-
}
private class PSTextRun {
private AffineTransform textTransform;
- private List relativePositions = new java.util.LinkedList();
- private StringBuffer currentChars = new StringBuffer();
+ private List<Point2D> relativePositions = new LinkedList<Point2D>();
+ private StringBuffer currentGlyphs = new StringBuffer();
private int horizChanges = 0;
private int vertChanges = 0;
public void reset() {
textTransform = null;
- currentChars.setLength(0);
+ currentGlyphs.setLength(0);
horizChanges = 0;
vertChanges = 0;
relativePositions.clear();
@@ -369,9 +278,9 @@ public class PSTextPainter extends NativeTextPainter {
return 0;
}
- public void addCharacter(char paintChar, Point2D relPos) {
+ public void addGlyph(char glyph, Point2D relPos) {
addRelativePosition(relPos);
- currentChars.append(paintChar);
+ currentGlyphs.append(glyph);
}
private void addRelativePosition(Point2D relPos) {
@@ -393,7 +302,7 @@ public class PSTextPainter extends NativeTextPainter {
}
public int getRunLength() {
- return currentChars.length();
+ return currentGlyphs.length();
}
private boolean isXShow() {
@@ -407,9 +316,6 @@ public class PSTextPainter extends NativeTextPainter {
public void paint(PSGraphics2D g2d, TextUtil textUtil, TextPaintInfo tpi)
throws IOException {
if (getRunLength() > 0) {
- if (log.isDebugEnabled()) {
- log.debug("Text run: " + currentChars);
- }
textUtil.writeTextMatrix(this.textTransform);
if (isXShow()) {
log.debug("Horizontal text: xshow");
@@ -431,25 +337,20 @@ public class PSTextPainter extends NativeTextPainter {
private void paintXYShow(PSGraphics2D g2d, TextUtil textUtil, Paint paint,
boolean x, boolean y) throws IOException {
- PSGenerator gen = textUtil.gen;
- char firstChar = this.currentChars.charAt(0);
- //Font only has to be setup up before the first character
- Font f = textUtil.selectFontForChar(firstChar);
- char mapped = f.mapChar(firstChar);
- textUtil.selectFont(f, mapped);
- textUtil.setCurrentFont(f, mapped);
- applyColor(paint, gen);
-
- boolean multiByte = textUtil.isMultiByte(f);
+ char glyph = currentGlyphs.charAt(0);
+ textUtil.selectFont(font, glyph);
+ textUtil.setCurrentFont(font, glyph);
+ applyColor(paint);
+
+ boolean multiByte = textUtil.isMultiByte(font);
StringBuffer sb = new StringBuffer();
sb.append(multiByte ? '<' : '(');
- for (int i = 0, c = this.currentChars.length(); i < c; i++) {
- char ch = this.currentChars.charAt(i);
- mapped = f.mapChar(ch);
+ for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) {
+ glyph = this.currentGlyphs.charAt(i);
if (multiByte) {
- sb.append(HexEncoder.encode(mapped));
+ sb.append(HexEncoder.encode(glyph));
} else {
- char codepoint = (char) (mapped % 256);
+ char codepoint = (char) (glyph % 256);
PSGenerator.escapeChar(codepoint, sb);
}
}
@@ -457,9 +358,9 @@ public class PSTextPainter extends NativeTextPainter {
if (x || y) {
sb.append("\n[");
int idx = 0;
- Iterator iter = this.relativePositions.iterator();
+ Iterator<Point2D> iter = this.relativePositions.iterator();
while (iter.hasNext()) {
- Point2D pt = (Point2D)iter.next();
+ Point2D pt = iter.next();
if (idx > 0) {
if (x) {
sb.append(format(gen, pt.getX()));
@@ -500,6 +401,17 @@ public class PSTextPainter extends NativeTextPainter {
gen.writeln(sb.toString());
}
+ private void applyColor(Paint paint) throws IOException {
+ if (paint == null) {
+ return;
+ } else if (paint instanceof Color) {
+ Color col = (Color) paint;
+ gen.useColor(col);
+ } else {
+ log.warn("Paint not supported: " + paint.toString());
+ }
+ }
+
private String format(PSGenerator gen, double coord) {
if (Math.abs(coord) < 0.00001) {
return "0";
@@ -510,30 +422,21 @@ public class PSTextPainter extends NativeTextPainter {
private void paintStrokedGlyphs(PSGraphics2D g2d, TextUtil textUtil,
Paint strokePaint, Stroke stroke) throws IOException {
- PSGenerator gen = textUtil.gen;
-
- applyColor(strokePaint, gen);
+ applyColor(strokePaint);
PSGraphics2D.applyStroke(stroke, gen);
- Font f = null;
- Iterator iter = this.relativePositions.iterator();
+ Iterator<Point2D> iter = this.relativePositions.iterator();
iter.next();
Point2D pos = new Point2D.Double(0, 0);
gen.writeln("0 0 M");
- for (int i = 0, c = this.currentChars.length(); i < c; i++) {
- char ch = this.currentChars.charAt(0);
+ for (int i = 0, c = this.currentGlyphs.length(); i < c; i++) {
+ char mapped = this.currentGlyphs.charAt(i);
if (i == 0) {
- //Font only has to be setup up before the first character
- f = textUtil.selectFontForChar(ch);
- }
- char mapped = f.mapChar(ch);
- if (i == 0) {
- textUtil.selectFont(f, mapped);
- textUtil.setCurrentFont(f, mapped);
+ textUtil.selectFont(font, mapped);
+ textUtil.setCurrentFont(font, mapped);
}
//add glyph outlines to current path
- mapped = f.mapChar(this.currentChars.charAt(i));
- FontMetrics metrics = f.getFontMetrics();
+ FontMetrics metrics = font.getFontMetrics();
boolean multiByte = metrics instanceof MultiByteFont
|| metrics instanceof LazyFont
&& ((LazyFont) metrics).getRealFont() instanceof MultiByteFont;
@@ -542,14 +445,14 @@ public class PSTextPainter extends NativeTextPainter {
gen.write(HexEncoder.encode(mapped));
gen.write(">");
} else {
- char codepoint = (char)(mapped % 256);
+ char codepoint = (char) (mapped % 256);
gen.write("(" + codepoint + ")");
}
gen.writeln(" false charpath");
if (iter.hasNext()) {
//Position for the next character
- Point2D pt = (Point2D)iter.next();
+ Point2D pt = iter.next();
pos.setLocation(pos.getX() + pt.getX(), pos.getY() - pt.getY());
gen.writeln(gen.formatDouble5(pos.getX()) + " "
+ gen.formatDouble5(pos.getY()) + " M");
diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java
index 73fa3504c..2bb7befc1 100644
--- a/src/java/org/apache/fop/render/rtf/RTFHandler.java
+++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java
@@ -218,8 +218,10 @@ public class RTFHandler extends FOEventHandler {
eventProducer.onlySPMSupported(this, reference, pageSeq.getLocator());
PageSequenceMaster master
= pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference);
- this.pagemaster = master.getNextSimplePageMaster(
- false, false, false, false, pageSeq.getMainFlow().getFlowName());
+ if (pageSeq.getMainFlow() != null) {
+ this.pagemaster = master.getNextSimplePageMaster(
+ false, false, false, false, pageSeq.getMainFlow().getFlowName());
+ }
}
}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java
index bf32eceeb..9f542dd75 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfStringConverter.java
@@ -102,7 +102,7 @@ public final class RtfStringConverter {
if (i != 0) {
d = new Character(str.charAt(i - 1));
} else {
- d = new Character(str.charAt(i));
+ d = new Character(SPACE);
}
//This section modified by Chris Scott
diff --git a/src/java/org/apache/fop/svg/ACIUtils.java b/src/java/org/apache/fop/svg/ACIUtils.java
index f54a026e1..deba98f21 100644
--- a/src/java/org/apache/fop/svg/ACIUtils.java
+++ b/src/java/org/apache/fop/svg/ACIUtils.java
@@ -38,7 +38,8 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.svg.font.FOPGVTFont;
+import org.apache.fop.svg.font.FOPGVTFontFamily;
/**
* Utilities for java.text.AttributedCharacterIterator.
@@ -64,57 +65,43 @@ public final class ACIUtils {
@SuppressWarnings("unchecked")
List<GVTFontFamily> gvtFonts = (List<GVTFontFamily>) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
- Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
- Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
- Float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE);
-
- String style = toStyle(posture);
- int weight = toCSSWeight(taWeight);
- int fsize = (int)(fontSize.floatValue() * 1000);
+ String style = toStyle((Float) aci.getAttribute(TextAttribute.POSTURE));
+ int weight = toCSSWeight((Float) aci.getAttribute(TextAttribute.WEIGHT));
+ float fontSize = ((Float) aci.getAttribute(TextAttribute.SIZE)).floatValue();
String firstFontFamily = null;
-
//GVT_FONT can sometimes be different from the fonts in GVT_FONT_FAMILIES
//or GVT_FONT_FAMILIES can even be empty and only GVT_FONT is set
- /* The following code section is not available until Batik 1.7 is released. */
- GVTFont gvtFont = (GVTFont)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
+ GVTFont gvtFont = (GVTFont) aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
if (gvtFont != null) {
String gvtFontFamily = gvtFont.getFamilyName();
- if (fontInfo.hasFont(gvtFontFamily, style, weight)) {
- FontTriplet triplet = fontInfo.fontLookup(gvtFontFamily, style,
- weight);
- Font f = fontInfo.getFontInstance(triplet, fsize);
+ if (gvtFont instanceof FOPGVTFont) {
+ Font font = ((FOPGVTFont) gvtFont).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font: "
+ gvtFontFamily + ", " + weight + ", " + style
- + " -> " + f);
+ + " -> " + font);
}
- fonts.add(f);
+ fonts.add(font);
}
firstFontFamily = gvtFontFamily;
}
if (gvtFonts != null) {
boolean haveInstanceOfSVGFontFamily = false;
- for (GVTFontFamily fam : gvtFonts) {
- if (fam instanceof SVGFontFamily) {
+ for (GVTFontFamily fontFamily : gvtFonts) {
+ if (fontFamily instanceof SVGFontFamily) {
haveInstanceOfSVGFontFamily = true;
- }
- String fontFamily = fam.getFamilyName();
- if (fontInfo.hasFont(fontFamily, style, weight)) {
- FontTriplet triplet = fontInfo.fontLookup(fontFamily, style,
- weight);
- Font f = fontInfo.getFontInstance(triplet, fsize);
+ } else if (fontFamily instanceof FOPGVTFontFamily) {
+ Font font = ((FOPGVTFontFamily) fontFamily).deriveFont(fontSize, aci).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font family: "
- + fontFamily + ", " + weight + ", " + style
- + " -> " + f);
+ + fontFamily.getFamilyName() + ", " + weight + ", " + style + " -> " + font);
}
- fonts.add(f);
+ fonts.add(font);
}
if (firstFontFamily == null) {
- firstFontFamily = fontFamily;
+ firstFontFamily = fontFamily.getFamilyName();
}
}
// SVG fonts are embedded fonts in the SVG document and are rarely used; however if they
@@ -126,25 +113,10 @@ public final class ACIUtils {
return null; // Let Batik paint this text!
}
}
- if (fonts.isEmpty()) {
- if (firstFontFamily == null) {
- //This will probably never happen. Just to be on the safe side.
- firstFontFamily = "any";
- }
- //lookup with fallback possibility (incl. substitution notification)
- FontTriplet triplet = fontInfo.fontLookup(firstFontFamily, style, weight);
- Font f = fontInfo.getFontInstance(triplet, fsize);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Falling back to adjustable font lookup up for: "
- + firstFontFamily + ", " + weight + ", " + style
- + " -> " + f);
- }
- fonts.add(f);
- }
- return fonts.toArray(new Font[fonts.size()]);
+ return fonts.isEmpty() ? null : fonts.toArray(new Font[fonts.size()]);
}
- private static int toCSSWeight(Float weight) {
+ public static int toCSSWeight(Float weight) {
if (weight == null) {
return 400;
} else if (weight <= TextAttribute.WEIGHT_EXTRA_LIGHT.floatValue()) {
@@ -170,7 +142,7 @@ public final class ACIUtils {
}
}
- private static String toStyle(Float posture) {
+ public static String toStyle(Float posture) {
return ((posture != null) && (posture.floatValue() > 0.0))
? Font.STYLE_ITALIC
: Font.STYLE_NORMAL;
diff --git a/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java b/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java
index 3e16799f4..7df127d3a 100644
--- a/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java
+++ b/src/java/org/apache/fop/svg/AbstractFOPTextPainter.java
@@ -23,20 +23,15 @@ import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
-import java.awt.font.TextAttribute;
-import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
-import java.util.Iterator;
-import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.batik.dom.svg.SVGOMTextElement;
import org.apache.batik.gvt.TextNode;
import org.apache.batik.gvt.TextPainter;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
@@ -66,15 +61,15 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* Use the stroking text painter to get the bounds and shape.
* Also used as a fallback to draw the string with strokes.
*/
- protected static final TextPainter
- PROXY_PAINTER = StrokingTextPainter.getInstance();
+ private final TextPainter proxyTextPainter;
/**
* Create a new PS text painter with the given font information.
* @param nativeTextHandler the NativeTextHandler instance used for text painting
*/
- public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler) {
+ public AbstractFOPTextPainter(FOPTextHandler nativeTextHandler, TextPainter proxyTextPainter) {
this.nativeTextHandler = nativeTextHandler;
+ this.proxyTextPainter = proxyTextPainter;
}
/**
@@ -85,19 +80,10 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @param g2d the Graphics2D to use
*/
public void paint(TextNode node, Graphics2D g2d) {
- Point2D loc = node.getLocation();
- if (!isSupportedGraphics2D(g2d) || hasUnsupportedAttributes(node)) {
- if (log.isDebugEnabled()) {
- log.debug("painting text node " + node
- + " by stroking due to unsupported attributes or an incompatible Graphics2D");
- }
- PROXY_PAINTER.paint(node, g2d);
- } else {
- if (log.isDebugEnabled()) {
- log.debug("painting text node " + node + " normally.");
- }
- paintTextRuns(node.getTextRuns(), g2d, loc);
+ if (isSupportedGraphics2D(g2d)) {
+ new TextRunPainter().paintTextRuns(node.getTextRuns(), g2d, node.getLocation());
}
+ proxyTextPainter.paint(node, g2d);
}
/**
@@ -109,190 +95,99 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
*/
protected abstract boolean isSupportedGraphics2D(Graphics2D g2d);
- private boolean hasUnsupportedAttributes(TextNode node) {
- Iterator iter = node.getTextRuns().iterator();
- while (iter.hasNext()) {
- StrokingTextPainter.TextRun
- run = (StrokingTextPainter.TextRun)iter.next();
- AttributedCharacterIterator aci = run.getACI();
- boolean hasUnsupported = hasUnsupportedAttributes(aci);
- if (hasUnsupported) {
- return true;
- }
- }
- return false;
- }
-
- private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) {
- boolean hasUnsupported = false;
-
- Font font = getFont(aci);
- String text = getText(aci);
- if (hasUnsupportedGlyphs(text, font)) {
- log.trace("-> Unsupported glyphs found");
- hasUnsupported = true;
- }
+ private class TextRunPainter {
- TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
- if ((tpi != null)
- && ((tpi.strokeStroke != null && tpi.strokePaint != null)
- || (tpi.strikethroughStroke != null)
- || (tpi.underlineStroke != null)
- || (tpi.overlineStroke != null))) {
- log.trace("-> under/overlines etc. found");
- hasUnsupported = true;
- }
+ private Point2D currentLocation;
- //Alpha is not supported
- Paint foreground = (Paint) aci.getAttribute(TextAttribute.FOREGROUND);
- if (foreground instanceof Color) {
- Color col = (Color)foreground;
- if (col.getAlpha() != 255) {
- log.trace("-> transparency found");
- hasUnsupported = true;
+ public void paintTextRuns(Iterable<StrokingTextPainter.TextRun> textRuns, Graphics2D g2d,
+ Point2D nodeLocation) {
+ currentLocation = new Point2D.Double(nodeLocation.getX(), nodeLocation.getY());
+ for (StrokingTextPainter.TextRun run : textRuns) {
+ paintTextRun(run, g2d);
}
}
- Object letSpace = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
- if (letSpace != null) {
- log.trace("-> letter spacing found");
- hasUnsupported = true;
- }
-
- Object wordSpace = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
- if (wordSpace != null) {
- log.trace("-> word spacing found");
- hasUnsupported = true;
- }
-
- Object lengthAdjust = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.LENGTH_ADJUST);
- if (lengthAdjust != null) {
- log.trace("-> length adjustments found");
- hasUnsupported = true;
- }
-
- Object writeMod = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE);
- if (writeMod != null
- && !GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
- writeMod)) {
- log.trace("-> Unsupported writing modes found");
- hasUnsupported = true;
- }
-
- Object vertOr = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
- if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
- vertOr)) {
- log.trace("-> vertical orientation found");
- hasUnsupported = true;
- }
-
- Object rcDel = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
- //Batik 1.6 returns null here which makes it impossible to determine whether this can
- //be painted or not, i.e. fall back to stroking. :-(
- if (rcDel != null && !(rcDel instanceof SVGOMTextElement)) {
- log.trace("-> spans found");
- hasUnsupported = true; //Filter spans
- }
-
- if (hasUnsupported) {
- log.trace("Unsupported attributes found in ACI, using StrokingTextPainter");
- }
- return hasUnsupported;
- }
-
- /**
- * Paint a list of text runs on the Graphics2D at a given location.
- * @param textRuns the list of text runs
- * @param g2d the Graphics2D to paint to
- * @param loc the current location of the "cursor"
- */
- protected void paintTextRuns(List textRuns, Graphics2D g2d, Point2D loc) {
- Point2D currentloc = loc;
- Iterator i = textRuns.iterator();
- while (i.hasNext()) {
- StrokingTextPainter.TextRun
- run = (StrokingTextPainter.TextRun)i.next();
- currentloc = paintTextRun(run, g2d, currentloc);
- }
- }
-
- /**
- * Paint a single text run on the Graphics2D at a given location.
- * @param run the text run to paint
- * @param g2d the Graphics2D to paint to
- * @param loc the current location of the "cursor"
- * @return the new location of the "cursor" after painting the text run
- */
- protected Point2D paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d, Point2D loc) {
- AttributedCharacterIterator aci = run.getACI();
- aci.first();
-
- updateLocationFromACI(aci, loc);
- AffineTransform at = g2d.getTransform();
- loc = at.transform(loc, null);
-
- // font
- Font font = getFont(aci);
- if (font != null) {
- nativeTextHandler.setOverrideFont(font);
- }
-
- // color
- TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
- if (tpi == null) {
- return loc;
- }
- Paint foreground = tpi.fillPaint;
- if (foreground instanceof Color) {
- Color col = (Color)foreground;
- g2d.setColor(col);
- }
- g2d.setPaint(foreground);
-
- // text anchor
- TextNode.Anchor anchor = (TextNode.Anchor)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
-
- // text
- String txt = getText(aci);
- float advance = getStringWidth(txt, font);
- float tx = 0;
- if (anchor != null) {
- switch (anchor.getType()) {
- case TextNode.Anchor.ANCHOR_MIDDLE:
- tx = -advance / 2;
- break;
- case TextNode.Anchor.ANCHOR_END:
- tx = -advance;
- break;
- default: //nop
+ private void paintTextRun(StrokingTextPainter.TextRun run, Graphics2D g2d) {
+ AttributedCharacterIterator aci = run.getACI();
+ aci.first();
+ updateLocationFromACI(aci, currentLocation);
+ // font
+ Font font = getFont(aci);
+ if (font != null) {
+ nativeTextHandler.setOverrideFont(font);
}
- }
-
- // draw string
- double x = loc.getX();
- double y = loc.getY();
- try {
+ // color
+ TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
+ if (tpi == null) {
+ return;
+ }
+ Paint foreground = tpi.fillPaint;
+ if (foreground instanceof Color) {
+ Color col = (Color) foreground;
+ g2d.setColor(col);
+ }
+ g2d.setPaint(foreground);
+ // text anchor
+ TextNode.Anchor anchor = (TextNode.Anchor) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
+ // text
+ String txt = getText(aci);
+ double advance = font == null ? run.getLayout().getAdvance2D().getX() : getStringWidth(txt, font);
+ double tx = 0;
+ if (anchor != null) {
+ switch (anchor.getType()) {
+ case TextNode.Anchor.ANCHOR_MIDDLE:
+ tx = -advance / 2;
+ break;
+ case TextNode.Anchor.ANCHOR_END:
+ tx = -advance;
+ break;
+ default: //nop
+ }
+ }
+ // draw string
+ Point2D outputLocation = g2d.getTransform().transform(currentLocation, null);
+ double x = outputLocation.getX();
+ double y = outputLocation.getY();
try {
- nativeTextHandler.drawString(g2d, txt, (float)x + tx, (float)y);
- } catch (IOException ioe) {
- if (g2d instanceof AFPGraphics2D) {
- ((AFPGraphics2D)g2d).handleIOException(ioe);
+ try {
+ //TODO draw underline and overline if set
+ nativeTextHandler.drawString(g2d, txt, (float) (x + tx), (float) y);
+ //TODO draw strikethrough if set
+ } catch (IOException ioe) {
+ if (g2d instanceof AFPGraphics2D) {
+ ((AFPGraphics2D) g2d).handleIOException(ioe);
+ }
}
+ } finally {
+ nativeTextHandler.setOverrideFont(null);
+ }
+ currentLocation.setLocation(currentLocation.getX() + advance, currentLocation.getY());
+ }
+ private void updateLocationFromACI(AttributedCharacterIterator aci, Point2D loc) {
+ //Adjust position of span
+ Float xpos = (Float) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.X);
+ Float ypos = (Float) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.Y);
+ Float dxpos = (Float) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.DX);
+ Float dypos = (Float) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.DY);
+ if (xpos != null) {
+ loc.setLocation(xpos.doubleValue(), loc.getY());
+ }
+ if (ypos != null) {
+ loc.setLocation(loc.getX(), ypos.doubleValue());
+ }
+ if (dxpos != null) {
+ loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY());
+ }
+ if (dypos != null) {
+ loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue());
}
- } finally {
- nativeTextHandler.setOverrideFont(null);
}
- loc.setLocation(loc.getX() + advance, loc.getY());
- return loc;
}
/**
@@ -305,36 +200,9 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
for (char c = aci.first(); c != CharacterIterator.DONE; c = aci.next()) {
sb.append(c);
}
- aci.first();
return sb.toString();
}
- private void updateLocationFromACI(
- AttributedCharacterIterator aci,
- Point2D loc) {
- //Adjust position of span
- Float xpos = (Float)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.X);
- Float ypos = (Float)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.Y);
- Float dxpos = (Float)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.DX);
- Float dypos = (Float)aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.DY);
- if (xpos != null) {
- loc.setLocation(xpos.doubleValue(), loc.getY());
- }
- if (ypos != null) {
- loc.setLocation(loc.getX(), ypos.doubleValue());
- }
- if (dxpos != null) {
- loc.setLocation(loc.getX() + dxpos.doubleValue(), loc.getY());
- }
- if (dypos != null) {
- loc.setLocation(loc.getX(), loc.getY() + dypos.doubleValue());
- }
- }
-
private Font getFont(AttributedCharacterIterator aci) {
Font[] fonts = ACIUtils.findFontsForBatikACI(aci, nativeTextHandler.getFontInfo());
return fonts == null ? null : fonts[0];
@@ -360,21 +228,6 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
return wordWidth / 1000f;
}
- private boolean hasUnsupportedGlyphs(String str, Font font) {
- if (font == null) {
- return true;
- }
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
- if (!font.hasChar(c)) {
- return true;
- }
- }
- }
- return false;
- }
-
/**
* Get the outline shape of the text characters.
* This uses the StrokingTextPainter to get the outline
@@ -384,7 +237,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @return the outline shape of the text characters
*/
public Shape getOutline(TextNode node) {
- return PROXY_PAINTER.getOutline(node);
+ return proxyTextPainter.getOutline(node);
}
/**
@@ -399,7 +252,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
/* (todo) getBounds2D() is too slow
* because it uses the StrokingTextPainter. We should implement this
* method ourselves. */
- return PROXY_PAINTER.getBounds2D(node);
+ return proxyTextPainter.getBounds2D(node);
}
/**
@@ -411,7 +264,7 @@ public abstract class AbstractFOPTextPainter implements TextPainter {
* @return the bounds of the text
*/
public Rectangle2D getGeometryBounds(TextNode node) {
- return PROXY_PAINTER.getGeometryBounds(node);
+ return proxyTextPainter.getGeometryBounds(node);
}
// Methods that have no purpose for PS
diff --git a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java
index e04bf0d35..9b1606953 100644
--- a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java
+++ b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java
@@ -36,9 +36,9 @@ import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.SimpleLog;
-import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.util.DocumentFactory;
+import org.apache.batik.gvt.font.FontFamilyResolver;
import org.apache.batik.transcoder.ErrorHandler;
import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
@@ -56,6 +56,8 @@ import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
import org.apache.xmlgraphics.util.UnitConv;
+import org.apache.fop.svg.font.FOPFontFamilyResolver;
+
/**
* This is the common base class of all of FOP's transcoders.
*/
@@ -86,11 +88,6 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
/** The value to turn off text stroking. */
public static final Boolean VALUE_FORMAT_OFF = Boolean.FALSE;
- /**
- * The user agent dedicated to this Transcoder.
- */
- protected UserAgent userAgent = createUserAgent();
-
private Log logger;
private EntityResolver resolver;
private Configuration cfg = null;
@@ -113,7 +110,7 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
* this method if you need non-default behaviour.
* @return UserAgent the newly created user agent
*/
- protected UserAgent createUserAgent() {
+ protected FOPTranscoderUserAgent createUserAgent() {
return new FOPTranscoderUserAgent();
}
@@ -331,6 +328,8 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
*/
protected class FOPTranscoderUserAgent extends SVGAbstractTranscoderUserAgent {
+ private FOPFontFamilyResolver fontFamilyResolver;
+
/**
* Displays the specified error message using the {@link ErrorHandler}.
* @param message the message to display
@@ -386,6 +385,15 @@ public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implem
return "print";
}
+ public void setFontFamilyResolver(FOPFontFamilyResolver resolver) {
+ fontFamilyResolver = resolver;
+ }
+
+ @Override
+ public FontFamilyResolver getFontFamilyResolver() {
+ return fontFamilyResolver;
+ }
+
}
}
diff --git a/src/java/org/apache/fop/svg/NativeTextPainter.java b/src/java/org/apache/fop/svg/NativeTextPainter.java
index 4513e0101..200f6558b 100644
--- a/src/java/org/apache/fop/svg/NativeTextPainter.java
+++ b/src/java/org/apache/fop/svg/NativeTextPainter.java
@@ -19,7 +19,14 @@
package org.apache.fop.svg;
+import java.awt.BasicStroke;
+import java.awt.Color;
import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
import java.io.IOException;
import java.text.AttributedCharacterIterator;
import java.util.List;
@@ -27,11 +34,17 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.batik.bridge.SVGGVTFont;
+import org.apache.batik.gvt.font.FontFamilyResolver;
+import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
+import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextSpanLayout;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
+import org.apache.fop.svg.font.FOPGVTFont;
import org.apache.fop.util.CharUtilities;
/**
@@ -41,17 +54,26 @@ import org.apache.fop.util.CharUtilities;
public abstract class NativeTextPainter extends StrokingTextPainter {
/** the logger for this class */
- protected Log log = LogFactory.getLog(NativeTextPainter.class);
+ protected static final Log log = LogFactory.getLog(NativeTextPainter.class);
+
+ private static final boolean DEBUG = false;
/** the font collection */
protected final FontInfo fontInfo;
+ protected final FontFamilyResolver fontFamilyResolver;
+
+ protected Font font;
+
+ protected TextPaintInfo tpi;
+
/**
* Creates a new instance.
* @param fontInfo the font collection
*/
public NativeTextPainter(FontInfo fontInfo) {
this.fontInfo = fontInfo;
+ this.fontFamilyResolver = new FOPFontFamilyResolverImpl(fontInfo);
}
/**
@@ -68,11 +90,93 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
* @param g2d the target Graphics2D instance
* @throws IOException if an I/O error occurs while rendering the text
*/
- protected abstract void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException;
+ protected final void paintTextRun(TextRun textRun, Graphics2D g2d) throws IOException {
+ AttributedCharacterIterator runaci = textRun.getACI();
+ runaci.first();
+
+ tpi = (TextPaintInfo) runaci.getAttribute(PAINT_INFO);
+ if (tpi == null || !tpi.visible) {
+ return;
+ }
+ if (tpi.composite != null) {
+ g2d.setComposite(tpi.composite);
+ }
+
+ //------------------------------------
+ TextSpanLayout layout = textRun.getLayout();
+ logTextRun(runaci, layout);
+ runaci.first(); //Reset ACI
+
+ GeneralPath debugShapes = null;
+ if (DEBUG) {
+ debugShapes = new GeneralPath();
+ }
+
+ preparePainting(g2d);
+
+ GVTGlyphVector gv = layout.getGlyphVector();
+ if (!(gv.getFont() instanceof FOPGVTFont)) {
+ assert gv.getFont() == null || gv.getFont() instanceof SVGGVTFont;
+ //Draw using Java2D when no native fonts are available
+ textRun.getLayout().draw(g2d);
+ return;
+ }
+ font = ((FOPGVTFont) gv.getFont()).getFont();
+
+ saveGraphicsState();
+ setInitialTransform(g2d.getTransform());
+ clip(g2d.getClip());
+ beginTextObject();
+
+ AffineTransform localTransform = new AffineTransform();
+ Point2D prevPos = null;
+ AffineTransform prevGlyphTransform = null;
+ for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
+ if (!gv.isGlyphVisible(index)) {
+ continue;
+ }
+ Point2D glyphPos = gv.getGlyphPosition(index);
+
+ AffineTransform glyphTransform = gv.getGlyphTransform(index);
+ if (log.isTraceEnabled()) {
+ log.trace("pos " + glyphPos + ", transform " + glyphTransform);
+ }
+ if (DEBUG) {
+ Shape sh = gv.getGlyphLogicalBounds(index);
+ if (sh == null) {
+ sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
+ }
+ debugShapes.append(sh, false);
+ }
+
+ //Exact position of the glyph
+ localTransform.setToIdentity();
+ localTransform.translate(glyphPos.getX(), glyphPos.getY());
+ if (glyphTransform != null) {
+ localTransform.concatenate(glyphTransform);
+ }
+ localTransform.scale(1, -1);
+
+ positionGlyph(prevPos, glyphPos, glyphTransform != null || prevGlyphTransform != null);
+ char glyph = (char) gv.getGlyphCode(index);
+ //Update last position
+ prevPos = glyphPos;
+ prevGlyphTransform = glyphTransform;
+
+ writeGlyph(glyph, localTransform);
+ }
+ endTextObject();
+ restoreGraphicsState();
+ if (DEBUG) {
+ //Paint debug shapes
+ g2d.setStroke(new BasicStroke(0));
+ g2d.setColor(Color.LIGHT_GRAY);
+ g2d.draw(debugShapes);
+ }
+ }
- /** {@inheritDoc} */
@Override
- protected void paintTextRuns(List textRuns, Graphics2D g2d) {
+ protected void paintTextRuns(@SuppressWarnings("rawtypes") List textRuns, Graphics2D g2d) {
if (log.isTraceEnabled()) {
log.trace("paintTextRuns: count = " + textRuns.size());
}
@@ -81,7 +185,7 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
return;
}
for (int i = 0; i < textRuns.size(); i++) {
- TextRun textRun = (TextRun)textRuns.get(i);
+ TextRun textRun = (TextRun) textRuns.get(i);
try {
paintTextRun(textRun, g2d);
} catch (IOException ioe) {
@@ -92,16 +196,6 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
}
/**
- * Finds an array of suitable fonts for a given AttributedCharacterIterator.
- * @param aci the character iterator
- * @return the array of fonts
- */
- protected Font[] findFonts(AttributedCharacterIterator aci) {
- Font[] fonts = ACIUtils.findFontsForBatikACI(aci, fontInfo);
- return fonts;
- }
-
- /**
* Collects all characters from an {@link AttributedCharacterIterator}.
* @param runaci the character iterator
* @return the characters
@@ -115,6 +209,25 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
return chars;
}
+ protected abstract void preparePainting(Graphics2D g2d);
+
+ protected abstract void saveGraphicsState() throws IOException;
+
+ protected abstract void restoreGraphicsState() throws IOException;
+
+ protected abstract void setInitialTransform(AffineTransform transform) throws IOException;
+
+ protected abstract void clip(Shape clip) throws IOException;
+
+ protected abstract void beginTextObject() throws IOException;
+
+ protected abstract void endTextObject() throws IOException;
+
+ protected abstract void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition);
+
+ protected abstract void writeGlyph(char glyph, AffineTransform transform) throws IOException;
+
+
/**
* @param runaci an attributed character iterator
* @param layout a text span layout
@@ -155,5 +268,9 @@ public abstract class NativeTextPainter extends StrokingTextPainter {
}
}
+ @Override
+ protected FontFamilyResolver getFontFamilyResolver() {
+ return this.fontFamilyResolver;
+ }
}
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index 1fcf9f870..42d79a931 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -189,6 +189,17 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
*/
protected OutputStream outputStream = null;
+ private TransparencyIgnoredEventListener transparencyIgnoredEventListener;
+
+ /**
+ * May be used to give proper feedback to the user when a particular PDF profile is
+ * being used that disallows transparency.
+ */
+ public interface TransparencyIgnoredEventListener {
+
+ void transparencyIgnored(Object pdfProfile);
+ }
+
/**
* Create a new PDFGraphics2D with the given pdf document info.
* This is used to create a Graphics object for use inside an already
@@ -203,7 +214,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
* @param size the current font size
*/
public PDFGraphics2D(boolean textAsShapes, FontInfo fi, PDFDocument doc,
- PDFResourceContext page, String pref, String font, float size) {
+ PDFResourceContext page, String pref, String font, float size,
+ TransparencyIgnoredEventListener listener) {
this(textAsShapes);
pdfDoc = doc;
this.colorHandler = new PDFColorHandler(doc.getResources());
@@ -213,6 +225,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
fontInfo = fi;
pageRef = pref;
paintingState = new PDFPaintingState();
+ this.transparencyIgnoredEventListener = listener;
}
/**
@@ -244,6 +257,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
this.nativeCount = g.nativeCount;
this.outputStream = g.outputStream;
this.ovFontState = g.ovFontState;
+ this.transparencyIgnoredEventListener = g.transparencyIgnoredEventListener;
}
/**
@@ -977,7 +991,7 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
PDFResourceContext context = new PDFResourceContext(res);
PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo,
pdfDoc, context, getPageReference(),
- "", 0);
+ "", 0, transparencyIgnoredEventListener);
pattGraphic.setGraphicContext(new GraphicContext());
pattGraphic.gc.validateTransformStack();
pattGraphic.setRenderingHints(this.getRenderingHints());
@@ -1430,18 +1444,21 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
*/
protected void applyAlpha(int fillAlpha, int strokeAlpha) {
if (fillAlpha != OPAQUE || strokeAlpha != OPAQUE) {
- checkTransparencyAllowed();
- Map<String, Float> vals = new java.util.HashMap<String, Float>();
- if (fillAlpha != OPAQUE) {
- vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f));
- }
- if (strokeAlpha != OPAQUE) {
- vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f));
+ Object profile = isTransparencyAllowed();
+ if (profile == null) {
+ Map<String, Float> vals = new java.util.HashMap<String, Float>();
+ if (fillAlpha != OPAQUE) {
+ vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f));
+ }
+ if (strokeAlpha != OPAQUE) {
+ vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f));
+ }
+ PDFGState gstate = pdfDoc.getFactory().makeGState(vals, paintingState.getGState());
+ resourceContext.addGState(gstate);
+ currentStream.write("/" + gstate.getName() + " gs\n");
+ } else if (transparencyIgnoredEventListener != null) {
+ transparencyIgnoredEventListener.transparencyIgnored(profile);
}
- PDFGState gstate = pdfDoc.getFactory().makeGState(
- vals, paintingState.getGState());
- resourceContext.addGState(gstate);
- currentStream.write("/" + gstate.getName() + " gs\n");
}
}
@@ -1686,8 +1703,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
}
/** Checks whether the use of transparency is allowed. */
- protected void checkTransparencyAllowed() {
- pdfDoc.getProfile().verifyTransparencyAllowed("Java2D graphics");
+ protected Object isTransparencyAllowed() {
+ return pdfDoc.getProfile().isTransparencyAllowed();
}
/**
diff --git a/src/java/org/apache/fop/svg/PDFTextPainter.java b/src/java/org/apache/fop/svg/PDFTextPainter.java
index ef376663f..c5fa9f04e 100644
--- a/src/java/org/apache/fop/svg/PDFTextPainter.java
+++ b/src/java/org/apache/fop/svg/PDFTextPainter.java
@@ -19,25 +19,17 @@
package org.apache.fop.svg;
-import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
-import java.text.AttributedCharacterIterator;
-import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.text.TextPaintInfo;
-import org.apache.batik.gvt.text.TextSpanLayout;
-import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.util.CharUtilities;
/**
* Renders the attributed character iterator of a {@link org.apache.batik.gvt.TextNode}.
@@ -51,11 +43,19 @@ import org.apache.fop.util.CharUtilities;
*/
class PDFTextPainter extends NativeTextPainter {
- private static final boolean DEBUG = false;
+ private PDFGraphics2D pdf;
+
+ private PDFTextUtil textUtil;
+
+ private double prevVisibleGlyphWidth;
+
+ private boolean repositionNextGlyph;
/**
* Create a new PDF text painter with the given font information.
+ *
* @param fi the font info
+ * @param fontFamilyResolver the Font Family Resolver
*/
public PDFTextPainter(FontInfo fi) {
super(fi);
@@ -67,29 +67,29 @@ class PDFTextPainter extends NativeTextPainter {
return g2d instanceof PDFGraphics2D;
}
- /** {@inheritDoc} */
@Override
- protected void paintTextRun(TextRun textRun, Graphics2D g2d) {
- AttributedCharacterIterator runaci = textRun.getACI();
- runaci.first();
+ protected void preparePainting(Graphics2D g2d) {
+ pdf = (PDFGraphics2D) g2d;
+ }
- TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
- if (tpi == null || !tpi.visible) {
- return;
- }
- if ((tpi != null) && (tpi.composite != null)) {
- g2d.setComposite(tpi.composite);
- }
+ @Override
+ protected void saveGraphicsState() {
+ pdf.saveGraphicsState();
+ }
- //------------------------------------
- TextSpanLayout layout = textRun.getLayout();
- logTextRun(runaci, layout);
- CharSequence chars = collectCharacters(runaci);
- runaci.first(); //Reset ACI
+ @Override
+ protected void restoreGraphicsState() {
+ pdf.restoreGraphicsState();
+ }
- final PDFGraphics2D pdf = (PDFGraphics2D)g2d;
+ @Override
+ protected void setInitialTransform(AffineTransform transform) {
+ createTextUtil();
+ textUtil.concatMatrix(transform);
+ }
- PDFTextUtil textUtil = new PDFTextUtil(pdf.fontInfo) {
+ private void createTextUtil() {
+ textUtil = new PDFTextUtil(pdf.fontInfo) {
protected void write(String code) {
pdf.currentStream.write(code);
}
@@ -97,142 +97,39 @@ class PDFTextPainter extends NativeTextPainter {
pdf.currentStream.append(code);
}
};
+ }
- if (DEBUG) {
- log.debug("Text: " + chars);
- pdf.currentStream.write("%Text: " + chars + "\n");
- }
-
- GeneralPath debugShapes = null;
- if (DEBUG) {
- debugShapes = new GeneralPath();
- }
-
- Font[] fonts = findFonts(runaci);
- if (fonts == null || fonts.length == 0) {
- //Draw using Java2D when no native fonts are available
- textRun.getLayout().draw(g2d);
- return;
- }
-
- pdf.saveGraphicsState();
- textUtil.concatMatrix(g2d.getTransform());
- Shape imclip = g2d.getClip();
- pdf.writeClip(imclip);
-
- applyColorAndPaint(tpi, pdf);
+ @Override
+ protected void clip(Shape clip) {
+ pdf.writeClip(clip);
+ }
+ @Override
+ protected void beginTextObject() {
+ applyColorAndPaint(tpi);
textUtil.beginTextObject();
- textUtil.setFonts(fonts);
- boolean stroke = (tpi.strokePaint != null)
- && (tpi.strokeStroke != null);
+ boolean stroke = (tpi.strokePaint != null) && (tpi.strokeStroke != null);
textUtil.setTextRenderingMode(tpi.fillPaint != null, stroke, false);
+ }
- AffineTransform localTransform = new AffineTransform();
- Point2D prevPos = null;
- double prevVisibleCharWidth = 0.0;
- GVTGlyphVector gv = layout.getGlyphVector();
- for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
- char ch = chars.charAt(index);
- boolean visibleChar = gv.isGlyphVisible(index)
- || (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch));
- logCharacter(ch, layout, index, visibleChar);
- if (!visibleChar) {
- continue;
- }
- Point2D glyphPos = gv.getGlyphPosition(index);
-
- AffineTransform glyphTransform = gv.getGlyphTransform(index);
- //TODO Glyph transforms could be refined so not every char has to be painted
- //with its own TJ command (stretch/squeeze case could be optimized)
- if (log.isTraceEnabled()) {
- log.trace("pos " + glyphPos + ", transform " + glyphTransform);
- }
- if (DEBUG) {
- Shape sh = gv.getGlyphLogicalBounds(index);
- if (sh == null) {
- sh = new Ellipse2D.Double(glyphPos.getX(), glyphPos.getY(), 2, 2);
- }
- debugShapes.append(sh, false);
- }
-
- //Exact position of the glyph
- localTransform.setToIdentity();
- localTransform.translate(glyphPos.getX(), glyphPos.getY());
- if (glyphTransform != null) {
- localTransform.concatenate(glyphTransform);
- }
- localTransform.scale(1, -1);
-
- boolean yPosChanged = (prevPos == null
- || prevPos.getY() != glyphPos.getY()
- || glyphTransform != null);
- if (yPosChanged) {
- if (index > 0) {
- textUtil.writeTJ();
- textUtil.writeTextMatrix(localTransform);
- }
- } else {
- double xdiff = glyphPos.getX() - prevPos.getX();
- //Width of previous character
- Font font = textUtil.getCurrentFont();
- double cw = prevVisibleCharWidth;
- double effxdiff = (1000 * xdiff) - cw;
- if (effxdiff != 0) {
- double adjust = (-effxdiff / font.getFontSize());
- textUtil.adjustGlyphTJ(adjust * 1000);
- }
- if (log.isTraceEnabled()) {
- log.trace("==> x diff: " + xdiff + ", " + effxdiff
- + ", charWidth: " + cw);
- }
- }
- Font f = textUtil.selectFontForChar(ch);
- char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch);
- char mappedChar = f.mapChar(paintChar);
- boolean encodingChanging = false; // used for single byte
- if (!textUtil.isMultiByteFont(f.getFontName())) {
- int encoding = mappedChar / 256;
- mappedChar = (char) (mappedChar % 256);
- if (textUtil.getCurrentEncoding() != encoding) {
- textUtil.setCurrentEncoding(encoding);
- encodingChanging = true;
- }
- }
- if (f != textUtil.getCurrentFont() || encodingChanging) {
- textUtil.writeTJ();
- textUtil.setCurrentFont(f);
- textUtil.writeTf(f);
- textUtil.writeTextMatrix(localTransform);
- }
- textUtil.writeTJMappedChar(mappedChar);
-
- //Update last position
- prevPos = glyphPos;
- prevVisibleCharWidth = textUtil.getCurrentFont().getCharWidth(chars.charAt(index));
- }
+ @Override
+ protected void endTextObject() {
textUtil.writeTJ();
textUtil.endTextObject();
- pdf.restoreGraphicsState();
- if (DEBUG) {
- g2d.setStroke(new BasicStroke(0));
- g2d.setColor(Color.LIGHT_GRAY);
- g2d.draw(debugShapes);
- }
}
- private void applyColorAndPaint(TextPaintInfo tpi, PDFGraphics2D pdf) {
+ private void applyColorAndPaint(TextPaintInfo tpi) {
Paint fillPaint = tpi.fillPaint;
Paint strokePaint = tpi.strokePaint;
Stroke stroke = tpi.strokeStroke;
int fillAlpha = PDFGraphics2D.OPAQUE;
if (fillPaint instanceof Color) {
- Color col = (Color)fillPaint;
+ Color col = (Color) fillPaint;
pdf.applyColor(col, true);
fillAlpha = col.getAlpha();
}
if (strokePaint instanceof Color) {
- Color col = (Color)strokePaint;
+ Color col = (Color) strokePaint;
pdf.applyColor(col, false);
}
pdf.applyPaint(fillPaint, true);
@@ -243,4 +140,46 @@ class PDFTextPainter extends NativeTextPainter {
pdf.applyAlpha(fillAlpha, PDFGraphics2D.OPAQUE);
}
+ @Override
+ protected void positionGlyph(Point2D prevPos, Point2D glyphPos, boolean reposition) {
+ // TODO Glyph transforms could be refined so not every char has to be painted
+ // with its own TJ command (stretch/squeeze case could be optimized)
+ repositionNextGlyph = (prevPos == null
+ || prevPos.getY() != glyphPos.getY()
+ || reposition);
+ if (!repositionNextGlyph) {
+ double xdiff = glyphPos.getX() - prevPos.getX();
+ //Width of previous character
+ double cw = prevVisibleGlyphWidth;
+ double effxdiff = (1000 * xdiff) - cw;
+ if (effxdiff != 0) {
+ double adjust = (-effxdiff / font.getFontSize());
+ textUtil.adjustGlyphTJ(adjust * 1000);
+ }
+ }
+ }
+
+ @Override
+ protected void writeGlyph(char glyph, AffineTransform transform) {
+ prevVisibleGlyphWidth = font.getWidth(glyph);
+ boolean encodingChanging = false; // used for single byte
+ if (!textUtil.isMultiByteFont(font.getFontName())) {
+ int encoding = glyph / 256;
+ glyph = (char) (glyph % 256);
+ if (textUtil.getCurrentEncoding() != encoding) {
+ textUtil.setCurrentEncoding(encoding);
+ encodingChanging = true;
+ }
+ }
+ if (repositionNextGlyph || encodingChanging) {
+ textUtil.writeTJ();
+ if (font != textUtil.getCurrentFont() || encodingChanging) {
+ textUtil.setCurrentFont(font);
+ textUtil.writeTf(font);
+ }
+ textUtil.writeTextMatrix(transform);
+ }
+ textUtil.writeTJMappedChar(glyph);
+ }
+
}
diff --git a/src/java/org/apache/fop/svg/PDFTextUtil.java b/src/java/org/apache/fop/svg/PDFTextUtil.java
index 8325dce1f..d525ecefc 100644
--- a/src/java/org/apache/fop/svg/PDFTextUtil.java
+++ b/src/java/org/apache/fop/svg/PDFTextUtil.java
@@ -30,7 +30,6 @@ import org.apache.fop.fonts.Typeface;
public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
private FontInfo fontInfo;
- private Font[] fonts;
private Font font;
private int encoding;
@@ -50,23 +49,6 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
}
/**
- * Sets the current fonts for the text object. For every character, the suitable font will
- * be selected.
- * @param fonts the new fonts
- */
- public void setFonts(Font[] fonts) {
- this.fonts = fonts;
- }
-
- /**
- * Sets the current font for the text object.
- * @param font the new font
- */
- public void setFont(Font font) {
- setFonts(new Font[] {font});
- }
-
- /**
* Returns the current font in use.
* @return the current font or null if no font is currently active.
*/
@@ -123,27 +105,4 @@ public abstract class PDFTextUtil extends org.apache.fop.pdf.PDFTextUtil {
}
}
- /**
- * Selects a font from the font list suitable to display the given character.
- * @param ch the character
- * @return the recommended Font to use
- */
- public Font selectFontForChar(char ch) {
- for (int i = 0, c = fonts.length; i < c; i++) {
- if (fonts[i].hasChar(ch)) {
- return fonts[i];
- }
- }
- return fonts[0]; //TODO Maybe fall back to painting with shapes
- }
-
- /**
- * Writes a char to the "TJ-Buffer".
- * @param ch the unmapped character
- */
- public void writeTJChar(char ch) {
- char mappedChar = font.mapChar(ch);
- writeTJMappedChar(mappedChar);
- }
-
}
diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java
index 9f0345657..1a3f154cb 100644
--- a/src/java/org/apache/fop/svg/PDFTranscoder.java
+++ b/src/java/org/apache/fop/svg/PDFTranscoder.java
@@ -31,7 +31,6 @@ import org.apache.avalon.framework.configuration.Configuration;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UnitProcessor;
-import org.apache.batik.bridge.UserAgent;
import org.apache.batik.ext.awt.RenderingHintsKeyExt;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderOutput;
@@ -39,6 +38,7 @@ import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.fop.Version;
import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
/**
* <p>This class enables to transcode an input to a PDF document.</p>
@@ -88,7 +88,7 @@ public class PDFTranscoder extends AbstractFOPTranscoder {
/**
* {@inheritDoc}
*/
- protected UserAgent createUserAgent() {
+ protected FOPTranscoderUserAgent createUserAgent() {
return new AbstractFOPTranscoder.FOPTranscoderUserAgent() {
// The PDF stuff wants everything at 72dpi
public float getPixelUnitToMillimeter() {
@@ -131,6 +131,8 @@ public class PDFTranscoder extends AbstractFOPTranscoder {
} else {
graphics.setupDefaultFontInfo();
}
+ ((FOPTranscoderUserAgent) userAgent).setFontFamilyResolver(
+ new FOPFontFamilyResolverImpl(graphics.getFontInfo()));
} catch (Exception e) {
throw new TranscoderException(
"Error while setting up PDFDocumentGraphics2D", e);
diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.java b/src/java/org/apache/fop/svg/SVGEventProducer.java
index 743649717..6bf7ed100 100644
--- a/src/java/org/apache/fop/svg/SVGEventProducer.java
+++ b/src/java/org/apache/fop/svg/SVGEventProducer.java
@@ -89,4 +89,13 @@ public interface SVGEventProducer extends EventProducer {
*/
void svgRenderingError(Object source, Exception e, String uri);
+ /**
+ * Transparency has been ignored due to restrictions from the PDF profile being used.
+ * @param source the event source
+ * @param pdfProfile the PDF profile
+ * @param uri the image URI, if available
+ * @event.severity WARN
+ */
+ void transparencyIgnored(Object source, Object pdfProfile, String uri);
+
}
diff --git a/src/java/org/apache/fop/svg/SVGEventProducer.xml b/src/java/org/apache/fop/svg/SVGEventProducer.xml
index 9d229a14b..f5e1d300a 100644
--- a/src/java/org/apache/fop/svg/SVGEventProducer.xml
+++ b/src/java/org/apache/fop/svg/SVGEventProducer.xml
@@ -22,4 +22,5 @@
<message key="info">SVG info: {message}</message>
<message key="svgNotBuilt">SVG graphic could not be built. Reason: {e}</message>
<message key="svgRenderingError">SVG graphic could not be rendered. Reason: {e}</message>
+ <message key="transparencyIgnored">Transparency in an SVG image will be ignored because {pdfProfile} does not allow it[ (see {uri})].</message>
</catalogue>
diff --git a/src/java/org/apache/fop/svg/SVGUserAgent.java b/src/java/org/apache/fop/svg/SVGUserAgent.java
index d43552289..a265b4fef 100644
--- a/src/java/org/apache/fop/svg/SVGUserAgent.java
+++ b/src/java/org/apache/fop/svg/SVGUserAgent.java
@@ -21,6 +21,8 @@ package org.apache.fop.svg;
import java.awt.geom.AffineTransform;
+import org.apache.batik.gvt.font.FontFamilyResolver;
+
import org.apache.fop.apps.FOUserAgent;
/**
@@ -34,10 +36,11 @@ public class SVGUserAgent extends SimpleSVGUserAgent {
/**
* Creates a new SVGUserAgent.
* @param foUserAgent the FO user agent to associate with this SVG user agent
+ * @param fontFamilyResolver the font family resolver
* @param at the current transform
*/
- public SVGUserAgent(FOUserAgent foUserAgent, AffineTransform at) {
- super(foUserAgent.getSourcePixelUnitToMillimeter(), at);
+ public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver, AffineTransform at) {
+ super(foUserAgent.getSourcePixelUnitToMillimeter(), at, fontFamilyResolver);
this.eventProducer = SVGEventProducer.Provider.get(foUserAgent.getEventBroadcaster());
}
@@ -45,8 +48,8 @@ public class SVGUserAgent extends SimpleSVGUserAgent {
* Creates a new SVGUserAgent.
* @param foUserAgent the FO user agent to associate with this SVG user agent
*/
- public SVGUserAgent(FOUserAgent foUserAgent) {
- this(foUserAgent, new AffineTransform());
+ public SVGUserAgent(FOUserAgent foUserAgent, FontFamilyResolver fontFamilyResolver) {
+ this(foUserAgent, fontFamilyResolver, new AffineTransform());
}
/**
diff --git a/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java b/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java
index 132c633dc..60a6020fc 100644
--- a/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java
+++ b/src/java/org/apache/fop/svg/SimpleSVGUserAgent.java
@@ -29,6 +29,7 @@ import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.apache.batik.bridge.UserAgentAdapter;
+import org.apache.batik.gvt.font.FontFamilyResolver;
/**
* A simple SVG user agent.
@@ -38,14 +39,18 @@ import org.apache.batik.bridge.UserAgentAdapter;
public class SimpleSVGUserAgent extends UserAgentAdapter {
private AffineTransform currentTransform = null;
+
private float pixelUnitToMillimeter = 0.0f;
+ private final FontFamilyResolver fontFamilyResolver;
+
/**
* Creates a new user agent.
* @param pixelUnitToMM the pixel to millimeter conversion factor currently in effect
* @param at the current transform
*/
- public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at) {
+ public SimpleSVGUserAgent(float pixelUnitToMM, AffineTransform at, FontFamilyResolver fontFamilyResolver) {
+ this.fontFamilyResolver = fontFamilyResolver;
pixelUnitToMillimeter = pixelUnitToMM;
currentTransform = at;
}
@@ -136,5 +141,10 @@ public class SimpleSVGUserAgent extends UserAgentAdapter {
return new Dimension(100, 100);
}
+ @Override
+ public FontFamilyResolver getFontFamilyResolver() {
+ return fontFamilyResolver;
+ }
+
}
diff --git a/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java
new file mode 100644
index 000000000..a5a25c4ce
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/AggregatingFontFamilyResolver.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.font;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.batik.bridge.FontFace;
+import org.apache.batik.gvt.font.FontFamilyResolver;
+import org.apache.batik.gvt.font.GVTFontFamily;
+
+public class AggregatingFontFamilyResolver implements FontFamilyResolver {
+
+ private final List<FontFamilyResolver> resolvers;
+
+ public AggregatingFontFamilyResolver(FontFamilyResolver... resolvers) {
+ this.resolvers = Arrays.<FontFamilyResolver>asList(resolvers);
+ }
+
+ public GVTFontFamily resolve(String familyName) {
+ for (FontFamilyResolver resolver : resolvers) {
+ GVTFontFamily family = resolver.resolve(familyName);
+ if (family != null) {
+ return family;
+ }
+ }
+ return null;
+ }
+
+ public GVTFontFamily resolve(String familyName, FontFace fontFace) {
+ for (FontFamilyResolver resolver : resolvers) {
+ GVTFontFamily family = resolver.resolve(familyName, fontFace);
+ if (family != null) {
+ return family;
+ }
+ }
+ return null;
+ }
+
+ public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception {
+ for (FontFamilyResolver resolver : resolvers) {
+ try {
+ return resolver.loadFont(in, fontFace);
+ } catch (Exception e) {
+ // Try the next one
+ }
+ }
+ return null;
+ }
+
+ public GVTFontFamily getDefault() {
+ return resolve("any");
+ }
+
+ public GVTFontFamily getFamilyThatCanDisplay(char c) {
+ for (FontFamilyResolver resolver : resolvers) {
+ GVTFontFamily family = resolver.getFamilyThatCanDisplay(c);
+ if (family != null) {
+ return family;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java
new file mode 100644
index 000000000..7af5f0b4f
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolver.java
@@ -0,0 +1,31 @@
+/*
+ * 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.font;
+
+import org.apache.batik.gvt.font.FontFamilyResolver;
+
+public interface FOPFontFamilyResolver extends FontFamilyResolver {
+
+ FOPGVTFontFamily resolve(String familyName);
+
+ FOPGVTFontFamily getDefault();
+
+ FOPGVTFontFamily getFamilyThatCanDisplay(char c);
+}
diff --git a/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java
new file mode 100644
index 000000000..4305838da
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FOPFontFamilyResolverImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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.font;
+
+import java.io.InputStream;
+import java.util.Map;
+
+import org.apache.batik.bridge.FontFace;
+import org.apache.batik.gvt.font.GVTFontFace;
+import org.apache.batik.gvt.font.GVTFontFamily;
+
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.Typeface;
+
+public class FOPFontFamilyResolverImpl implements FOPFontFamilyResolver {
+
+ private final FontInfo fontInfo;
+
+ public FOPFontFamilyResolverImpl(FontInfo fontInfo) {
+ this.fontInfo = fontInfo;
+ }
+
+ public FOPGVTFontFamily resolve(String familyName) {
+ return resolve(familyName, new GVTFontFace(familyName));
+ }
+
+ public FOPGVTFontFamily resolve(String familyName, FontFace fontFace) {
+ return resolve(familyName, (GVTFontFace) FontFace.createFontFace(familyName, fontFace));
+ }
+
+ private FOPGVTFontFamily resolve(String familyName, GVTFontFace fontFace) {
+ FOPGVTFontFamily gvtFontFamily = null;
+ FontTriplet triplet = fontInfo.fontLookup(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+ if (fontInfo.hasFont(familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL)) {
+ gvtFontFamily = new FOPGVTFontFamily(fontInfo, familyName, triplet, fontFace);
+ }
+ return gvtFontFamily;
+ }
+
+ public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public FOPGVTFontFamily getDefault() {
+ return resolve("any");
+ }
+
+ public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
+ Map<String, Typeface> fonts = fontInfo.getFonts();
+ for (Typeface font : fonts.values()) {
+ if (font.hasChar(c)) {
+ String fontFamily = font.getFamilyNames().iterator().next();
+ return new FOPGVTFontFamily(fontInfo, fontFamily,
+ new FontTriplet(fontFamily, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL),
+ new GVTFontFace(fontFamily));
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/font/FOPGVTFont.java b/src/java/org/apache/fop/svg/font/FOPGVTFont.java
new file mode 100644
index 000000000..c55e2fa8b
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FOPGVTFont.java
@@ -0,0 +1,159 @@
+/*
+ * 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.font;
+
+import java.awt.font.FontRenderContext;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+
+import org.apache.batik.gvt.font.GVTFont;
+import org.apache.batik.gvt.font.GVTFontFamily;
+import org.apache.batik.gvt.font.GVTGlyphVector;
+import org.apache.batik.gvt.font.GVTLineMetrics;
+
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontMetrics;
+
+public class FOPGVTFont implements GVTFont {
+
+ private final Font font;
+
+ private final GVTFontFamily fontFamily;
+
+ public FOPGVTFont(Font font, GVTFontFamily fontFamily) {
+ this.font = font;
+ this.fontFamily = fontFamily;
+ }
+
+ public Font getFont() {
+ return font;
+ }
+
+ public boolean canDisplay(char c) {
+ return font.hasChar(c);
+ }
+
+ public int canDisplayUpTo(char[] text, int start, int limit) {
+ for (int i = start; i < limit; i++) {
+ if (!canDisplay(text[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
+ public int canDisplayUpTo(CharacterIterator iter, int start, int limit) {
+ for (char c = iter.setIndex(start); iter.getIndex() < limit; c = iter.next()) {
+ if (!canDisplay(c)) {
+ return iter.getIndex();
+ }
+ }
+ return -1;
+ }
+
+ public int canDisplayUpTo(String str) {
+ for (int i = 0; i < str.length(); i++) {
+ if (!canDisplay(str.charAt(i))) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public GVTGlyphVector createGlyphVector(FontRenderContext frc, char[] chars) {
+ return createGlyphVector(frc, new String(chars));
+ }
+
+ public GVTGlyphVector createGlyphVector(FontRenderContext frc, CharacterIterator ci) {
+ // TODO Batik does manual glyph shaping for Arabic. Replace with complex scripts implementation
+ return new FOPGVTGlyphVector(this, ci, frc);
+ }
+
+ public GVTGlyphVector createGlyphVector(FontRenderContext frc,
+ int[] glyphCodes,
+ CharacterIterator ci) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str) {
+ StringCharacterIterator sci = new StringCharacterIterator(str);
+ return createGlyphVector(frc, sci);
+ }
+
+ public FOPGVTFont deriveFont(float size) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public String getFamilyName() {
+ return fontFamily.getFamilyName();
+ }
+
+ public GVTLineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, FontRenderContext frc) {
+ return getLineMetrics(limit - beginIndex);
+ }
+
+ GVTLineMetrics getLineMetrics(int numChars) {
+ numChars = numChars < 0 ? 0 : numChars;
+ FontMetrics metrics = font.getFontMetrics();
+ int size = font.getFontSize();
+ return new GVTLineMetrics(
+ metrics.getCapHeight(size) / 1000000f,
+ java.awt.Font.ROMAN_BASELINE, // Not actually used by Batik
+ null, // Not actually used by Batik
+ -metrics.getDescender(size) / 1000000f,
+ 0, // Not actually used by Batik
+ 0, // Not actually used by Batik
+ numChars,
+ -metrics.getStrikeoutPosition(size) / 1000000f,
+ metrics.getStrikeoutThickness(size) / 1000000f,
+ -metrics.getUnderlinePosition(size) / 1000000f,
+ metrics.getUnderlineThickness(size) / 1000000f,
+ -metrics.getCapHeight(size) / 1000000f, // Because this is what Batik does in GVTLineMetrics
+ metrics.getUnderlineThickness(size) / 1000000f);
+ }
+
+ public GVTLineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit,
+ FontRenderContext frc) {
+ return getLineMetrics(limit - beginIndex);
+ }
+
+ public GVTLineMetrics getLineMetrics(String str, FontRenderContext frc) {
+ return getLineMetrics(str.length());
+ }
+
+ public GVTLineMetrics getLineMetrics(String str, int beginIndex, int limit, FontRenderContext frc) {
+ return getLineMetrics(limit - beginIndex);
+ }
+
+ public float getSize() {
+ return font.getFontSize() / 1000f;
+ }
+
+ public float getVKern(int glyphCode1, int glyphCode2) {
+ return 0;
+ }
+
+ public float getHKern(int glyphCode1, int glyphCode2) {
+ // TODO Cannot be implemented until getKernValue takes glyph indices instead of character codes
+ return 0;
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java b/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.java
new file mode 100644
index 000000000..5be9419d3
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FOPGVTFontFamily.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.svg.font;
+
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.util.Map;
+
+import org.apache.batik.gvt.font.GVTFontFace;
+import org.apache.batik.gvt.font.GVTFontFamily;
+
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.svg.ACIUtils;
+
+public class FOPGVTFontFamily implements GVTFontFamily {
+
+ private final FontInfo fontInfo;
+
+ private final FontTriplet fontTriplet;
+
+ private final String familyName;
+
+ private GVTFontFace fontFace;
+
+ public FOPGVTFontFamily(FontInfo fontInfo, String familyName, FontTriplet triplet, GVTFontFace fontFace) {
+ this.fontInfo = fontInfo;
+ this.fontTriplet = triplet;
+ this.familyName = familyName;
+ this.fontFace = fontFace;
+ }
+
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ public GVTFontFace getFontFace() {
+ return fontFace;
+ }
+
+ public FOPGVTFont deriveFont(float size, AttributedCharacterIterator aci) {
+ return deriveFont(size, aci.getAttributes());
+ }
+
+ public FOPGVTFont deriveFont(float size, @SuppressWarnings("rawtypes") Map attrs) {
+ Float fontWeight = (Float) attrs.get(TextAttribute.WEIGHT);
+ int weight = fontWeight == null ? fontTriplet.getWeight() : ACIUtils.toCSSWeight(fontWeight);
+ Float fontStyle = (Float) attrs.get(TextAttribute.POSTURE);
+ String style = fontStyle == null ? fontTriplet.getStyle() : ACIUtils.toStyle(fontStyle);
+ FontTriplet triplet = fontInfo.fontLookup(fontTriplet.getName(), style, weight);
+ return new FOPGVTFont(fontInfo.getFontInstance(triplet, (int) (size * 1000)), this);
+ }
+
+ public boolean isComplex() {
+ return false;
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java b/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java
new file mode 100644
index 000000000..3567bb508
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FOPGVTGlyphVector.java
@@ -0,0 +1,339 @@
+/*
+ * 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.font;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphJustificationInfo;
+import java.awt.font.GlyphMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.Arrays;
+
+import org.apache.batik.gvt.font.GVTFont;
+import org.apache.batik.gvt.font.GVTGlyphMetrics;
+import org.apache.batik.gvt.font.GVTGlyphVector;
+import org.apache.batik.gvt.font.GVTLineMetrics;
+
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.GlyphMapping;
+import org.apache.fop.fonts.TextFragment;
+import org.apache.fop.traits.MinOptMax;
+
+class FOPGVTGlyphVector implements GVTGlyphVector {
+
+ private final CharacterIterator charIter;
+
+ private final FOPGVTFont font;
+
+ private final int fontSize;
+
+ private final FontMetrics fontMetrics;
+
+ private final FontRenderContext frc;
+
+ private int[] glyphs;
+
+ private float[] positions;
+
+ private Rectangle2D[] boundingBoxes;
+
+ private GeneralPath outline;
+
+ private AffineTransform[] glyphTransforms;
+
+ private boolean[] glyphVisibilities;
+
+ private Rectangle2D logicalBounds;
+
+ FOPGVTGlyphVector(FOPGVTFont font, final CharacterIterator iter, FontRenderContext frc) {
+ this.charIter = iter;
+ this.font = font;
+ Font f = font.getFont();
+ this.fontSize = f.getFontSize();
+ this.fontMetrics = f.getFontMetrics();
+ this.frc = frc;
+ }
+
+ public void performDefaultLayout() {
+ Font f = font.getFont();
+ TextFragment text = new SVGTextFragment(charIter);
+ MinOptMax letterSpaceIPD = MinOptMax.ZERO;
+ MinOptMax[] letterSpaceAdjustments = new MinOptMax[charIter.getEndIndex() - charIter.getBeginIndex()];
+ GlyphMapping mapping = GlyphMapping.doGlyphMapping(text, charIter.getBeginIndex(), charIter.getEndIndex(),
+ f, letterSpaceIPD, letterSpaceAdjustments, '\0', '\0', false, 0 /* TODO */);
+ glyphs = buildGlyphs(f, mapping.mapping != null ? new StringCharacterIterator(mapping.mapping) : charIter);
+ buildGlyphPositions(mapping, letterSpaceAdjustments);
+ this.glyphVisibilities = new boolean[this.glyphs.length];
+ Arrays.fill(glyphVisibilities, true);
+ this.glyphTransforms = new AffineTransform[this.glyphs.length];
+ }
+
+ private static class SVGTextFragment implements TextFragment {
+
+ private final CharacterIterator charIter;
+
+ SVGTextFragment(CharacterIterator charIter) {
+ this.charIter = charIter;
+ }
+
+ public CharSequence subSequence(int startIndex, int endIndex) {
+ StringBuilder sb = new StringBuilder();
+ for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) {
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ public String getScript() {
+ return "DFLT"; // TODO pass on script value from SVG
+ }
+
+ public String getLanguage() {
+ return "dflt"; // TODO pass on language value from SVG
+ }
+
+ public char charAt(int index) {
+ return charIter.setIndex(index - charIter.getBeginIndex());
+ }
+ }
+
+ private int[] buildGlyphs(Font font, final CharacterIterator charIter) {
+ int[] glyphs = new int[charIter.getEndIndex() - charIter.getBeginIndex()];
+ int index = 0;
+ for (char c = charIter.first(); c != CharacterIterator.DONE; c = charIter.next()) {
+ glyphs[index] = font.mapChar(c);
+ index++;
+ }
+ return glyphs;
+ }
+
+ private void buildGlyphPositions(GlyphMapping ai, MinOptMax[] letterSpaceAdjustments) {
+ positions = new float[2 * glyphs.length + 2];
+ if (ai.gposAdjustments != null) {
+ assert ai.gposAdjustments.length == glyphs.length;
+ for (int glyphIndex = 0; glyphIndex < glyphs.length; glyphIndex++) {
+ int n = 2 * glyphIndex;
+ if (ai.gposAdjustments[glyphIndex] != null) {
+ for (int p = 0; p < 4; p++) {
+ positions[n + p] += ai.gposAdjustments[glyphIndex][p] / 1000f;
+ }
+ }
+ positions[n + 2] += positions[n] + getGlyphWidth(glyphIndex);
+ }
+ } else {
+ for (int i = 0, n = 2; i < glyphs.length; i++, n += 2) {
+ int kern = i < glyphs.length - 1 && letterSpaceAdjustments[i + 1] != null
+ ? letterSpaceAdjustments[i + 1].getOpt()
+ : 0;
+ positions[n] = positions[n - 2] + getGlyphWidth(i) + kern / 1000f;
+ positions[n + 1] = 0;
+ }
+ }
+ }
+
+ private float getGlyphWidth(int index) {
+ return fontMetrics.getWidth(glyphs[index], fontSize) / 1000000f;
+ }
+
+ public GVTFont getFont() {
+ return font;
+ }
+
+ public FontRenderContext getFontRenderContext() {
+ return frc;
+ }
+
+ public int getGlyphCode(int glyphIndex) {
+ return glyphs[glyphIndex];
+ }
+
+ public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
+ int[] codeReturn) {
+ if (codeReturn == null) {
+ codeReturn = new int[numEntries];
+ }
+ System.arraycopy(glyphs, beginGlyphIndex, codeReturn, 0, numEntries);
+ return codeReturn;
+ }
+
+ public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ public Shape getGlyphLogicalBounds(int glyphIndex) {
+ GVTGlyphMetrics metrics = getGlyphMetrics(glyphIndex);
+ Point2D pos = getGlyphPosition(glyphIndex);
+ GVTLineMetrics fontMetrics = font.getLineMetrics(0);
+ Rectangle2D bounds = new Rectangle2D.Float(0, -fontMetrics.getDescent(), metrics.getHorizontalAdvance(),
+ fontMetrics.getAscent() + fontMetrics.getDescent());
+ AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
+ AffineTransform transf = getGlyphTransform(glyphIndex);
+ if (transf != null) {
+ t.concatenate(transf);
+ }
+ t.scale(1, -1); // Translate from glyph coordinate system to user
+ return t.createTransformedShape(bounds);
+ }
+
+ public GVTGlyphMetrics getGlyphMetrics(int glyphIndex) {
+ Rectangle2D bbox = getBoundingBoxes()[glyphIndex];
+ return new GVTGlyphMetrics(positions[2 * (glyphIndex + 1)] - positions[2 * glyphIndex],
+ (fontMetrics.getAscender(fontSize) - fontMetrics.getDescender(fontSize)) / 1000000f,
+ bbox, GlyphMetrics.STANDARD);
+ }
+
+ public Shape getGlyphOutline(int glyphIndex) {
+ Shape glyphBox = getBoundingBoxes()[glyphIndex];
+ AffineTransform tr = AffineTransform.getTranslateInstance(positions[glyphIndex * 2],
+ positions[glyphIndex * 2 + 1]);
+ AffineTransform glyphTransform = getGlyphTransform(glyphIndex);
+ if (glyphTransform != null) {
+ tr.concatenate(glyphTransform);
+ }
+ return tr.createTransformedShape(glyphBox);
+ }
+
+ public Rectangle2D getGlyphCellBounds(int glyphIndex) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ public Point2D getGlyphPosition(int glyphIndex) {
+ int positionIndex = glyphIndex * 2;
+ return new Point2D.Float(positions[positionIndex], positions[positionIndex + 1]);
+ }
+
+ public float[] getGlyphPositions(int beginGlyphIndex, int numEntries, float[] positionReturn) {
+ if (positionReturn == null) {
+ positionReturn = new float[numEntries * 2];
+ }
+ System.arraycopy(positions, beginGlyphIndex * 2, positionReturn, 0, numEntries * 2);
+ return positionReturn;
+ }
+
+ public AffineTransform getGlyphTransform(int glyphIndex) {
+ return glyphTransforms[glyphIndex];
+ }
+
+ public Shape getGlyphVisualBounds(int glyphIndex) {
+ Rectangle2D bbox = getBoundingBoxes()[glyphIndex];
+ Point2D pos = getGlyphPosition(glyphIndex);
+ AffineTransform t = AffineTransform.getTranslateInstance(pos.getX(), pos.getY());
+ AffineTransform transf = getGlyphTransform(glyphIndex);
+ if (transf != null) {
+ t.concatenate(transf);
+ }
+ return t.createTransformedShape(bbox);
+ }
+
+ public Rectangle2D getLogicalBounds() {
+ if (logicalBounds == null) {
+ GeneralPath logicalBoundsPath = new GeneralPath();
+ for (int i = 0; i < getNumGlyphs(); i++) {
+ Shape glyphLogicalBounds = getGlyphLogicalBounds(i);
+ logicalBoundsPath.append(glyphLogicalBounds, false);
+ }
+ logicalBounds = logicalBoundsPath.getBounds2D();
+ }
+ return logicalBounds;
+ }
+
+ public int getNumGlyphs() {
+ return glyphs.length;
+ }
+
+ public Shape getOutline() {
+ if (outline == null) {
+ outline = new GeneralPath();
+ for (int i = 0; i < glyphs.length; i++) {
+ outline.append(getGlyphOutline(i), false);
+ }
+ }
+ return outline;
+ }
+
+ public Shape getOutline(float x, float y) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ public Rectangle2D getGeometricBounds() {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ public Rectangle2D getBounds2D(AttributedCharacterIterator aci) {
+ return getOutline().getBounds2D();
+ }
+
+ public void setGlyphPosition(int glyphIndex, Point2D newPos) {
+ int idx = glyphIndex * 2;
+ positions[idx] = (float) newPos.getX();
+ positions[idx + 1] = (float) newPos.getY();
+ }
+
+ public void setGlyphTransform(int glyphIndex, AffineTransform newTX) {
+ glyphTransforms[glyphIndex] = newTX;
+ }
+
+ public void setGlyphVisible(int glyphIndex, boolean visible) {
+ glyphVisibilities[glyphIndex] = visible;
+ }
+
+ public boolean isGlyphVisible(int glyphIndex) {
+ return glyphVisibilities[glyphIndex];
+ }
+
+ public int getCharacterCount(int startGlyphIndex, int endGlyphIndex) {
+ // TODO Not that simple if complex scripts are involved
+ return endGlyphIndex - startGlyphIndex + 1;
+ }
+
+ public void draw(Graphics2D graphics2d, AttributedCharacterIterator aci) {
+ // NOP
+ }
+
+ private Rectangle2D[] getBoundingBoxes() {
+ if (boundingBoxes == null) {
+ buildBoundingBoxes();
+ }
+ return boundingBoxes;
+ }
+
+ private void buildBoundingBoxes() {
+ boundingBoxes = new Rectangle2D[glyphs.length];
+ for (int i = 0; i < glyphs.length; i++) {
+ Rectangle bbox = fontMetrics.getBoundingBox(glyphs[i], fontSize);
+ boundingBoxes[i] = new Rectangle2D.Float(bbox.x / 1000000f, -(bbox.y + bbox.height) / 1000000f,
+ bbox.width / 1000000f, bbox.height / 1000000f);
+ }
+ }
+
+}
diff --git a/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java b/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java
new file mode 100644
index 000000000..93b92ea36
--- /dev/null
+++ b/src/java/org/apache/fop/svg/font/FilteringFontFamilyResolver.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.font;
+
+import java.io.InputStream;
+
+import org.apache.batik.bridge.FontFace;
+import org.apache.batik.gvt.font.GVTFontFamily;
+
+
+public class FilteringFontFamilyResolver implements FOPFontFamilyResolver {
+
+ private final FOPFontFamilyResolver delegate;
+
+ public FilteringFontFamilyResolver(FOPFontFamilyResolver delegate) {
+ this.delegate = delegate;
+ }
+
+ public FOPGVTFontFamily resolve(String familyName) {
+ return delegate.resolve(familyName);
+ }
+
+ public GVTFontFamily resolve(String familyName, FontFace fontFace) {
+ return delegate.resolve(familyName, fontFace);
+ }
+
+ public GVTFontFamily loadFont(InputStream in, FontFace fontFace) throws Exception {
+ return delegate.loadFont(in, fontFace);
+ }
+
+ public FOPGVTFontFamily getDefault() {
+ return delegate.getDefault();
+ }
+
+ public FOPGVTFontFamily getFamilyThatCanDisplay(char c) {
+ return delegate.getFamilyThatCanDisplay(c);
+ }
+
+}
diff --git a/test/java/org/apache/fop/AbstractBasicTranscoderTest.java b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java
index 2087c8df2..7a40b353a 100644
--- a/test/java/org/apache/fop/AbstractBasicTranscoderTest.java
+++ b/test/java/org/apache/fop/AbstractBasicTranscoderTest.java
@@ -24,13 +24,15 @@ import java.io.InputStream;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+
import org.apache.batik.transcoder.Transcoder;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
-import org.apache.commons.io.output.ByteArrayOutputStream;
import static org.apache.fop.FOPTestUtils.getBaseDir;
-import static org.junit.Assert.assertTrue;
/**
* Basic runtime test for FOP's transcoders. It is used to verify that
diff --git a/test/java/org/apache/fop/BasicDriverTestCase.java b/test/java/org/apache/fop/BasicDriverTestCase.java
index f149b451e..e89a1c558 100644
--- a/test/java/org/apache/fop/BasicDriverTestCase.java
+++ b/test/java/org/apache/fop/BasicDriverTestCase.java
@@ -28,11 +28,13 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
-import org.apache.fop.apps.FOPException;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
@@ -40,7 +42,6 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.cli.InputHandler;
import static org.apache.fop.FOPTestUtils.getBaseDir;
-import static org.junit.Assert.assertTrue;
/**
* Basic runtime test for the old Fop class. It is used to verify that
@@ -136,7 +137,7 @@ public class BasicDriverTestCase {
InputHandler handler = new InputHandler(xmlFile, xsltFile, null);
try {
handler.renderTo(foUserAgent, MimeConstants.MIME_PDF, baout);
- } catch (FOPException e) {}
+ } catch (FOPException e) { /* NOP */ }
}
}
diff --git a/test/java/org/apache/fop/BasicDriverTestSuite.java b/test/java/org/apache/fop/BasicDriverTestSuite.java
index 8330a5f7f..68619926a 100644
--- a/test/java/org/apache/fop/BasicDriverTestSuite.java
+++ b/test/java/org/apache/fop/BasicDriverTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* Test suite for basic functionality of FOP's Driver API.
*/
@RunWith(Suite.class)
-@SuiteClasses({ BasicDriverTestCase.class })
+@SuiteClasses(BasicDriverTestCase.class)
public class BasicDriverTestSuite {
}
diff --git a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java
index f2f233a5a..2d6fc0d81 100644
--- a/test/java/org/apache/fop/BasicPSTranscoderTestCase.java
+++ b/test/java/org/apache/fop/BasicPSTranscoderTestCase.java
@@ -20,6 +20,7 @@
package org.apache.fop;
import org.apache.batik.transcoder.Transcoder;
+
import org.apache.fop.render.ps.PSTranscoder;
/**
diff --git a/test/java/org/apache/fop/DebugHelper.java b/test/java/org/apache/fop/DebugHelper.java
index 6705d2f56..9ee7de072 100644
--- a/test/java/org/apache/fop/DebugHelper.java
+++ b/test/java/org/apache/fop/DebugHelper.java
@@ -25,7 +25,10 @@ import org.apache.fop.logging.LoggingElementListObserver;
/**
* Handles some standard tasks for debugging.
*/
-public class DebugHelper {
+public final class DebugHelper {
+
+ private DebugHelper() {
+ }
private static boolean elObserversRegistered = false;
diff --git a/test/java/org/apache/fop/DigestFilterTestCase.java b/test/java/org/apache/fop/DigestFilterTestCase.java
index 5606c2b66..679b65aee 100644
--- a/test/java/org/apache/fop/DigestFilterTestCase.java
+++ b/test/java/org/apache/fop/DigestFilterTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop;
-import static org.junit.Assert.assertTrue;
-
import java.io.IOException;
import java.io.StringReader;
import java.security.NoSuchAlgorithmException;
@@ -28,13 +26,16 @@ import java.security.NoSuchAlgorithmException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-import org.apache.fop.util.DigestFilter;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.fop.util.DigestFilter;
+
/**
* Test case for digesting SAX filter.
*
diff --git a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java
index b5132fee9..aa92191de 100644
--- a/test/java/org/apache/fop/KnuthAlgorithmTestCase.java
+++ b/test/java/org/apache/fop/KnuthAlgorithmTestCase.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import org.apache.fop.layoutmgr.BlockKnuthSequence;
diff --git a/test/java/org/apache/fop/URIResolutionTestCase.java b/test/java/org/apache/fop/URIResolutionTestCase.java
index e1015306e..e01271f2b 100644
--- a/test/java/org/apache/fop/URIResolutionTestCase.java
+++ b/test/java/org/apache/fop/URIResolutionTestCase.java
@@ -41,6 +41,9 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.xpath.XPathAPI;
@@ -59,8 +62,6 @@ import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.render.xml.XMLRenderer;
import static org.apache.fop.FOPTestUtils.getBaseDir;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
/**
* Tests URI resolution facilities.
diff --git a/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java
index fc5f1825c..e9134a90b 100644
--- a/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java
+++ b/test/java/org/apache/fop/afp/AFPObjectAreaInfoTestCase.java
@@ -19,11 +19,11 @@
package org.apache.fop.afp;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Test case for {@link AFPObjectAreaInfo}.
*/
diff --git a/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java
index 47c93064c..e9806f944 100644
--- a/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java
+++ b/test/java/org/apache/fop/afp/AFPPaintingStateTestCase.java
@@ -19,11 +19,11 @@
package org.apache.fop.afp;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Test case for {@link AFPPaintingState}.
*/
diff --git a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java
index 21540221f..9d805a7da 100644
--- a/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java
+++ b/test/java/org/apache/fop/afp/AFPResourceManagerTestCase.java
@@ -26,13 +26,13 @@ import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.xmlgraphics.util.MimeConstants;
import org.apache.fop.apps.io.ResourceResolverFactory;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
/**
* Test case for {@link AFPResourceManager}.
*/
diff --git a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java
index a7cf57ebe..178e5c6ad 100644
--- a/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java
+++ b/test/java/org/apache/fop/afp/AFPResourceUtilTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.afp;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -29,11 +27,11 @@ import java.util.Arrays;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.IOUtils;
-import org.apache.fop.afp.util.AFPResourceUtil;
-import org.junit.Test;
-import static org.junit.Assert.assertTrue;
+import org.apache.fop.afp.util.AFPResourceUtil;
/**
* Tests the {@link AFPResourceUtil} class.
@@ -133,7 +131,7 @@ public class AFPResourceUtilTestCase {
* names fails.
* @throws Exception -
*/
- @Test(expected=Exception.class)
+ @Test(expected = Exception.class)
public void testResourceNameMismatch() throws Exception {
testResource(RESOURCE_NAME_MISMATCH, PSEG_B);
}
@@ -156,6 +154,6 @@ public class AFPResourceUtilTestCase {
}
private interface ResourceCopier {
- public void copy(InputStream in, OutputStream out) throws IOException;
+ void copy(InputStream in, OutputStream out) throws IOException;
}
}
diff --git a/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java b/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.java
new file mode 100644
index 000000000..96c0618a7
--- /dev/null
+++ b/test/java/org/apache/fop/afp/fonts/IntegerKeyStoreTestCase.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.afp.fonts;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+public class IntegerKeyStoreTestCase {
+
+ @Test
+ public void getAndPut() {
+ IntegerKeyStore<Integer> sut = new IntegerKeyStore<Integer>();
+ assertNull(sut.get(0));
+ sut.put(0, 0);
+ assertEquals(Integer.valueOf(0), sut.get(0));
+ sut.put(0, 1);
+ assertEquals(Integer.valueOf(1), sut.get(0));
+ sut.put(0, null);
+ assertNull(sut.get(0));
+ try {
+ sut.put(-1, 0);
+ fail("Negative index");
+ } catch (IndexOutOfBoundsException e) {
+ // As expected
+ }
+ }
+
+}
diff --git a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java
index b77ef6e12..17c47743c 100644
--- a/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java
+++ b/test/java/org/apache/fop/afp/goca/GraphicsCharacterStringTestCase.java
@@ -16,16 +16,17 @@
*/
package org.apache.fop.afp.goca;
-import static org.junit.Assert.assertEquals;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.fonts.CharacterSetBuilder;
import org.apache.fop.fonts.Typeface;
-import org.junit.Before;
-import org.junit.Test;
public class GraphicsCharacterStringTestCase {
private GraphicsCharacterString gcsCp500;
diff --git a/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java
index 65c0224c2..a4c80cc65 100644
--- a/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java
+++ b/test/java/org/apache/fop/afp/modca/AbstractAFPObjectTest.java
@@ -19,10 +19,6 @@
package org.apache.fop.afp.modca;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -30,9 +26,14 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.apache.fop.afp.Streamable;
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.afp.Streamable;
+
/**
* Tests the {@link AbstractAFPObject} class.
*/
diff --git a/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java
index 5c863b6e4..0593ae637 100644
--- a/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java
+++ b/test/java/org/apache/fop/afp/modca/AbstractNamedAFPObjectTest.java
@@ -19,12 +19,12 @@
package org.apache.fop.afp.modca;
-import static org.junit.Assert.assertTrue;
-
import java.util.Arrays;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
/**
* Tests the {@linkplain AbstractAFPObject} class.
*/
diff --git a/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java
index faef0a4f6..d0a543087 100644
--- a/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java
+++ b/test/java/org/apache/fop/afp/modca/AbstractStructuredObjectTest.java
@@ -21,7 +21,8 @@ package org.apache.fop.afp.modca;
import java.io.IOException;
-public abstract class AbstractStructuredObjectTest<S extends AbstractStructuredObject> extends AbstractAFPObjectTest<S> {
+public abstract class AbstractStructuredObjectTest<S extends AbstractStructuredObject>
+ extends AbstractAFPObjectTest<S> {
/**
* Test writeStart() - test that the contract is maintained with
diff --git a/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java
index 10c154550..fe25996bb 100644
--- a/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java
+++ b/test/java/org/apache/fop/afp/modca/AbstractTripletStructuredObjectTest.java
@@ -19,10 +19,6 @@
package org.apache.fop.afp.modca;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -33,6 +29,10 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.afp.modca.triplets.AbstractTriplet;
import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet;
import org.apache.fop.afp.modca.triplets.CommentTriplet;
diff --git a/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java
index 0449f2599..7e096f98b 100644
--- a/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java
+++ b/test/java/org/apache/fop/afp/modca/IncludeObjectTestCase.java
@@ -19,16 +19,17 @@
package org.apache.fop.afp.modca;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
-import org.apache.fop.afp.util.BinaryUtils;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.fop.afp.util.BinaryUtils;
+
/**
* Test {@link IncludeObject}
*/
diff --git a/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java
index c80ef086c..176344618 100644
--- a/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java
+++ b/test/java/org/apache/fop/afp/parser/MODCAParserTestCase.java
@@ -19,11 +19,6 @@
package org.apache.fop.afp.parser;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@@ -32,6 +27,11 @@ import java.util.Arrays;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
/**
* MODCAParser and MODCAParser.UnparsedStructuredField Unit tests
*/
diff --git a/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java b/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
index 338c5e6f4..8d6c79d05 100644
--- a/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
+++ b/test/java/org/apache/fop/afp/ptoca/TransparentDataControlSequenceTestCase.java
@@ -24,15 +24,16 @@ import java.io.OutputStream;
import org.junit.Test;
-import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
-import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
-
-import static org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
+
+import static org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE;
+
public class TransparentDataControlSequenceTestCase {
private EncodedChars encodedChars;
diff --git a/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java b/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java
index 9739db2f3..e4c9ceb44 100644
--- a/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java
+++ b/test/java/org/apache/fop/apps/AbstractRendererConfigParserTester.java
@@ -19,6 +19,9 @@
package org.apache.fop.apps;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
@@ -28,9 +31,6 @@ import org.apache.fop.fonts.FontManager;
import org.apache.fop.render.RendererConfig;
import org.apache.fop.render.RendererConfig.RendererConfigParser;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
public abstract class AbstractRendererConfigParserTester<B extends RendererConfBuilder,
C extends RendererConfig> {
diff --git a/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java b/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java
index 58c14f5df..2487c0a63 100644
--- a/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java
+++ b/test/java/org/apache/fop/apps/AbstractRendererConfiguratorTest.java
@@ -24,16 +24,17 @@ import java.io.IOException;
import org.xml.sax.SAXException;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.fop.apps.FopConfBuilder.RendererConfBuilder;
import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.intermediate.IFDocumentHandler;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public abstract class AbstractRendererConfiguratorTest<T extends PrintRendererConfigurator, B extends RendererConfBuilder> {
+public abstract class AbstractRendererConfiguratorTest<T extends PrintRendererConfigurator,
+ B extends RendererConfBuilder> {
protected final String mimeType;
protected FOUserAgent userAgent;
diff --git a/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java b/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java
index e94403e71..83bfd2076 100644
--- a/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java
+++ b/test/java/org/apache/fop/apps/EnvironmentalProfileFactoryTestCase.java
@@ -21,7 +21,6 @@ import java.net.URI;
import org.junit.Test;
-
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
diff --git a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java
index e504c4bc4..86b4e7c04 100644
--- a/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java
+++ b/test/java/org/apache/fop/apps/FopFactoryBuilderTestCase.java
@@ -27,6 +27,12 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.area.AreaTreeHandler;
import org.apache.fop.area.Block;
@@ -45,12 +51,6 @@ import org.apache.fop.layoutmgr.PageSequenceLayoutManager;
import org.apache.fop.layoutmgr.StaticContentLayoutManager;
import org.apache.fop.layoutmgr.inline.ContentLayoutManager;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
/**
* Test case for {@link FopFactoryBuilder}.
*/
diff --git a/test/java/org/apache/fop/apps/FopFactoryTestCase.java b/test/java/org/apache/fop/apps/FopFactoryTestCase.java
index 8ac21c994..439ffa44e 100644
--- a/test/java/org/apache/fop/apps/FopFactoryTestCase.java
+++ b/test/java/org/apache/fop/apps/FopFactoryTestCase.java
@@ -24,16 +24,15 @@ import java.io.IOException;
import org.junit.Test;
import org.xml.sax.SAXException;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.config.BaseConstructiveUserConfigTest;
-import org.apache.fop.render.RendererConfig.RendererConfigParser;
-import org.apache.fop.render.pdf.PDFRendererConfig;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import org.apache.fop.config.BaseConstructiveUserConfigTest;
+import org.apache.fop.render.RendererConfig.RendererConfigParser;
+import org.apache.fop.render.pdf.PDFRendererConfig;
+
public class FopFactoryTestCase extends BaseConstructiveUserConfigTest {
public FopFactoryTestCase() throws SAXException, IOException {
diff --git a/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java b/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java
index 13ca3df6b..3da4e1daf 100644
--- a/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java
+++ b/test/java/org/apache/fop/apps/PDFRendererConfBuilder.java
@@ -22,10 +22,8 @@ package org.apache.fop.apps;
import org.w3c.dom.Element;
import org.apache.fop.apps.FopConfBuilder.RendererConfBuilder;
-import org.apache.fop.pdf.PDFEncryptionParams;
import org.apache.fop.render.RendererConfigOption;
import org.apache.fop.render.pdf.PDFEncryptionOption;
-import org.apache.fop.render.pdf.PDFRendererOption;
import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_LENGTH;
import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS;
diff --git a/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java b/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java
index 2131407c1..e04283718 100644
--- a/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java
+++ b/test/java/org/apache/fop/apps/io/BaseURIResolutionTest.java
@@ -34,6 +34,8 @@ import javax.xml.transform.stream.StreamSource;
import org.xml.sax.SAXException;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
@@ -48,7 +50,6 @@ import org.apache.fop.apps.FopFactoryBuilder;
import org.apache.fop.apps.MimeConstants;
import static org.apache.fop.FOPTestUtils.getBaseDir;
-import static org.junit.Assert.assertTrue;
public abstract class BaseURIResolutionTest {
diff --git a/test/java/org/apache/fop/apps/io/FontURIResolver.java b/test/java/org/apache/fop/apps/io/FontURIResolver.java
index 40d6c7402..781aca368 100644
--- a/test/java/org/apache/fop/apps/io/FontURIResolver.java
+++ b/test/java/org/apache/fop/apps/io/FontURIResolver.java
@@ -33,14 +33,13 @@ import javax.xml.transform.TransformerException;
import org.junit.Test;
import org.xml.sax.SAXException;
-import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.apps.PDFRendererConfBuilder;
-
import static org.junit.Assert.assertTrue;
import org.apache.xmlgraphics.io.Resource;
+import org.apache.fop.apps.FopConfBuilder;
+import org.apache.fop.apps.PDFRendererConfBuilder;
+
public class FontURIResolver extends BaseURIResolutionTest {
public enum Event {
diff --git a/test/java/org/apache/fop/area/ViewportTest.java b/test/java/org/apache/fop/area/ViewportTest.java
index cb2282071..46412c83d 100644
--- a/test/java/org/apache/fop/area/ViewportTest.java
+++ b/test/java/org/apache/fop/area/ViewportTest.java
@@ -19,13 +19,13 @@
package org.apache.fop.area;
+import java.awt.Rectangle;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import java.awt.Rectangle;
-
/**
* Tests implementations of the {@linkplain Viewport} interface.
*/
diff --git a/test/java/org/apache/fop/area/ViewportTestSuite.java b/test/java/org/apache/fop/area/ViewportTestSuite.java
index 065e07bf9..891f1d081 100644
--- a/test/java/org/apache/fop/area/ViewportTestSuite.java
+++ b/test/java/org/apache/fop/area/ViewportTestSuite.java
@@ -19,11 +19,12 @@
package org.apache.fop.area;
-import org.apache.fop.area.inline.InlineViewportTestCase;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
+import org.apache.fop.area.inline.InlineViewportTestCase;
+
/**
* A suite of all the tests relating to the {@linkplain Viewport} interface.
*/
diff --git a/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java
index edcf99d14..cba5759cf 100644
--- a/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java
+++ b/test/java/org/apache/fop/area/inline/InlineViewportTestCase.java
@@ -19,9 +19,10 @@
package org.apache.fop.area.inline;
-import org.apache.fop.area.ViewportTest;
import org.junit.Test;
+import org.apache.fop.area.ViewportTest;
+
/**
* Tests the {@linkplain InlineViewport} class.
*/
diff --git a/test/java/org/apache/fop/check/ChecksFactory.java b/test/java/org/apache/fop/check/ChecksFactory.java
index a493c09f2..d77ce422d 100644
--- a/test/java/org/apache/fop/check/ChecksFactory.java
+++ b/test/java/org/apache/fop/check/ChecksFactory.java
@@ -37,7 +37,7 @@ public abstract class ChecksFactory<C extends Check> {
/**
* A factory to create a particular kind of check.
*/
- protected static interface CheckFactory<C> {
+ protected interface CheckFactory<C> {
/**
* Creates a {@link Check} instance from the given XML element.
diff --git a/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java b/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java
index 9a80fd964..1be3daa84 100644
--- a/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java
+++ b/test/java/org/apache/fop/cli/CommandLineOptionsTestCase.java
@@ -19,15 +19,16 @@
package org.apache.fop.cli;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.io.IOException;
-import org.apache.fop.apps.FOPException;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.fop.apps.FOPException;
+
public class CommandLineOptionsTestCase {
private final CommandLineOptions clo = new CommandLineOptions();
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java
index f20e113c1..8ed1af217 100644
--- a/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiAlgorithmTestCase.java
@@ -19,26 +19,23 @@
package org.apache.fop.complexscripts.bidi;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.apache.fop.complexscripts.bidi.UnicodeBidiAlgorithm;
-
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
/**
* <p>Test case for Unicode Bidi Algorithm.</p>
- * @author Glenn Adams
*/
public class BidiAlgorithmTestCase {
/**
* logging instance
*/
- private static final Log log = LogFactory.getLog(BidiAlgorithmTestCase.class); // CSOK: ConstantNameCheck
+ private static final Log log = LogFactory.getLog(BidiAlgorithmTestCase.class);
/**
* Concatenated array of <test-set,test-sequence> tuples
@@ -122,7 +119,7 @@ public class BidiAlgorithmTestCase {
}
if (includeSequence(testSet, testSequence)) {
includedSequences++;
- if (! excludeSequence(testSet, testSequence)) {
+ if (!excludeSequence(testSet, testSequence)) {
if (testBidiAlgorithm(testSet, testSequence, la, ra, ta, bs)) {
passedSequences++;
}
@@ -151,7 +148,7 @@ public class BidiAlgorithmTestCase {
}
private boolean includeSequence(int testSet, int testSequence) {
- if (! includeTestSet(testSet)) {
+ if (!includeTestSet(testSet)) {
return false;
} else {
for (int i = 0, n = INCLUSIONS.length / 2; i < n; i++) {
@@ -196,7 +193,8 @@ public class BidiAlgorithmTestCase {
return false;
}
- private boolean testBidiAlgorithm(int testSet, int testSequence, int[] la, int[] ra, int[] ta, int bs) throws Exception {
+ private boolean testBidiAlgorithm(int testSet, int testSequence, int[] la, int[] ra, int[] ta, int bs)
+ throws Exception {
boolean passed = true;
int n = la.length;
if (ra.length != n) {
@@ -211,14 +209,14 @@ public class BidiAlgorithmTestCase {
// LTR
if ((bs & 2) != 0) {
int[] levels = UnicodeBidiAlgorithm.resolveLevels(null, ta, 0, new int [ n ], true);
- if (! verifyResults(la, levels, ta, 0, testSet, testSequence)) {
+ if (!verifyResults(la, levels, ta, 0, testSet, testSequence)) {
passed = false;
}
}
// RTL
if ((bs & 4) != 0) {
int[] levels = UnicodeBidiAlgorithm.resolveLevels(null, ta, 1, new int [ n ], true);
- if (! verifyResults(la, levels, ta, 1, testSet, testSequence)) {
+ if (!verifyResults(la, levels, ta, 1, testSet, testSequence)) {
passed = false;
}
}
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java
index 10a84b856..f393e5b70 100644
--- a/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiClassTestCase.java
@@ -19,14 +19,13 @@
package org.apache.fop.complexscripts.bidi;
-import org.apache.fop.complexscripts.bidi.BidiClass;
-import org.apache.fop.util.CharUtilities;
-
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import org.apache.fop.util.CharUtilities;
+
public class BidiClassTestCase {
@Test
@@ -46,8 +45,8 @@ public class BidiClassTestCase {
private void testBidiClass(int[] da) throws Exception {
int bc = da[0];
for (int i = 1, n = da.length; i < n; i += 2) {
- int s = da[i+0];
- int e = da[i+1];
+ int s = da[i + 0];
+ int e = da[i + 1];
for (int c = s; c < e; c++) {
int cbc = BidiClass.getBidiClass(c);
assertEquals("bad bidi class for CH(" + CharUtilities.format(c) + ")", bc, cbc);
diff --git a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java
index 6be0c1fa9..49a5c9455 100644
--- a/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java
+++ b/test/java/org/apache/fop/complexscripts/bidi/BidiTestData.java
@@ -65,7 +65,7 @@ public final class BidiTestData {
data = null;
} finally {
if (is != null) {
- try { is.close(); } catch (Exception e) {}
+ try { is.close(); } catch (Exception e) { /* NOP */ }
}
}
return data;
diff --git a/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java
index af929d3a1..f1512903c 100644
--- a/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/fonts/GDEFTestCase.java
@@ -21,21 +21,14 @@ package org.apache.fop.complexscripts.fonts;
import java.io.File;
-import org.apache.fop.complexscripts.fonts.GlyphSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable;
-import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
-import org.apache.fop.complexscripts.util.GlyphContextTester;
-import org.apache.fop.complexscripts.util.GlyphSequence;
-
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.complexscripts.fonts.ttx.TTXFile;
+
public class GDEFTestCase {
private static String ttxFilesRoot = "test/resources/complexscripts";
diff --git a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
index 270b56797..cf63b4eff 100644
--- a/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/fonts/GPOSTestCase.java
@@ -20,18 +20,6 @@
package org.apache.fop.complexscripts.fonts;
import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.fop.complexscripts.fonts.GlyphSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable;
-import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
-import org.apache.fop.complexscripts.util.GlyphContextTester;
-import org.apache.fop.complexscripts.util.GlyphSequence;
-import org.apache.fop.complexscripts.util.ScriptContextTester;
import org.junit.Test;
@@ -40,6 +28,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable;
+import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
+import org.apache.fop.complexscripts.util.GlyphContextTester;
+import org.apache.fop.complexscripts.util.GlyphSequence;
+import org.apache.fop.complexscripts.util.ScriptContextTester;
+
+// CSOFF: LineLength
+
public class GPOSTestCase implements ScriptContextTester, GlyphContextTester {
private static String ttxFilesRoot = "test/resources/complexscripts";
diff --git a/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java
index b235fa58c..3f23d9ab3 100644
--- a/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/fonts/GSUBTestCase.java
@@ -21,18 +21,6 @@ package org.apache.fop.complexscripts.fonts;
import java.io.File;
import java.nio.IntBuffer;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.fop.complexscripts.fonts.GlyphSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupSpec;
-import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable;
-import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
-import org.apache.fop.complexscripts.util.GlyphContextTester;
-import org.apache.fop.complexscripts.util.GlyphSequence;
-import org.apache.fop.complexscripts.util.ScriptContextTester;
import org.junit.Test;
@@ -41,6 +29,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.apache.fop.complexscripts.fonts.GlyphTable.LookupTable;
+import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
+import org.apache.fop.complexscripts.util.GlyphContextTester;
+import org.apache.fop.complexscripts.util.GlyphSequence;
+import org.apache.fop.complexscripts.util.ScriptContextTester;
+
+// CSOFF: LineLength
+
public class GSUBTestCase implements ScriptContextTester, GlyphContextTester {
private static String ttxFilesRoot = "test/resources/complexscripts";
diff --git a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java
index c106e65c8..178203ff6 100644
--- a/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java
+++ b/test/java/org/apache/fop/complexscripts/fonts/ttx/TTXFile.java
@@ -21,11 +21,9 @@ package org.apache.fop.complexscripts.fonts.ttx;
import java.io.File;
import java.io.IOException;
-
import java.nio.IntBuffer;
-
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -41,21 +39,23 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.complexscripts.fonts.GlyphClassTable;
import org.apache.fop.complexscripts.fonts.GlyphCoverageTable;
-import org.apache.fop.complexscripts.fonts.GlyphDefinitionSubtable;
import org.apache.fop.complexscripts.fonts.GlyphDefinitionTable;
import org.apache.fop.complexscripts.fonts.GlyphMappingTable;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningSubtable;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Anchor;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.MarkAnchor;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.PairValues;
import org.apache.fop.complexscripts.fonts.GlyphPositioningTable.Value;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionSubtable;
import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.Ligature;
import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable.LigatureSet;
@@ -66,11 +66,6 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
import org.apache.fop.complexscripts.util.UTF32;
import org.apache.fop.util.CharUtilities;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
// CSOFF: LineLengthCheck
@@ -87,8 +82,6 @@ import org.xml.sax.helpers.DefaultHandler;
* files directly in the FOP distribution. In such cases, <code>TTX</code> files are used
* to distribute a subset of the complex script advanced table information contained in
* certain font files to facilitate testing.
- *
- * @author Glenn Adams
*/
public class TTXFile {
@@ -100,22 +93,22 @@ public class TTXFile {
private static final String DEFAULT_LANGUAGE_TAG = "dflt";
/** ttxfile cache */
- private static Map<String,TTXFile> cache = new HashMap<String,TTXFile>();
+ private static Map<String, TTXFile> cache = new HashMap<String, TTXFile>();
// transient parsing state
private Locator locator; // current document locator
private Stack<String[]> elements; // stack of ttx elements being parsed
- private Map<String,Integer> glyphIds; // map of glyph names to glyph identifiers
+ private Map<String, Integer> glyphIds; // map of glyph names to glyph identifiers
private List<int[]> cmapEntries; // list of <charCode,glyphCode> pairs
private Vector<int[]> hmtxEntries; // vector of <width,lsb> pairs
- private Map<String,Integer> glyphClasses; // map of glyph names to glyph classes
- private Map<String,Map<String,List<String>>> scripts; // map of script tag to Map<language-tag,List<features-id>>>
- private Map<String,List<String>> languages; // map of language tag to List<feature-id>
- private Map<String,Object[]> features; // map of feature id to Object[2] : { feature-tag, List<lookup-id> }
+ private Map<String, Integer> glyphClasses; // map of glyph names to glyph classes
+ private Map<String, Map<String, List<String>>> scripts; // map of script tag to Map<language-tag,List<features-id>>>
+ private Map<String, List<String>> languages; // map of language tag to List<feature-id>
+ private Map<String, Object[]> features; // map of feature id to Object[2] : { feature-tag, List<lookup-id> }
private List<String> languageFeatures; // list of language system feature ids, where first is (possibly null) required feature id
private List<String> featureLookups; // list of lookup ids for feature being constructed
private List<Integer> coverageEntries; // list of entries for coverage table being constructed
- private Map<String,GlyphCoverageTable> coverages; // map of coverage table keys to coverage tables
+ private Map<String, GlyphCoverageTable> coverages; // map of coverage table keys to coverage tables
private List subtableEntries; // list of lookup subtable entries
private List<GlyphSubtable> subtables; // list of constructed subtables
private List<Integer> alternates; // list of alternates in alternate set being constructed
@@ -162,8 +155,8 @@ public class TTXFile {
// resultant state
private int upem; // units per em
- private Map<Integer,Integer> cmap; // constructed character map
- private Map<Integer,Integer> gmap; // constructed glyph map
+ private Map<Integer, Integer> cmap; // constructed character map
+ private Map<Integer, Integer> gmap; // constructed glyph map
private int[][] hmtx; // constructed horizontal metrics - array of design { width, lsb } pairs, indexed by glyph code
private int[] widths; // pdf normalized widths (millipoints)
private GlyphDefinitionTable gdef; // constructed glyph definition table
@@ -172,17 +165,17 @@ public class TTXFile {
public TTXFile() {
elements = new Stack<String[]>();
- glyphIds = new HashMap<String,Integer>();
+ glyphIds = new HashMap<String, Integer>();
cmapEntries = new ArrayList<int[]>();
hmtxEntries = new Vector<int[]>();
- glyphClasses = new HashMap<String,Integer>();
- scripts = new HashMap<String,Map<String,List<String>>>();
- languages = new HashMap<String,List<String>>();
- features = new HashMap<String,Object[]>();
+ glyphClasses = new HashMap<String, Integer>();
+ scripts = new HashMap<String, Map<String, List<String>>>();
+ languages = new HashMap<String, List<String>>();
+ features = new HashMap<String, Object[]>();
languageFeatures = new ArrayList<String>();
featureLookups = new ArrayList<String>();
coverageEntries = new ArrayList<Integer>();
- coverages = new HashMap<String,GlyphCoverageTable>();
+ coverages = new HashMap<String, GlyphCoverageTable>();
subtableEntries = new ArrayList();
subtables = new ArrayList<GlyphSubtable>();
alternates = new ArrayList<Integer>();
@@ -342,7 +335,7 @@ public class TTXFile {
long rest1 = tw % upem;
long storrest = 1000 * rest1;
long ledd2 = (storrest != 0) ? (rest1 / storrest) : 0;
- pw = - ((-1000 * tw) / upem - (int) ledd2);
+ pw = -((-1000 * tw) / upem - (int) ledd2);
} else {
pw = (tw / upem) * 1000 + ((tw % upem) * 1000) / upem;
}
@@ -370,7 +363,7 @@ public class TTXFile {
public static synchronized void clearCache() {
cache.clear();
}
- private class Handler extends DefaultHandler {
+ private final class Handler extends DefaultHandler {
private Handler() {
}
@Override
@@ -493,7 +486,7 @@ public class TTXFile {
}
} else if (en[1].equals("BaseArray")) {
String[] pn = new String[] { null, "MarkBasePos" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("BaseCoverage")) {
@@ -587,7 +580,7 @@ public class TTXFile {
if (glyphClass == null) {
missingRequiredAttribute(en, "class");
}
- if (! glyphIds.containsKey(glyph)) {
+ if (!glyphIds.containsKey(glyph)) {
unsupportedGlyph(en, glyph);
} else if (isParent(pn1)) {
if (glyphClasses.containsKey(glyph)) {
@@ -675,7 +668,7 @@ public class TTXFile {
}
} else if (en[1].equals("DefaultLangSys")) {
String[] pn = new String[] { null, "Script" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
} else {
assertLanguageFeaturesClear();
@@ -718,7 +711,7 @@ public class TTXFile {
}
} else if (en[1].equals("Feature")) {
String[] pn = new String[] { null, "FeatureRecord" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
} else {
assertFeatureLookupsClear();
@@ -752,7 +745,7 @@ public class TTXFile {
String[] pn1 = new String[] { null, "GSUB" };
String[] pn2 = new String[] { null, "GPOS" };
String[][] pnx = new String[][] { pn1, pn2 };
- if (! isParent(pnx)) {
+ if (!isParent(pnx)) {
notPermittedInElementContext(en, getParent(), pnx);
}
} else if (en[1].equals("FeatureRecord")) {
@@ -885,7 +878,7 @@ public class TTXFile {
}
} else if (en[1].equals("GlyphOrder")) {
String[] pn = new String[] { null, "ttFont" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("InputCoverage")) {
@@ -923,7 +916,7 @@ public class TTXFile {
}
} else if (en[1].equals("LangSys")) {
String[] pn = new String[] { null, "LangSysRecord" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
} else {
assertLanguageFeaturesClear();
@@ -953,7 +946,7 @@ public class TTXFile {
}
} else if (en[1].equals("LigCaretList")) {
String[] pn = new String[] { null, "GDEF" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("Ligature")) {
@@ -991,7 +984,7 @@ public class TTXFile {
}
} else if (en[1].equals("LigatureArray")) {
String[] pn = new String[] { null, "MarkLigPos" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("LigatureAttach")) {
@@ -1139,7 +1132,7 @@ public class TTXFile {
String[] pn1 = new String[] { null, "GSUB" };
String[] pn2 = new String[] { null, "GPOS" };
String[][] pnx = new String[][] { pn1, pn2 };
- if (! isParent(pnx)) {
+ if (!isParent(pnx)) {
notPermittedInElementContext(en, getParent(), pnx);
}
} else if (en[1].equals("LookupListIndex")) {
@@ -1179,7 +1172,7 @@ public class TTXFile {
}
} else if (en[1].equals("Mark1Array")) {
String[] pn = new String[] { null, "MarkMarkPos" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("Mark1Coverage")) {
@@ -1220,7 +1213,7 @@ public class TTXFile {
}
} else if (en[1].equals("Mark2Array")) {
String[] pn = new String[] { null, "MarkMarkPos" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("Mark2Coverage")) {
@@ -1273,7 +1266,7 @@ public class TTXFile {
String[] pn1 = new String[] { null, "MarkBasePos" };
String[] pn2 = new String[] { null, "MarkLigPos" };
String[][] pnx = new String[][] { pn1, pn2 };
- if (! isParent(pnx)) {
+ if (!isParent(pnx)) {
notPermittedInElementContext(en, getParent(), pnx);
}
} else if (en[1].equals("MarkAttachClassDef")) {
@@ -1549,14 +1542,14 @@ public class TTXFile {
}
} else if (en[1].equals("Script")) {
String[] pn = new String[] { null, "ScriptRecord" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("ScriptList")) {
String[] pn1 = new String[] { null, "GSUB" };
String[] pn2 = new String[] { null, "GPOS" };
String[][] pnx = new String[][] { pn1, pn2 };
- if (! isParent(pnx)) {
+ if (!isParent(pnx)) {
notPermittedInElementContext(en, getParent(), pnx);
}
} else if (en[1].equals("ScriptRecord")) {
@@ -1890,7 +1883,7 @@ public class TTXFile {
}
} else if (en[1].equals("cmap")) {
String[] pn = new String[] { null, "ttFont" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("cmap_format_0")) {
@@ -1997,12 +1990,12 @@ public class TTXFile {
}
} else if (en[1].equals("head")) {
String[] pn = new String[] { null, "ttFont" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
}
} else if (en[1].equals("hmtx")) {
String[] pn = new String[] { null, "ttFont" };
- if (! isParent(pn)) {
+ if (!isParent(pn)) {
notPermittedInElementContext(en, getParent(), pn);
} else if (glyphIdMax > 0) {
hmtxEntries.setSize(glyphIdMax + 1);
@@ -2216,7 +2209,7 @@ public class TTXFile {
throw new SAXException("element stack is empty, elements are not balanced");
}
String[] en = makeExpandedName(uri, localName, qName);
- if (! sameExpandedName(enParent, en)) {
+ if (!sameExpandedName(enParent, en)) {
throw new SAXException("element stack is unbalanced, expanded name mismatch");
}
if (en[0] != null) {
@@ -2244,7 +2237,7 @@ public class TTXFile {
} else if (en[1].equals("AlternateSet")) {
subtableEntries.add(extractAlternates());
} else if (en[1].equals("AlternateSubst")) {
- if (! sortEntries(coverageEntries, subtableEntries)) {
+ if (!sortEntries(coverageEntries, subtableEntries)) {
mismatchedEntries(en, coverageEntries.size(), subtableEntries.size());
}
addGSUBSubtable(GlyphSubstitutionTable.GSUB_LOOKUP_TYPE_ALTERNATE, extractCoverage());
@@ -2262,9 +2255,9 @@ public class TTXFile {
} else if (en[1].equals("ChainContextPos") || en[1].equals("ChainContextSubst")) {
GlyphCoverageTable coverage = null;
if (stFormat == 3) {
- GlyphCoverageTable igca[] = getCoveragesWithPrefix("in");
- GlyphCoverageTable bgca[] = getCoveragesWithPrefix("bk");
- GlyphCoverageTable lgca[] = getCoveragesWithPrefix("la");
+ GlyphCoverageTable[] igca = getCoveragesWithPrefix("in");
+ GlyphCoverageTable[] bgca = getCoveragesWithPrefix("bk");
+ GlyphCoverageTable[] lgca = getCoveragesWithPrefix("la");
if ((igca.length == 0) || hasMissingCoverage(igca)) {
missingCoverage(en, "input", igca.length);
} else if (hasMissingCoverage(bgca)) {
@@ -2363,7 +2356,7 @@ public class TTXFile {
} else if (en[1].equals("LigatureSet")) {
subtableEntries.add(extractLigatures());
} else if (en[1].equals("LigatureSubst")) {
- if (! sortEntries(coverageEntries, subtableEntries)) {
+ if (!sortEntries(coverageEntries, subtableEntries)) {
mismatchedEntries(en, coverageEntries.size(), subtableEntries.size());
}
GlyphCoverageTable coverage = extractCoverage();
@@ -2475,7 +2468,8 @@ public class TTXFile {
}
GlyphCoverageTable coverage = coverages.get("main");
addGPOSSubtable(GlyphPositioningTable.GPOS_LOOKUP_TYPE_PAIR, coverage);
- vf1 = vf2 = -1; psIndex = -1;
+ vf1 = vf2 = -1;
+ psIndex = -1;
} else if (en[1].equals("PairSet")) {
if (psIndex != pairSets.size()) {
invalidIndex(en, psIndex, pairSets.size());
@@ -2528,7 +2522,7 @@ public class TTXFile {
addGPOSSubtable(GlyphPositioningTable.GPOS_LOOKUP_TYPE_SINGLE, coverage);
vf1 = -1;
} else if (en[1].equals("SingleSubst")) {
- if (! sortEntries(coverageEntries, subtableEntries)) {
+ if (!sortEntries(coverageEntries, subtableEntries)) {
mismatchedEntries(en, coverageEntries.size(), subtableEntries.size());
}
GlyphCoverageTable coverage = extractCoverage();
@@ -2556,7 +2550,7 @@ public class TTXFile {
public void characters(char[] chars, int start, int length) {
}
private String[] getParent() {
- if (! elements.empty()) {
+ if (!elements.empty()) {
return elements.peek();
} else {
return new String[] { null, null };
@@ -2572,13 +2566,11 @@ public class TTXFile {
return false;
} else if (enx instanceof String[]) {
String[] en = (String[]) enx;
- if (! elements.empty()) {
+ if (!elements.empty()) {
String[] pn = elements.peek();
return (pn != null) && sameExpandedName(en, pn);
- } else if ((en[0] == null) && (en[1] == null)) {
- return true;
} else {
- return false;
+ return ((en[0] == null) && (en[1] == null));
}
} else {
return false;
@@ -2595,14 +2587,12 @@ public class TTXFile {
return true;
} else if (ln.equals("MarkAnchor")) {
return true;
- } else if (ln.equals("Mark2Anchor")) {
- return true;
} else {
- return false;
+ return ln.equals("Mark2Anchor");
}
}
- private Map<Integer,Integer> getCMAP() {
- Map<Integer,Integer> cmap = new TreeMap();
+ private Map<Integer, Integer> getCMAP() {
+ Map<Integer, Integer> cmap = new TreeMap();
for (int[] cme : cmapEntries) {
Integer c = Integer.valueOf(cme[0]);
Integer g = Integer.valueOf(cme[1]);
@@ -2610,8 +2600,8 @@ public class TTXFile {
}
return cmap;
}
- private Map<Integer,Integer> getGMAP() {
- Map<Integer,Integer> gmap = new TreeMap();
+ private Map<Integer, Integer> getGMAP() {
+ Map<Integer, Integer> gmap = new TreeMap();
for (int[] cme : cmapEntries) {
Integer c = Integer.valueOf(cme[0]);
Integer g = Integer.valueOf(cme[1]);
@@ -2631,7 +2621,7 @@ public class TTXFile {
}
return hmtx;
}
- private GlyphClassTable extractClassDefMapping(Map<String,Integer> glyphClasses, int format, boolean clearSourceMap) {
+ private GlyphClassTable extractClassDefMapping(Map<String, Integer> glyphClasses, int format, boolean clearSourceMap) {
GlyphClassTable ct;
if (format == 1) {
ct = extractClassDefMapping1(extractClassMappings(glyphClasses, clearSourceMap));
@@ -2685,11 +2675,11 @@ public class TTXFile {
}
return GlyphClassTable.createClassTable(entries);
}
- private int[][] extractClassMappings(Map<String,Integer> glyphClasses, boolean clearSourceMap) {
+ private int[][] extractClassMappings(Map<String, Integer> glyphClasses, boolean clearSourceMap) {
int nc = glyphClasses.size();
int i = 0;
int[][] cma = new int [ nc ] [ 2 ];
- for (Map.Entry<String,Integer> e : glyphClasses.entrySet()) {
+ for (Map.Entry<String, Integer> e : glyphClasses.entrySet()) {
Integer gid = glyphIds.get(e.getKey());
assert gid != null;
int[] m = cma [ i ];
@@ -2856,8 +2846,8 @@ public class TTXFile {
private void clearLanguageFeatures() {
languageFeatures.clear();
}
- private Map<String,List<String>> extractLanguages() {
- Map<String,List<String>> lm = new HashMap(languages);
+ private Map<String, List<String>> extractLanguages() {
+ Map<String, List<String>> lm = new HashMap(languages);
clearLanguages();
return lm;
}
@@ -2923,10 +2913,10 @@ public class TTXFile {
ltFlags = 0;
clearSubtablesInLookup();
}
- private Map<GlyphTable.LookupSpec,List<String>> extractLookups() {
- Map<GlyphTable.LookupSpec,List<String>> lookups = new LinkedHashMap<GlyphTable.LookupSpec,List<String>>();
+ private Map<GlyphTable.LookupSpec, List<String>> extractLookups() {
+ Map<GlyphTable.LookupSpec, List<String>> lookups = new LinkedHashMap<GlyphTable.LookupSpec, List<String>>();
for (String st : scripts.keySet()) {
- Map<String,List<String>> lm = scripts.get(st);
+ Map<String, List<String>> lm = scripts.get(st);
if (lm != null) {
for (String lt : lm.keySet()) {
List<String> fids = lm.get(lt);
@@ -3062,7 +3052,7 @@ public class TTXFile {
missingParameter(en, "xAdvance");
}
String yAdvance = attrs.getValue("YAdvance");
- int ya = 0;;
+ int ya = 0;
if (yAdvance != null) {
ya = Integer.parseInt(yAdvance);
} else if ((format & GlyphPositioningTable.Value.Y_ADVANCE) != 0) {
@@ -3207,7 +3197,7 @@ public class TTXFile {
if (cm != null) {
for (Anchor[] aa : cm) {
if (aa != null) {
- int nc = aa.length;;
+ int nc = aa.length;
if (nc > ncMax) {
ncMax = nc;
}
@@ -3223,7 +3213,7 @@ public class TTXFile {
if (lam != null) {
for (Anchor[][] cm : lam) {
if (cm != null) {
- int nx = cm.length;;
+ int nx = cm.length;
if (nx > nxMax) {
nxMax = nx;
}
@@ -3424,7 +3414,7 @@ public class TTXFile {
return false;
}
if ((u1 != null) && (u2 != null)) {
- if (! u1.equals(u2)) {
+ if (!u1.equals(u2)) {
return false;
}
}
@@ -3434,7 +3424,7 @@ public class TTXFile {
return false;
}
if ((l1 != null) && (l2 != null)) {
- if (! l1.equals(l2)) {
+ if (!l1.equals(l2)) {
return false;
}
}
diff --git a/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
index cf5d846b4..c48be5220 100644
--- a/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
+++ b/test/java/org/apache/fop/complexscripts/scripts/ScriptsTestSuite.java
@@ -29,8 +29,6 @@ import org.apache.fop.complexscripts.scripts.arabic.ArabicTestCase;
* Test suite for script specific functionality related to complex scripts.
*/
@RunWith(Suite.class)
-@SuiteClasses({
- ArabicTestCase.class
-})
+@SuiteClasses(ArabicTestCase.class)
public class ScriptsTestSuite {
}
diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java
index d34e88a03..8542faae9 100644
--- a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestCase.java
@@ -21,30 +21,26 @@ package org.apache.fop.complexscripts.scripts.arabic;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FilenameFilter;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
+import java.io.FilenameFilter;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.LineNumberReader;
import java.io.ObjectInputStream;
import java.nio.IntBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
import java.util.List;
-import org.apache.fop.complexscripts.fonts.GlyphPositioningTable;
-import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
-import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
-import org.apache.fop.complexscripts.util.GlyphSequence;
-
-import org.junit.BeforeClass;
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.complexscripts.fonts.GlyphPositioningTable;
+import org.apache.fop.complexscripts.fonts.GlyphSubstitutionTable;
+import org.apache.fop.complexscripts.fonts.ttx.TTXFile;
+import org.apache.fop.complexscripts.util.GlyphSequence;
+
+// CSOFF: LineLength
+
/**
* Tests for functionality related to the arabic script.
*/
@@ -52,9 +48,9 @@ public class ArabicTestCase implements ArabicTestConstants {
@Test
public void testArabicWordForms() {
- for (String sfn : srcFiles) {
+ for (String sfn : SRC_FILES) {
try {
- processWordForms(new File(datFilesDir));
+ processWordForms(new File(DAT_FILES_DIR));
} catch (Exception e) {
fail(e.getMessage());
}
@@ -72,7 +68,7 @@ public class ArabicTestCase implements ArabicTestConstants {
private String[] listWordFormFiles(File dfd) {
return dfd.list(new FilenameFilter() {
public boolean accept(File f, String name) {
- return hasPrefixFrom(name, srcFiles) && hasExtension(name, WF_FILE_DAT_EXT);
+ return hasPrefixFrom(name, SRC_FILES) && hasExtension(name, WF_FILE_DAT_EXT);
}
private boolean hasPrefixFrom(String name, String[] prefixes) {
for (String p : prefixes) {
@@ -108,7 +104,7 @@ public class ArabicTestCase implements ArabicTestConstants {
throw new RuntimeException(e.getMessage(), e);
} finally {
if (fis != null) {
- try { fis.close(); } catch (Exception e) {}
+ try { fis.close(); } catch (Exception e) { /* NOP */ }
}
}
}
@@ -129,7 +125,7 @@ public class ArabicTestCase implements ArabicTestConstants {
script = (String) d[0];
language = (String) d[1];
tfn = (String) d[3];
- tf = TTXFile.getFromCache(ttxFontsDir + File.separator + tfn);
+ tf = TTXFile.getFromCache(TTX_FONTS_DIR + File.separator + tfn);
assertTrue(tf != null);
gsub = tf.getGSUB();
assertTrue(gsub != null);
diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java
index 0669ff137..cc9167553 100644
--- a/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java
+++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/ArabicTestConstants.java
@@ -24,22 +24,22 @@ package org.apache.fop.complexscripts.scripts.arabic;
*/
public interface ArabicTestConstants {
- final String WF_FILE_SCRIPT = "arab";
- final String WF_FILE_LANGUAGE = "dflt";
+ String WF_FILE_SCRIPT = "arab";
+ String WF_FILE_LANGUAGE = "dflt";
- String srcFilesDir = "test/resources/complexscripts/arab/data";
- String datFilesDir = "test/resources/complexscripts/arab/data";
+ String SRC_FILES_DIR = "test/resources/complexscripts/arab/data";
+ String DAT_FILES_DIR = "test/resources/complexscripts/arab/data";
- String[] srcFiles = {
+ String[] SRC_FILES = {
"arab-001", // unpointed word forms
};
- final String WF_FILE_SRC_EXT = "txt";
- final String WF_FILE_DAT_EXT = "ser";
+ String WF_FILE_SRC_EXT = "txt";
+ String WF_FILE_DAT_EXT = "ser";
- String ttxFontsDir = "test/resources/complexscripts/arab/ttx";
+ String TTX_FONTS_DIR = "test/resources/complexscripts/arab/ttx";
- String[] ttxFonts = {
+ String[] TTX_FONTS = {
"arab-001.ttx", // simplified arabic
"arab-002.ttx", // traditional arabic
"arab-003.ttx", // lateef
diff --git a/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java
index a4f876dd8..9ca16a164 100644
--- a/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java
+++ b/test/java/org/apache/fop/complexscripts/scripts/arabic/GenerateArabicTestData.java
@@ -40,7 +40,10 @@ import org.apache.fop.complexscripts.util.GlyphSequence;
/**
* Tests for functionality related to the arabic script.
*/
-public class GenerateArabicTestData implements ArabicTestConstants {
+public final class GenerateArabicTestData implements ArabicTestConstants {
+
+ private GenerateArabicTestData() {
+ }
public static void main(String[] args) {
boolean compile = false;
@@ -69,9 +72,9 @@ public class GenerateArabicTestData implements ArabicTestConstants {
}
private static void compile() {
- for (String sfn : srcFiles) {
+ for (String sfn : SRC_FILES) {
try {
- String spn = srcFilesDir + File.separator + sfn + "." + WF_FILE_SRC_EXT;
+ String spn = SRC_FILES_DIR + File.separator + sfn + "." + WF_FILE_SRC_EXT;
compile(WF_FILE_SCRIPT, WF_FILE_LANGUAGE, spn);
} catch (Exception e) {
System.err.println(e.getMessage());
@@ -81,8 +84,8 @@ public class GenerateArabicTestData implements ArabicTestConstants {
private static void compile(String script, String language, String spn) {
int fno = 0;
- for (String tfn : ttxFonts) {
- TTXFile tf = TTXFile.getFromCache(ttxFontsDir + File.separator + tfn);
+ for (String tfn : TTX_FONTS) {
+ TTXFile tf = TTXFile.getFromCache(TTX_FONTS_DIR + File.separator + tfn);
assert tf != null;
List data = compile(script, language, spn, tfn, tf);
output(makeDataPathName(spn, fno++), data);
@@ -106,7 +109,7 @@ public class GenerateArabicTestData implements ArabicTestConstants {
GlyphSequence igs = tf.mapCharsToGlyphs(wf);
GlyphSequence ogs = gsub.substitute(igs, script, language);
int[][] paa = new int [ ogs.getGlyphCount() ] [ 4 ];
- if (! gpos.position(ogs, script, language, 1000, widths, paa)) {
+ if (!gpos.position(ogs, script, language, 1000, widths, paa)) {
paa = null;
}
data.add(new Object[] { wf, getGlyphs(igs), getGlyphs(ogs), paa });
@@ -121,7 +124,7 @@ public class GenerateArabicTestData implements ArabicTestConstants {
throw new RuntimeException(e.getMessage(), e);
} finally {
if (fis != null) {
- try { fis.close(); } catch (Exception e) {}
+ try { fis.close(); } catch (Exception e) { /* NOP */ }
}
}
} else {
@@ -142,7 +145,7 @@ public class GenerateArabicTestData implements ArabicTestConstants {
private static String makeDataPathName(String spn, int fno) {
File f = new File(spn);
- return datFilesDir + File.separator + stripExtension(f.getName()) + "-f" + fno + "." + WF_FILE_DAT_EXT;
+ return DAT_FILES_DIR + File.separator + stripExtension(f.getName()) + "-f" + fno + "." + WF_FILE_DAT_EXT;
}
private static String stripExtension(String s) {
@@ -171,7 +174,7 @@ public class GenerateArabicTestData implements ArabicTestConstants {
throw new RuntimeException(e.getMessage(), e);
} finally {
if (fos != null) {
- try { fos.close(); } catch (Exception e) {}
+ try { fos.close(); } catch (Exception e) { /* NOP */ }
}
}
}
diff --git a/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java
index ea885b6c5..4e1db5fb3 100644
--- a/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java
+++ b/test/java/org/apache/fop/complexscripts/util/NumberConverterTestCase.java
@@ -30,12 +30,10 @@ import static org.junit.Assert.assertEquals;
/**
* Test number converter functionality.
- *
- * @author Glenn Adams
*/
public class NumberConverterTestCase {
- static private String[][] formatDecimal =
+ private static String[][] formatDecimal =
{
{ "1" },
{ "0", "0" },
@@ -45,7 +43,7 @@ public class NumberConverterTestCase {
{ "1000000000", "1000000000" },
};
- static private String[][] formatDecimalPadded =
+ private static String[][] formatDecimalPadded =
{
{ "001" },
{ "0", "000" },
@@ -58,7 +56,7 @@ public class NumberConverterTestCase {
{ "1000", "1000" },
};
- static private String[][] formatDecimalGrouped =
+ private static String[][] formatDecimalGrouped =
{
{ "1", ",", "1" },
{ "0", "0" },
@@ -68,7 +66,7 @@ public class NumberConverterTestCase {
{ "1000000000", "1,0,0,0,0,0,0,0,0,0" },
};
- static private String[][] formatDecimalGroupedPadded =
+ private static String[][] formatDecimalGroupedPadded =
{
{ "001", ",", "2" },
{ "0", "0,00" },
@@ -81,7 +79,7 @@ public class NumberConverterTestCase {
{ "1000", "10,00" },
};
- static private String[][] formatDecimalArabic =
+ private static String[][] formatDecimalArabic =
{
{ "\u0661" },
{ "0", "\u0660" },
@@ -100,7 +98,7 @@ public class NumberConverterTestCase {
{ "1000000000", "\u0661\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660\u0660" },
};
- static private String[][] formatDecimalArabicPadded =
+ private static String[][] formatDecimalArabicPadded =
{
{ "\u0660\u0660\u0661" },
{ "0", "\u0660\u0660\u0660" },
@@ -113,7 +111,7 @@ public class NumberConverterTestCase {
{ "1000", "\u0661\u0660\u0660\u0660" },
};
- static private String[][] formatDecimalArabicGrouped =
+ private static String[][] formatDecimalArabicGrouped =
{
{ "\u0661", "\u066c", "1" },
{ "0", "\u0660" },
@@ -123,7 +121,7 @@ public class NumberConverterTestCase {
{ "1000000000", "\u0661\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660\u066c\u0660" },
};
- static private String[][] formatDecimalArabicGroupedPadded =
+ private static String[][] formatDecimalArabicGroupedPadded =
{
{ "\u0660\u0660\u0661", "\u066c", "2" },
{ "0", "\u0660\u066c\u0660\u0660" },
@@ -136,7 +134,7 @@ public class NumberConverterTestCase {
{ "1000", "\u0661\u0660\u066c\u0660\u0660" },
};
- static private String[][] formatDecimalThai =
+ private static String[][] formatDecimalThai =
{
{ "\u0E51" },
{ "0", "\u0E50" },
@@ -155,7 +153,7 @@ public class NumberConverterTestCase {
{ "1000000000", "\u0E51\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50\u0E50" },
};
- static private String[][] formatDecimalThaiPadded =
+ private static String[][] formatDecimalThaiPadded =
{
{ "\u0E50\u0E50\u0E51" },
{ "0", "\u0E50\u0E50\u0E50" },
@@ -168,7 +166,7 @@ public class NumberConverterTestCase {
{ "1000", "\u0E51\u0E50\u0E50\u0E50" },
};
- static private String[][] formatRomanLower =
+ private static String[][] formatRomanLower =
{
{ "i" },
{ "0", "0" },
@@ -206,7 +204,7 @@ public class NumberConverterTestCase {
{ "5000", "5000" },
};
- static private String[][] formatRomanUpper =
+ private static String[][] formatRomanUpper =
{
{ "I" },
@@ -245,7 +243,7 @@ public class NumberConverterTestCase {
{ "5000", "5000" },
};
- static private String[][] formatRomanLargeLower =
+ private static String[][] formatRomanLargeLower =
{
{ "i", null, null, null, "large" },
{ "0", "0" },
@@ -293,7 +291,7 @@ public class NumberConverterTestCase {
{ "200000", "200000" },
};
- static private String[][] formatRomanLargeUpper =
+ private static String[][] formatRomanLargeUpper =
{
{ "I", null, null, null, "large" },
{ "0", "0" },
@@ -341,7 +339,7 @@ public class NumberConverterTestCase {
{ "200000", "200000" },
};
- static private String[][] formatRomanNumberFormsLower =
+ private static String[][] formatRomanNumberFormsLower =
{
{ "i", null, null, null, "unicode-number-forms" },
{ "0", "0" },
@@ -399,7 +397,7 @@ public class NumberConverterTestCase {
{ "200000", "200000" },
};
- static private String[][] formatRomanNumberFormsUpper =
+ private static String[][] formatRomanNumberFormsUpper =
{
{ "I", null, null, null, "unicode-number-forms" },
{ "0", "0" },
@@ -457,7 +455,7 @@ public class NumberConverterTestCase {
{ "200000", "200000" },
};
- static private String[][] formatAlphabeticLatinLower =
+ private static String[][] formatAlphabeticLatinLower =
{
{ "a" },
{ "0", "0" },
@@ -478,7 +476,7 @@ public class NumberConverterTestCase {
{ "1000000", "bdwgn" },
};
- static private String[][] formatAlphabeticLatinUpper =
+ private static String[][] formatAlphabeticLatinUpper =
{
{ "A" },
{ "0", "0" },
@@ -499,7 +497,7 @@ public class NumberConverterTestCase {
{ "1000000", "BDWGN" },
};
- static private String[][] formatAlphabeticArabicHijai =
+ private static String[][] formatAlphabeticArabicHijai =
{
{ "\u0627", null, null, "alphabetic" },
{ "0", "0" },
@@ -540,7 +538,7 @@ public class NumberConverterTestCase {
{ "1000000", "\u0623\u0638\u0636\u0635\u062F" },
};
- static private String[][] formatAlphabeticArabicAbjadi =
+ private static String[][] formatAlphabeticArabicAbjadi =
{
{ "\u0627", null, null, "traditional" },
{ "0", "0" },
@@ -581,7 +579,7 @@ public class NumberConverterTestCase {
{ "1000000", "\u0623\u0641\u0633\u0646\u062D" },
};
- static private String[][] formatNumeralArabicAbjadi =
+ private static String[][] formatNumeralArabicAbjadi =
{
{ "\u0623", null, null, "traditional" },
{ "0", "0" },
@@ -629,7 +627,7 @@ public class NumberConverterTestCase {
{ "2000", "2000" },
};
- static private String[][] formatAlphabeticHebrew =
+ private static String[][] formatAlphabeticHebrew =
{
{ "\u05D0", null, null, "alphabetic" },
{ "0", "0" },
@@ -669,7 +667,7 @@ public class NumberConverterTestCase {
{ "1000000", "\u05D0\u05DA\u05E9\u05E8\u05D0" },
};
- static private String[][] formatNumeralHebrewGematria =
+ private static String[][] formatNumeralHebrewGematria =
{
{ "\u05D0", null, null, "traditional" },
{ "0", "0" },
@@ -717,7 +715,7 @@ public class NumberConverterTestCase {
{ "2000", "2000" },
};
- static private String[][] formatAlphabeticThai =
+ private static String[][] formatAlphabeticThai =
{
{ "\u0E01", null, null, "alphabetic" },
{ "0", "0" },
@@ -738,7 +736,7 @@ public class NumberConverterTestCase {
{ "1000000", "\u0E0B\u0E20\u0E17\u0E0C" },
};
- static private String[][] formatWordEnglishLower =
+ private static String[][] formatWordEnglishLower =
{
{ "w", null, null, null, null, "eng" },
{ "0", "zero" },
@@ -762,7 +760,7 @@ public class NumberConverterTestCase {
{ "1000000000", "one billion" }
};
- static private String[][] formatWordEnglishUpper =
+ private static String[][] formatWordEnglishUpper =
{
{ "W", null, null, null, null, "eng" },
{ "0", "ZERO" },
@@ -786,7 +784,7 @@ public class NumberConverterTestCase {
{ "1000000000", "ONE BILLION" }
};
- static private String[][] formatWordEnglishTitle =
+ private static String[][] formatWordEnglishTitle =
{
{ "Ww", null, null, null, null, "eng" },
{ "0", "Zero" },
@@ -810,7 +808,7 @@ public class NumberConverterTestCase {
{ "1000000000", "One Billion" }
};
- static private String[][] formatWordSpanishLower =
+ private static String[][] formatWordSpanishLower =
{
{ "w", null, null, null, null, "spa" },
{ "0", "cero" },
@@ -890,7 +888,7 @@ public class NumberConverterTestCase {
{ "1000000000", "mil millones" }
};
- static private String[][] formatWordSpanishUpper =
+ private static String[][] formatWordSpanishUpper =
{
{ "W", null, null, null, null, "spa" },
{ "0", "CERO" },
@@ -970,7 +968,7 @@ public class NumberConverterTestCase {
{ "1000000000", "MIL MILLONES" }
};
- static private String[][] formatWordSpanishTitle =
+ private static String[][] formatWordSpanishTitle =
{
{ "Ww", null, null, null, null, "spa" },
{ "0", "Cero" },
@@ -1050,7 +1048,7 @@ public class NumberConverterTestCase {
{ "1000000000", "Mil Millones" }
};
- static private String[][] formatWordFrenchLower =
+ private static String[][] formatWordFrenchLower =
{
{ "w", null, null, null, null, "fra" },
{ "0", "z\u00e9ro" },
@@ -1141,7 +1139,7 @@ public class NumberConverterTestCase {
{ "1000000000", "un milliard" }
};
- static private String[][] formatWordFrenchUpper =
+ private static String[][] formatWordFrenchUpper =
{
{ "W", null, null, null, null, "fra" },
{ "0", "Z\u00c9RO" },
@@ -1232,7 +1230,7 @@ public class NumberConverterTestCase {
{ "1000000000", "UN MILLIARD" }
};
- static private String[][] formatWordFrenchTitle =
+ private static String[][] formatWordFrenchTitle =
{
{ "Ww", null, null, null, null, "fra" },
{ "0", "Z\u00e9ro" },
diff --git a/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java
index 70bd568af..4407254a8 100644
--- a/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java
+++ b/test/java/org/apache/fop/complexscripts/util/UtilTestSuite.java
@@ -27,8 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* Test suite for bidirectional functionality.
*/
@RunWith(Suite.class)
-@SuiteClasses({
- NumberConverterTestCase.class
-})
+@SuiteClasses(NumberConverterTestCase.class)
public class UtilTestSuite {
}
diff --git a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java
index 8d7d46928..fa4babfa2 100644
--- a/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java
+++ b/test/java/org/apache/fop/config/FontAttributesMissingTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
/**
diff --git a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java
index 84e8ee804..591104412 100644
--- a/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java
+++ b/test/java/org/apache/fop/config/FontMetricsUrlBadTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
/**
diff --git a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java
index 3479c3794..11538dc33 100644
--- a/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java
+++ b/test/java/org/apache/fop/config/FontMetricsUrlMalformedTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
/**
diff --git a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java
index 800e06d32..4bacc180c 100644
--- a/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java
+++ b/test/java/org/apache/fop/config/FontTripletAttributeMissingTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
/**
diff --git a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java
index c9f6d98ff..e05e44ab1 100644
--- a/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java
+++ b/test/java/org/apache/fop/config/FontsAutoDetectTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
public class FontsAutoDetectTestCase extends BaseConstructiveUserConfigTest {
diff --git a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java
index 2776c2cce..aab7a2e7c 100644
--- a/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java
+++ b/test/java/org/apache/fop/config/FontsDirectoryRecursiveTestCase.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import org.xml.sax.SAXException;
import org.apache.fop.apps.FopConfBuilder;
-import org.apache.fop.apps.MimeConstants;
import org.apache.fop.apps.PDFRendererConfBuilder;
/**
diff --git a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java
index 23af20a1a..f6e2b02ba 100644
--- a/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java
+++ b/test/java/org/apache/fop/datatypes/URISpecificationTestCase.java
@@ -19,10 +19,10 @@
package org.apache.fop.datatypes;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Tests for URISpecification.
*/
diff --git a/test/java/org/apache/fop/events/BasicEventTestCase.java b/test/java/org/apache/fop/events/BasicEventTestCase.java
index 87fc04329..39e3fec98 100644
--- a/test/java/org/apache/fop/events/BasicEventTestCase.java
+++ b/test/java/org/apache/fop/events/BasicEventTestCase.java
@@ -19,6 +19,8 @@
package org.apache.fop.events;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -26,7 +28,6 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.fop.events.model.EventSeverity;
-import org.junit.Test;
public class BasicEventTestCase {
diff --git a/test/java/org/apache/fop/events/EventChecker.java b/test/java/org/apache/fop/events/EventChecker.java
index 3f0eef6bb..506658467 100644
--- a/test/java/org/apache/fop/events/EventChecker.java
+++ b/test/java/org/apache/fop/events/EventChecker.java
@@ -27,7 +27,7 @@ import static org.junit.Assert.fail;
/**
* Class that checks that an expected event is produced, and only this one.
*/
-class EventChecker implements EventListener {
+public class EventChecker implements EventListener {
private final String expectedEventID;
@@ -35,7 +35,7 @@ class EventChecker implements EventListener {
private boolean eventReceived;
- EventChecker(String expectedEventID, Map<String, Object> expectedParams) {
+ public EventChecker(String expectedEventID, Map<String, Object> expectedParams) {
this.expectedEventID = expectedEventID;
this.expectedParams = expectedParams;
}
@@ -51,9 +51,9 @@ class EventChecker implements EventListener {
}
}
- void end() {
+ public void end() {
if (!eventReceived) {
- fail("Did not received expected event: " + expectedEventID);
+ fail("Did not receive expected event: " + expectedEventID);
}
}
}
diff --git a/test/java/org/apache/fop/events/TestEventProducer.java b/test/java/org/apache/fop/events/TestEventProducer.java
index ff0bc2a81..ff19c7ea6 100644
--- a/test/java/org/apache/fop/events/TestEventProducer.java
+++ b/test/java/org/apache/fop/events/TestEventProducer.java
@@ -38,7 +38,10 @@ public interface TestEventProducer extends EventProducer {
*/
void enjoy(Object source, String what);
- public class Provider {
+ public static final class Provider {
+
+ private Provider() {
+ }
public static TestEventProducer get(EventBroadcaster broadcaster) {
return (TestEventProducer)broadcaster.getEventProducerFor(TestEventProducer.class);
diff --git a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java
index 313379e02..226c551fb 100644
--- a/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java
+++ b/test/java/org/apache/fop/fo/DelegatingFOEventHandlerTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.fo;
-import static org.junit.Assert.assertArrayEquals;
-
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -42,6 +40,8 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
+import static org.junit.Assert.assertArrayEquals;
+
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory;
import org.apache.fop.fo.flow.BasicLink;
diff --git a/test/java/org/apache/fop/fo/FODocumentParser.java b/test/java/org/apache/fop/fo/FODocumentParser.java
index 7d03e38a6..2e691519b 100644
--- a/test/java/org/apache/fop/fo/FODocumentParser.java
+++ b/test/java/org/apache/fop/fo/FODocumentParser.java
@@ -64,7 +64,7 @@ public final class FODocumentParser {
/**
* A factory to create custom instances of {@link FOEventHandler}.
*/
- public static interface FOEventHandlerFactory {
+ public interface FOEventHandlerFactory {
/**
* Creates a new {@code FOEventHandler} instance parameterized with the given FO user agent.
diff --git a/test/java/org/apache/fop/fo/FONodeMocks.java b/test/java/org/apache/fop/fo/FONodeMocks.java
index ba969b9fa..97889c177 100644
--- a/test/java/org/apache/fop/fo/FONodeMocks.java
+++ b/test/java/org/apache/fop/fo/FONodeMocks.java
@@ -31,7 +31,6 @@ import org.apache.xmlgraphics.image.loader.ImageManager;
import org.apache.xmlgraphics.image.loader.ImageSessionContext;
import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.apps.FopFactory;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.flow.table.ColumnNumberManager;
import org.apache.fop.fo.flow.table.ColumnNumberManagerHolder;
@@ -46,7 +45,7 @@ public final class FONodeMocks {
/**
* Creates and returns a mock {@link FONode} configured with a mock
* {@link FOEventHandler}. The FO event handler returns a mock {@link FOUserAgent},
- * which in turn returns a mock {@link FopFactory}, which returns a mock
+ * which in turn returns a mock {@link org.apache.fop.apps.FopFactory}, which returns a mock
* {@link ImageManager}.
*
* @return a mock FO node
diff --git a/test/java/org/apache/fop/fo/flow/MarkersTestCase.java b/test/java/org/apache/fop/fo/flow/MarkersTestCase.java
index 983a531b0..09a4e129c 100644
--- a/test/java/org/apache/fop/fo/flow/MarkersTestCase.java
+++ b/test/java/org/apache/fop/fo/flow/MarkersTestCase.java
@@ -30,10 +30,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.flow.Marker;
-import org.apache.fop.fo.flow.Markers;
-import org.apache.fop.fo.flow.RetrieveMarker;
-import org.apache.fop.fo.flow.RetrieveTableMarker;
public class MarkersTestCase {
diff --git a/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java
index fb6ec6a25..0f0e347d3 100644
--- a/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java
+++ b/test/java/org/apache/fop/fo/flow/table/AbstractTableTest.java
@@ -24,8 +24,8 @@ import java.util.Iterator;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FODocumentParser;
-import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory;
+import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.util.ConsoleEventListenerForTests;
/**
diff --git a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java
index 7c0301ca7..75ba53525 100644
--- a/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java
+++ b/test/java/org/apache/fop/fo/flow/table/CollapsedConditionalBorderTestCase.java
@@ -19,18 +19,20 @@
package org.apache.fop.fo.flow.table;
-import static org.junit.Assert.assertEquals;
-
import java.awt.Color;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode.FONodeIterator;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;
+// CSOFF: LineLength
+
/**
* A testcase for the resolution of collapsed borders in the FO tree, taking
* conditionality into account. The resolved borders are generated by the
diff --git a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java
index 361517a66..884116441 100644
--- a/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java
+++ b/test/java/org/apache/fop/fo/flow/table/RowGroupBuilderTestCase.java
@@ -19,16 +19,16 @@
package org.apache.fop.fo.flow.table;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
/**
* Tests that RowGroupBuilder returns, for each part of a table, the expected number of
* row-groups with the expected number or rows in each.
diff --git a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java
index a21806559..2df0cac2a 100644
--- a/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java
+++ b/test/java/org/apache/fop/fo/flow/table/TableColumnColumnNumberTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.fo.flow.table;
-import static org.junit.Assert.assertEquals;
-
import java.util.Iterator;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FObj;
diff --git a/test/java/org/apache/fop/fo/flow/table/TableHandler.java b/test/java/org/apache/fop/fo/flow/table/TableHandler.java
index 11f24b99b..04da32b47 100644
--- a/test/java/org/apache/fop/fo/flow/table/TableHandler.java
+++ b/test/java/org/apache/fop/fo/flow/table/TableHandler.java
@@ -24,7 +24,6 @@ import java.util.List;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.FOEventHandler;
-import org.apache.fop.fo.flow.table.Table;
public class TableHandler extends FOEventHandler {
diff --git a/test/java/org/apache/fop/fo/pagination/AllTests.java b/test/java/org/apache/fop/fo/pagination/AllTests.java
index 40990cb06..bd5b21c14 100644
--- a/test/java/org/apache/fop/fo/pagination/AllTests.java
+++ b/test/java/org/apache/fop/fo/pagination/AllTests.java
@@ -19,8 +19,8 @@
package org.apache.fop.fo.pagination;
-import org.junit.runners.Suite;
import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
/**
* All test to be added in FOTreeTestSuite
@@ -28,6 +28,6 @@ import org.junit.runner.RunWith;
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({ PageSequenceMasterTestCase.class,
- RepeatablePageMasterAlternativesTestCase.class})
+ RepeatablePageMasterAlternativesTestCase.class })
public final class AllTests {
}
diff --git a/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java
index ad4f991ac..d7bc2e11c 100644
--- a/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java
+++ b/test/java/org/apache/fop/fo/pagination/PageSequenceMasterTestCase.java
@@ -19,8 +19,10 @@
package org.apache.fop.fo.pagination;
-import static org.junit.Assert.fail;
+import org.junit.Test;
+import org.xml.sax.Locator;
+import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
@@ -33,8 +35,6 @@ import static org.mockito.Mockito.when;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.layoutmgr.BlockLevelEventProducer;
-import org.junit.Test;
-import org.xml.sax.Locator;
/**
diff --git a/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java
index 5ac4860dc..ce1a97638 100644
--- a/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java
+++ b/test/java/org/apache/fop/fo/pagination/RepeatablePageMasterAlternativesTestCase.java
@@ -19,6 +19,8 @@
package org.apache.fop.fo.pagination;
+import org.junit.Test;
+
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
@@ -30,8 +32,6 @@ import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.NumericProperty;
import org.apache.fop.fo.properties.Property;
-import org.junit.Test;
-
/**
* Unit Test for RepeatablePageMasterAlternatives
*
diff --git a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java
index cd5d545ff..89ed2733d 100644
--- a/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java
+++ b/test/java/org/apache/fop/fo/properties/AltTextHolderTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.fo.properties;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import org.junit.Test;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.Constants;
diff --git a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java
index 352a39713..81ebc2f41 100644
--- a/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java
+++ b/test/java/org/apache/fop/fo/properties/CommonAccessibilityHolderTestCase.java
@@ -19,16 +19,16 @@
package org.apache.fop.fo.properties;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FONodeMocks;
diff --git a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
index 20212b002..4c89d00da 100644
--- a/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
+++ b/test/java/org/apache/fop/fonts/DejaVuLGCSerifTestCase.java
@@ -24,11 +24,11 @@ import java.io.File;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;
-import static org.junit.Assert.assertEquals;
-
/**
*
*/
@@ -58,4 +58,17 @@ public class DejaVuLGCSerifTestCase {
public void testFontName() {
assertEquals("DejaVuLGCSerif", font.getFontName());
}
+
+ @Test
+ public void testUnderline() {
+ assertEquals(-840, font.getUnderlinePosition(10));
+ assertEquals(430, font.getUnderlineThickness(10));
+ }
+
+ @Test
+ public void testStrikeout() {
+ assertEquals(2340, font.getStrikeoutPosition(10));
+ assertEquals(490, font.getStrikeoutThickness(10));
+ }
+
}
diff --git a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java
index ee3498a03..c8099f860 100644
--- a/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java
+++ b/test/java/org/apache/fop/fonts/EmbedFontInfoTestCase.java
@@ -35,7 +35,7 @@ import static org.junit.Assert.assertTrue;
*/
public class EmbedFontInfoTestCase {
- public EmbedFontInfoTestCase() {}
+ public EmbedFontInfoTestCase() { }
private EmbedFontInfo sut;
diff --git a/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
index 509ee56f4..b4271ba60 100644
--- a/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
+++ b/test/java/org/apache/fop/fonts/FontEventProcessingTestCase.java
@@ -52,13 +52,4 @@ public class FontEventProcessingTestCase {
MimeConstants.MIME_PDF);
}
- @Test
- public void testSVGFontStrokedAsShapes() throws Exception {
- // svg-fonts.fo embeds two fonts; one that is present in the system and the other is not; the
- // missing font is stroked as shapes while the fonts that exists is stroked as text
- InputStream inStream = getClass().getResourceAsStream("svg-fonts.fo");
- eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".svgTextStrokedAsShapes",
- MimeConstants.MIME_PDF);
- }
-
}
diff --git a/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java b/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java
index 073743c13..d653171b7 100644
--- a/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java
+++ b/test/java/org/apache/fop/fonts/FontManagerConfiguratorTestCase.java
@@ -20,7 +20,6 @@
package org.apache.fop.fonts;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
@@ -28,13 +27,14 @@ import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FopConfBuilder;
import org.apache.fop.apps.FopConfParser;
import org.apache.fop.apps.FopFactory;
import static org.apache.fop.apps.FopConfParserTestCase.getFopFactory;
-import static org.junit.Assert.assertEquals;
/**
* A test case for {@link FontManagerConfigurator}.
@@ -84,7 +84,7 @@ public class FontManagerConfiguratorTestCase {
/**
* This test is an interesting one; it's basically testing that if a base URI pointing to a
* directory that doesn't exist is used, an error is not thrown. The URI resolver should handle
- * any {@link FileNotFoundException}s, not the configuration. We're NOT testing whether a font
+ * any {@link java.io.FileNotFoundException}s, not the configuration. We're NOT testing whether a font
* can be resolved here, just that the URI resolver accepts it as its base URI.
*/
@Test
diff --git a/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java b/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java
index 64c7642eb..97ea5c52b 100644
--- a/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java
+++ b/test/java/org/apache/fop/fonts/cff/CFFDataReaderTestCase.java
@@ -26,14 +26,14 @@ import java.util.Random;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fontbox.cff.CFFDataInput;
import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData;
import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry;
import org.apache.fop.fonts.truetype.OTFSubSetFile;
-import static org.junit.Assert.assertEquals;
-
public class CFFDataReaderTestCase {
private CFFDataReader cffReader;
@@ -113,7 +113,7 @@ public class CFFDataReaderTestCase {
//Array comparison
int[] fontBBox = { -50, -40, 100, 120 };
DICTEntry fontBBoxEntry = dictMap.get("FontBBox");
- for (int i = 0;i < fontBBoxEntry.getOperands().size();i++) {
+ for (int i = 0; i < fontBBoxEntry.getOperands().size(); i++) {
assertEquals(fontBBoxEntry.getOperands().get(i).intValue(), fontBBox[i]);
}
//Multi-byte offset (number)
@@ -141,7 +141,7 @@ public class CFFDataReaderTestCase {
};
Random randGen = new Random();
byte[] data = new byte[31];
- for (int i = 0;i < data.length;i++) {
+ for (int i = 0; i < data.length; i++) {
data[i] = (byte)randGen.nextInt(255);
}
testIndex = OTFSubSetFile.concatArray(testIndex, data);
diff --git a/test/java/org/apache/fop/fonts/svg-fonts.fo b/test/java/org/apache/fop/fonts/svg-fonts.fo
deleted file mode 100644
index 0c5f3f599..000000000
--- a/test/java/org/apache/fop/fonts/svg-fonts.fo
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
- <fo:layout-master-set>
- <fo:simple-page-master master-name="page">
- <fo:region-body />
- </fo:simple-page-master>
- </fo:layout-master-set>
- <fo:page-sequence master-reference="page">
- <fo:flow flow-name="xsl-region-body">
- <fo:block>
- <fo:instream-foreign-object>
- <svg:svg width="250" height="50">
- <svg:font horiz-adv-x="1000">
- <svg:font-face font-family="Missing" units-per-em="1000" underline-position="-100"
- underline-thickness="50" />
- <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
- <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
- <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
- <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
- </svg:font>
- <svg:font horiz-adv-x="1000">
- <!-- this is not Helvetica but it is here to increase coverage and show the code takes expected path -->
- <svg:font-face font-family="Helvetica" units-per-em="1000" underline-position="-100"
- underline-thickness="50" />
- <svg:glyph unicode="A" horiz-adv-x="686" d="M162,186l362,0l78,-186l84,0l-308,708l-70,0l-308,-708l84,0M343,624l153,-372l-307,0z" />
- <svg:glyph unicode="C" horiz-adv-x="704" d="M620,154C567,72 491,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C492,660 571,613 599,567l63,47C600,693 505,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C534,-18 632,39 679,112z" />
- <svg:glyph unicode="F" horiz-adv-x="556" d="M168,335l330,0l0,66l-330,0l0,241l355,0l0,66l-427,0l0,-708l72,0z" />
- <svg:glyph unicode="G" horiz-adv-x="778" d="M673,631C610,694 529,726 417,726C206,726 48,569 48,354C48,139 206,-18 417,-18C503,-18 606,7 685,54l0,347l-241,0l0,-66l169,0l0,-237C560,68 490,48 417,48C235,48 126,191 126,354C126,517 235,660 417,660C504,660 571,629 619,578z" />
- </svg:font>
- <svg:text x="20" y="20" font-family="Missing" font-size="12">ACFG</svg:text>
- <svg:text x="20" y="40" font-family="Helvetica" font-size="12">ACFG</svg:text>
- </svg:svg>
- </fo:instream-foreign-object>
- </fo:block>
- </fo:flow>
- </fo:page-sequence>
-</fo:root>
diff --git a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
index e794ab1a8..952c3ec1f 100644
--- a/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/GlyfTableTestCase.java
@@ -37,7 +37,7 @@ import static org.junit.Assert.assertTrue;
*/
public class GlyfTableTestCase {
- private final static class DirData {
+ private static final class DirData {
final long offset;
final long length;
diff --git a/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java
index 737c2e05e..b4e2cee2e 100644
--- a/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/OTFFileTestCase.java
@@ -20,7 +20,6 @@
package org.apache.fop.fonts.truetype;
import java.io.FileInputStream;
-import java.io.IOException;
import java.io.InputStream;
import org.junit.Before;
@@ -37,7 +36,7 @@ public class OTFFileTestCase {
/**
* Initializes fonts used for the testing of reading OTF CFF
- * @throws IOException
+ * @throws java.io.IOException
*/
@Before
public void setUp() throws Exception {
@@ -75,11 +74,11 @@ public class OTFFileTestCase {
int[] gids = {32, 42, 44, 47};
int[] sourceSansWidths = {516, 555, 572, 383};
- for (int i = 0;i < gids.length;i++) {
+ for (int i = 0; i < gids.length; i++) {
assertEquals(sourceSansWidths[i], sourceSansProBold.getWidths()[gids[i]]);
}
int[] carolynaWidths = {842, 822, 658, 784};
- for (int i = 0;i < gids.length;i++) {
+ for (int i = 0; i < gids.length; i++) {
assertEquals(carolynaWidths[i], alexBrush.getWidths()[gids[i]]);
}
}
diff --git a/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
index 604cca3a8..fecb1e9f1 100644
--- a/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/OTFSubSetFileTestCase.java
@@ -20,6 +20,8 @@
package org.apache.fop.fonts.truetype;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,18 +29,15 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
-import org.apache.fontbox.cff.CFFDataInput;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fontbox.cff.CFFFont;
-import org.apache.fontbox.cff.CFFParser;
-import org.apache.fontbox.cff.IndexData;
-import org.apache.fontbox.cff.Type2CharStringParser;
import org.apache.fop.fonts.cff.CFFDataReader;
import org.apache.fop.fonts.cff.CFFDataReader.CFFIndexData;
import org.apache.fop.fonts.cff.CFFDataReader.DICTEntry;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.apache.fop.fonts.truetype.OTFSubSetFile.BytesNumber;
public class OTFSubSetFileTestCase extends OTFFileTestCase {
@@ -47,10 +46,6 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase {
private byte[] sourceSansData;
CFFDataReader cffReaderHeitiStd;
- public OTFSubSetFileTestCase() throws IOException {
- super();
- }
-
/**
* Initialises the test by creating the font subset. A CFFDataReader is
* also created based on the subset data for use in the tests.
@@ -80,12 +75,17 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase {
public void testCharStringIndex() throws IOException {
assertEquals(256, cffReaderSourceSans.getCharStringIndex().getNumObjects());
assertTrue(checkCorrectOffsets(cffReaderSourceSans.getCharStringIndex()));
- validateCharStrings(cffReaderSourceSans);
+ validateCharStrings(cffReaderSourceSans, sourceSansSubset.getCFFReader());
}
+ /**
+ * Checks the index data to ensure that the offsets are valid
+ * @param indexData The index data to check
+ * @return Returns true if it is found to be valid
+ */
private boolean checkCorrectOffsets(CFFIndexData indexData) {
int last = 0;
- for (int i = 0;i < indexData.getOffsets().length;i++) {
+ for (int i = 0; i < indexData.getOffsets().length; i++) {
if (indexData.getOffsets()[i] < last) {
return false;
}
@@ -94,35 +94,268 @@ public class OTFSubSetFileTestCase extends OTFFileTestCase {
return true;
}
- private void validateCharStrings(CFFDataReader cffReader) throws IOException {
+ /**
+ * Validates the subset font CharString data by comparing it with the original.
+ * @param subsetCFF The subset CFFDataReader containing the CharString data
+ * @param origCFF The original CFFDataReader containing the CharString data
+ * @throws IOException
+ */
+ private void validateCharStrings(CFFDataReader subsetCFF, CFFDataReader origCFF)
+ throws IOException {
CFFFont sourceSansOriginal = sourceSansProBold.fileFont;
+ CFFIndexData charStrings = subsetCFF.getCharStringIndex();
Map<String, byte[]> origCharStringData = sourceSansOriginal.getCharStringsDict();
- IndexData origGlobalIndex = sourceSansOriginal.getGlobalSubrIndex();
- IndexData origLocalIndex = sourceSansOriginal.getLocalSubrIndex();
+ for (int i = 0; i < charStrings.getNumObjects(); i++) {
+ byte[] origCharData = origCharStringData.get(origCharStringData.keySet().toArray(
+ new String[0])[i]);
+ byte[] charData = charStrings.getValue(i);
+ List<BytesNumber> origOperands = getFullCharString(origCharData, origCFF);
+ List<BytesNumber> subsetOperands = getFullCharString(charData, subsetCFF);
+ for (int j = 0; j < origOperands.size(); j++) {
+ assertTrue(origOperands.get(j).equals(subsetOperands.get(j)));
+ }
+ }
+ }
+
+ /**
+ * Recursively reads and constructs the full CharString for comparison
+ * @param data The original byte data of the CharString
+ * @param cffData The CFFDataReader containing the subroutine indexes
+ * @return Returns a list of parsed operands and operators
+ * @throws IOException
+ */
+ private List<BytesNumber> getFullCharString(byte[] data, CFFDataReader cffData) throws IOException {
+ CFFIndexData localIndexSubr = cffData.getLocalIndexSubr();
+ CFFIndexData globalIndexSubr = cffData.getGlobalIndexSubr();
+ boolean hasLocalSubroutines = localIndexSubr != null && localIndexSubr.getNumObjects() > 0;
+ boolean hasGlobalSubroutines = globalIndexSubr != null && globalIndexSubr.getNumObjects() > 0;
+ ArrayList<BytesNumber> operands = new ArrayList<BytesNumber>();
+ for (int dataPos = 0; dataPos < data.length; dataPos++) {
+ int b0 = data[dataPos] & 0xff;
+ if (b0 == 10 && hasLocalSubroutines) {
+ int subrNumber = getSubrNumber(localIndexSubr.getNumObjects(),
+ operands.get(operands.size() - 1).getNumber());
+ byte[] subr = localIndexSubr.getValue(subrNumber);
+ List<BytesNumber> subrOperands = getFullCharString(subr, cffData);
+ operands = mergeOperands(operands, subrOperands);
+ } else if (b0 == 29 && hasGlobalSubroutines) {
+ int subrNumber = getSubrNumber(globalIndexSubr.getNumObjects(),
+ operands.get(operands.size() - 1).getNumber());
+ byte[] subr = globalIndexSubr.getValue(subrNumber);
+ ArrayList<BytesNumber> subrOperands = (ArrayList<BytesNumber>)getFullCharString(subr, cffData);
+ operands = mergeOperands(operands, subrOperands);
+ } else if ((b0 >= 0 && b0 <= 27) || (b0 >= 29 && b0 <= 31)) {
+ int size = 1;
+ int b1 = -1;
+ if (b0 == 12) {
+ b1 = data[dataPos++] & 0xff;
+ size = 2;
+ }
+ if (b0 == 19 || b0 == 20) {
+ dataPos += 1;
+ size = 2;
+ }
+ operands.add(new Operator(b0, size, getOperatorName(b0, b1)));
+ } else if (b0 == 28 || (b0 >= 32 && b0 <= 255)) {
+ operands.add(readNumber(b0, data, dataPos));
+ dataPos += operands.get(operands.size() - 1).getNumBytes() - 1;
+ }
+ }
+ return operands;
+ }
+
+ /**
+ * Merges two lists of operands. This is typically used to merge the CharString
+ * data with that of a parsed and referenced subroutine.
+ * @param charString The parsed CharString data so far
+ * @param subroutine The parsed elements from a subroutine
+ * @return Returns a merged list of both CharString and subroutine elements.
+ */
+ private ArrayList<BytesNumber> mergeOperands(List<BytesNumber> charString,
+ List<BytesNumber> subroutine) {
+ BytesNumber[] charStringOperands = charString.toArray(new BytesNumber[0]);
+ BytesNumber[] subroutineOperands = subroutine.toArray(new BytesNumber[0]);
+ BytesNumber[] mergeData = new BytesNumber[charStringOperands.length - 1
+ + subroutineOperands.length - 1];
+ System.arraycopy(charStringOperands, 0, mergeData, 0, charStringOperands.length - 1);
+ System.arraycopy(subroutineOperands, 0, mergeData, charStringOperands.length - 1,
+ subroutineOperands.length - 1);
+ ArrayList<BytesNumber> hello = new ArrayList<BytesNumber>();
+ hello.addAll(Arrays.asList(mergeData));
+ return hello;
+ }
- CFFDataInput globalSubrs = new CFFDataInput(cffReader.getGlobalIndexSubr().getByteData());
- CFFDataInput localSubrs = new CFFDataInput(cffReader.getLocalIndexSubr().getByteData());
+ /**
+ * Parses a number from one or more bytes
+ * @param b0 The first byte to identify how to interpret the number
+ * @param input The original byte data containing the number
+ * @param curPos The current position of the number
+ * @return Returns the number
+ * @throws IOException
+ */
+ private BytesNumber readNumber(int b0, byte[] input, int curPos) throws IOException {
+ if (b0 == 28) {
+ int b1 = input[curPos + 1] & 0xff;
+ int b2 = input[curPos + 2] & 0xff;
+ return new BytesNumber(Integer.valueOf((short) (b1 << 8 | b2)), 3);
+ } else if (b0 >= 32 && b0 <= 246) {
+ return new BytesNumber(Integer.valueOf(b0 - 139), 1);
+ } else if (b0 >= 247 && b0 <= 250) {
+ int b1 = input[curPos + 1] & 0xff;
+ return new BytesNumber(Integer.valueOf((b0 - 247) * 256 + b1 + 108), 2);
+ } else if (b0 >= 251 && b0 <= 254) {
+ int b1 = input[curPos + 1] & 0xff;
+ return new BytesNumber(Integer.valueOf(-(b0 - 251) * 256 - b1 - 108), 2);
+ } else if (b0 == 255) {
+ int b1 = input[curPos + 1] & 0xff;
+ int b2 = input[curPos + 2] & 0xff;
+ return new BytesNumber(Integer.valueOf((short)(b1 << 8 | b2)), 5);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
- IndexData globalIndexData = CFFParser.readIndexData(globalSubrs);
- IndexData localIndexData = CFFParser.readIndexData(localSubrs);
+ /**
+ * Gets the subroutine number according to the number of subroutines
+ * and the provided operand.
+ * @param numSubroutines The number of subroutines used to calculate the
+ * subroutine reference.
+ * @param operand The operand for the subroutine
+ * @return Returns the calculated subroutine number
+ */
+ private int getSubrNumber(int numSubroutines, int operand) {
+ int bias = getBias(numSubroutines);
+ return bias + operand;
+ }
- CFFIndexData charStrings = cffReader.getCharStringIndex();
- for (int i = 0;i < charStrings.getNumObjects();i++) {
- byte[] charData = charStrings.getValue(i);
- Type2CharStringParser parser = new Type2CharStringParser();
+ /**
+ * Gets the bias give the number of subroutines. This is used in the
+ * calculation to determine a subroutine's number
+ * @param subrCount The number of subroutines for a given index
+ * @return Returns the bias value
+ */
+ private int getBias(int subrCount) {
+ if (subrCount < 1240) {
+ return 107;
+ } else if (subrCount < 33900) {
+ return 1131;
+ } else {
+ return 32768;
+ }
+ }
- byte[] origCharData = origCharStringData.get(origCharStringData.keySet().toArray(
- new String[0])[i]);
- List<Object> origSeq = parser.parse(origCharData, origGlobalIndex, origLocalIndex);
+ /**
+ * A class representing an operator from the CharString data
+ */
+ private class Operator extends BytesNumber {
+ private String opName = "";
- List<Object> subsetSeq = parser.parse(charData, globalIndexData, localIndexData);
+ public Operator(int number, int numBytes, String opName) {
+ super(number, numBytes);
+ this.opName = opName;
+ }
+ public String toString() {
+ return String.format("[%s]", opName);
+ }
+ }
- //Validates the subset glyph render routines against the originals
- assertEquals(origSeq, subsetSeq);
+ /**
+ * Gets the identifying name for the given operator. This is primarily
+ * used for debugging purposes. See the Type 2 CharString Format specification
+ * document (Technical Note #5177) Appendix A (Command Codes).
+ * @param operator The operator code
+ * @param codeb The second byte of the operator
+ * @return Returns the operator name.
+ */
+ private String getOperatorName(int operator, int operatorB) {
+ switch (operator) {
+ case 0: return "Reserved";
+ case 1: return "hstem";
+ case 2: return "Reserved";
+ case 3: return "vstem";
+ case 4: return "vmoveto";
+ case 5: return "rlineto";
+ case 6: return "hlineto";
+ case 7: return "vlineto";
+ case 8: return "rrcurveto";
+ case 9: return "Reserved";
+ case 10: return "callsubr";
+ case 11: return "return";
+ case 12: return getDoubleOpName(operatorB);
+ case 13: return "Reserved";
+ case 14: return "enchar";
+ case 15:
+ case 16:
+ case 17: return "Reserved";
+ case 18: return "hstemhm";
+ case 19: return "hintmask";
+ case 20: return "cntrmask";
+ case 21: return "rmoveto";
+ case 22: return "hmoveto";
+ case 23: return "vstemhm";
+ case 24: return "rcurveline";
+ case 25: return "rlinecurve";
+ case 26: return "vvcurveto";
+ case 27: return "hhcurveto";
+ case 28: return "shortint";
+ case 29: return "callgsubr";
+ case 30: return "vhcurveto";
+ case 31: return "hvcurveto";
+ default: return "Unknown";
}
}
/**
+ * Gets the name of a double byte operator code
+ * @param operator The second byte of the operator
+ * @return Returns the name
+ */
+ private String getDoubleOpName(int operator) {
+ switch (operator) {
+ case 0:
+ case 1:
+ case 2: return "Reserved";
+ case 3: return "and";
+ case 4: return "or";
+ case 5: return "not";
+ case 6:
+ case 7:
+ case 8: return "Reserved";
+ case 9: return "abs";
+ case 10: return "add";
+ case 11: return "sub";
+ case 12: return "div";
+ case 13: return "Reserved";
+ case 14: return "neg";
+ case 15: return "eq";
+ case 16:
+ case 17: return "Reserved";
+ case 18: return "drop";
+ case 19: return "Reserved";
+ case 20: return "put";
+ case 21: return "get";
+ case 22: return "ifelse";
+ case 23: return "random";
+ case 24: return "mul";
+ case 25: return "Reserved";
+ case 26: return "sqrt";
+ case 27: return "dup";
+ case 28: return "exch";
+ case 29: return "index";
+ case 30: return "roll";
+ case 31:
+ case 32:
+ case 33: return "Reserved";
+ case 34: return "hflex";
+ case 35: return "flex";
+ case 36: return "hflex1";
+ case 37: return "flex1";
+ case 38: return "Reserved";
+ default: return "Unknown";
+ }
+ }
+
+ /**
* Validates the String index data and size
* @throws IOException
*/
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
index a390bef0f..a78b3e674 100644
--- a/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/TTFFileTestCase.java
@@ -26,12 +26,12 @@ import java.util.Map;
import org.junit.Test;
-import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import org.apache.fop.fonts.truetype.OpenFont.PostScriptVersion;
+
/**
* Class for testing org.apache.fop.fonts.truetype.TTFFile
*/
@@ -430,6 +430,24 @@ public class TTFFileTestCase {
assertEquals(true, droidmonoTTFFile.isEmbeddable());
}
+ /** Underline position and thickness. */
+ @Test
+ public void testUnderline() {
+ assertEquals(-63, dejavuTTFFile.getUnderlinePosition());
+ assertEquals(43, dejavuTTFFile.getUnderlineThickness());
+ assertEquals(-75, droidmonoTTFFile.getUnderlinePosition());
+ assertEquals(49, droidmonoTTFFile.getUnderlineThickness());
+ }
+
+ /** Strikeout position and thickness. */
+ @Test
+ public void testStrikeout() {
+ assertEquals(258, dejavuTTFFile.getStrikeoutPosition());
+ assertEquals(49, dejavuTTFFile.getStrikeoutThickness());
+ assertEquals(243, droidmonoTTFFile.getStrikeoutPosition());
+ assertEquals(49, droidmonoTTFFile.getStrikeoutThickness());
+ }
+
/**
* Test readFont() - Add implementation if necessary.
*/
diff --git a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
index f50b116ac..899fe1d73 100644
--- a/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
+++ b/test/java/org/apache/fop/fonts/truetype/TTFFontLoaderTestCase.java
@@ -25,14 +25,14 @@ import java.net.URI;
import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.apps.io.ResourceResolverFactory;
import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
/**
* Test case for {@link OFFontLoader}.
*/
diff --git a/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java
index 93443a0d9..31a613567 100644
--- a/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java
+++ b/test/java/org/apache/fop/fonts/type1/AFMParserTestCase.java
@@ -19,9 +19,6 @@
package org.apache.fop.fonts.type1;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.awt.Rectangle;
import java.io.IOException;
import java.io.InputStream;
@@ -29,6 +26,9 @@ import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
/**
* Test case for {@link AFMParser}.
*/
@@ -128,4 +128,13 @@ public class AFMParserTestCase {
private boolean objectEquals(Object o1, Object o2) {
return o1 == null ? o2 == null : (o1 == o2 || o1.equals(o2));
}
+
+ @Test
+ public void testUnderlinePositionAndThickness() throws IOException {
+ AFMFile afm = sut.parse(getClass().getResourceAsStream("underline.afm"), null);
+ AFMWritingDirectionMetrics metrics = afm.getWritingDirectionMetrics(0);
+ assertEquals(-96, metrics.getUnderlinePosition());
+ assertEquals(58, metrics.getUnderlineThickness());
+ }
+
}
diff --git a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java
index 10ba42119..a3a3e1c40 100644
--- a/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java
+++ b/test/java/org/apache/fop/fonts/type1/AdobeStandardEncodingTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.fonts.type1;
-import static org.junit.Assert.assertEquals;
-
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -30,6 +28,8 @@ import java.io.InputStreamReader;
import org.junit.BeforeClass;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Test case for {@link AdobeStandardEncoding}.
*/
diff --git a/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java
index de9af2d33..c3e9334dd 100644
--- a/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java
+++ b/test/java/org/apache/fop/fonts/type1/CharMetricsHandlerTestCase.java
@@ -19,10 +19,6 @@
package org.apache.fop.fonts.type1;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
import java.awt.Rectangle;
import java.io.IOException;
import java.util.HashMap;
@@ -31,6 +27,10 @@ import java.util.Stack;
import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import org.apache.fop.fonts.NamedCharacter;
import org.apache.fop.fonts.type1.AFMParser.ValueHandler;
diff --git a/test/java/org/apache/fop/fonts/type1/underline.afm b/test/java/org/apache/fop/fonts/type1/underline.afm
new file mode 100644
index 000000000..8137b41eb
--- /dev/null
+++ b/test/java/org/apache/fop/fonts/type1/underline.afm
@@ -0,0 +1,4 @@
+StartFontMetrics 2.0
+UnderlinePosition -96
+UnderlineThickness 58
+EndFontMetrics
diff --git a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java
index 5070984d1..955644ae4 100644
--- a/test/java/org/apache/fop/fotreetest/ext/AssertElement.java
+++ b/test/java/org/apache/fop/fotreetest/ext/AssertElement.java
@@ -20,6 +20,9 @@
package org.apache.fop.fotreetest.ext;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOPropertyMapping;
@@ -32,9 +35,6 @@ import org.apache.fop.fo.properties.Property;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.fotreetest.ResultCollector;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-
/**
* Defines the assert element for the FOP Test extension.
*/
diff --git a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java
index eee0efac4..b61944eae 100644
--- a/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java
+++ b/test/java/org/apache/fop/fotreetest/ext/TestElementMapping.java
@@ -19,8 +19,8 @@
package org.apache.fop.fotreetest.ext;
-import org.apache.fop.fo.FONode;
import org.apache.fop.fo.ElementMapping;
+import org.apache.fop.fo.FONode;
/**
* This class provides the element mapping for FOP.
diff --git a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java
index f4763512a..7f3036c24 100644
--- a/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java
+++ b/test/java/org/apache/fop/image/loader/batik/ImageLoaderTestCase.java
@@ -19,10 +19,6 @@
package org.apache.fop.image.loader.batik;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
@@ -30,6 +26,10 @@ import java.io.File;
import org.junit.Ignore;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageInfo;
diff --git a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java
index efc5df1f7..3d690b67c 100644
--- a/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java
+++ b/test/java/org/apache/fop/image/loader/batik/ImagePreloaderTestCase.java
@@ -19,15 +19,15 @@
package org.apache.fop.image.loader.batik;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
import java.io.File;
import java.io.IOException;
import org.junit.Ignore;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
import org.apache.xmlgraphics.image.loader.ImageException;
import org.apache.xmlgraphics.image.loader.ImageInfo;
import org.apache.xmlgraphics.image.loader.ImageManager;
diff --git a/test/java/org/apache/fop/intermediate/AbstractIFTest.java b/test/java/org/apache/fop/intermediate/AbstractIFTest.java
index 419db2c47..48c3f335b 100644
--- a/test/java/org/apache/fop/intermediate/AbstractIFTest.java
+++ b/test/java/org/apache/fop/intermediate/AbstractIFTest.java
@@ -34,7 +34,6 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.w3c.dom.Document;
-
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
diff --git a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java
index 3fc855cef..2003958c8 100644
--- a/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java
+++ b/test/java/org/apache/fop/intermediate/AreaTreeXMLFormatTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* JUnit test suite for the area tree XML format
*/
@RunWith(Suite.class)
-@SuiteClasses({ AreaTreeParserTestCase.class })
+@SuiteClasses(AreaTreeParserTestCase.class)
public class AreaTreeXMLFormatTestSuite {
}
diff --git a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java
index 58281fc10..83dd88661 100644
--- a/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java
+++ b/test/java/org/apache/fop/intermediate/IFMimickingTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.intermediate;
-import static org.junit.Assert.fail;
-
import java.io.File;
import javax.xml.transform.ErrorListener;
@@ -34,6 +32,8 @@ import javax.xml.transform.stream.StreamSource;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.fail;
+
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
diff --git a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java
index f960990b2..71b26cb9b 100644
--- a/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java
+++ b/test/java/org/apache/fop/intermediate/IntermediateFormatTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* A test suite for testing the Intermediate Format output.
*/
@RunWith(Suite.class)
-@SuiteClasses({ IFTestCase.class })
+@SuiteClasses(IFTestCase.class)
public final class IntermediateFormatTestSuite {
}
diff --git a/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java
index 5d87df1a5..ea60f2ff4 100644
--- a/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java
+++ b/test/java/org/apache/fop/intermediate/LayoutIFTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* JUnit test suite for the intermediate format
*/
@RunWith(Suite.class)
-@SuiteClasses({ IFParserTestCase.class })
+@SuiteClasses(IFParserTestCase.class)
public final class LayoutIFTestSuite {
}
diff --git a/test/java/org/apache/fop/layoutengine/ElementListCheck.java b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
index e63fc3291..4d33d670b 100644
--- a/test/java/org/apache/fop/layoutengine/ElementListCheck.java
+++ b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
@@ -22,16 +22,17 @@ package org.apache.fop.layoutengine;
import java.util.Iterator;
import java.util.List;
-import org.apache.fop.layoutmgr.KnuthBox;
-import org.apache.fop.layoutmgr.KnuthElement;
-import org.apache.fop.layoutmgr.KnuthGlue;
-import org.apache.fop.layoutmgr.KnuthPenalty;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
+import org.apache.fop.layoutmgr.KnuthBox;
+import org.apache.fop.layoutmgr.KnuthElement;
+import org.apache.fop.layoutmgr.KnuthGlue;
+import org.apache.fop.layoutmgr.KnuthPenalty;
+
/**
* Check implementation that checks a Knuth element list.
*/
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
index e739221b0..ad0804af5 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestCase.java
@@ -21,8 +21,12 @@ package org.apache.fop.layoutengine;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
@@ -41,10 +45,16 @@ import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import org.apache.fop.DebugHelper;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
@@ -53,6 +63,8 @@ import org.apache.fop.apps.FormattingResults;
import org.apache.fop.area.AreaTreeModel;
import org.apache.fop.area.AreaTreeParser;
import org.apache.fop.area.RenderPagesModel;
+import org.apache.fop.events.Event;
+import org.apache.fop.events.EventListener;
import org.apache.fop.events.model.EventSeverity;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.intermediate.IFTester;
@@ -131,6 +143,8 @@ public class LayoutEngineTestCase {
Fop fop;
FopFactory effFactory;
+ EventsChecker eventsChecker = new EventsChecker(
+ new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN));
try {
Document testDoc = testAssistant.loadTestCase(testFile);
effFactory = testAssistant.getFopFactory(testDoc);
@@ -146,8 +160,7 @@ public class LayoutEngineTestCase {
//Setup FOP for area tree rendering
FOUserAgent ua = effFactory.newFOUserAgent();
- ua.getEventBroadcaster().addEventListener(
- new ConsoleEventListenerForTests(testFile.getName(), EventSeverity.WARN));
+ ua.getEventBroadcaster().addEventListener(eventsChecker);
XMLRenderer atrenderer = new XMLRenderer(ua);
atrenderer.setContentHandler(athandler);
@@ -167,7 +180,60 @@ public class LayoutEngineTestCase {
}
FormattingResults results = fop.getResults();
LayoutResult result = new LayoutResult(doc, elCollector, results);
- checkAll(effFactory, testFile, result);
+ checkAll(effFactory, testFile, result, eventsChecker);
+ }
+
+ private static class EventsChecker implements EventListener {
+
+ private final List<Event> events = new ArrayList<Event>();
+
+ private final EventListener defaultListener;
+
+ /**
+ * @param fallbackListener the listener to which this class will pass through
+ * events that are not being checked
+ */
+ public EventsChecker(EventListener fallbackListener) {
+ this.defaultListener = fallbackListener;
+ }
+
+ public void processEvent(Event event) {
+ events.add(event);
+ }
+
+ public void checkEvent(String expectedKey, Map<String, String> expectedParams) {
+ boolean eventFound = false;
+ for (Iterator<Event> iter = events.iterator(); !eventFound && iter.hasNext();) {
+ Event event = iter.next();
+ if (event.getEventKey().equals(expectedKey)) {
+ eventFound = true;
+ iter.remove();
+ checkParameters(event, expectedParams);
+ }
+ }
+ if (!eventFound) {
+ fail("Event did not occur but was expected to: " + expectedKey + expectedParams);
+ }
+ }
+
+ private void checkParameters(Event event, Map<String, String> expectedParams) {
+ Map<String, Object> actualParams = event.getParams();
+ for (Map.Entry<String, String> expectedParam : expectedParams.entrySet()) {
+ assertTrue("Event \"" + event.getEventKey()
+ + "\" is missing parameter \"" + expectedParam.getKey() + '"',
+ actualParams.containsKey(expectedParam.getKey()));
+ assertEquals("Event \"" + event.getEventKey()
+ + "\" has wrong value for parameter \"" + expectedParam.getKey() + "\";",
+ actualParams.get(expectedParam.getKey()).toString(),
+ expectedParam.getValue());
+ }
+ }
+
+ public void emitUncheckedEvents() {
+ for (Event event : events) {
+ defaultListener.processEvent(event);
+ }
+ }
}
/**
@@ -177,8 +243,8 @@ public class LayoutEngineTestCase {
* @param result The layout results
* @throws TransformerException if a problem occurs in XSLT/JAXP
*/
- protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result)
- throws TransformerException {
+ protected void checkAll(FopFactory fopFactory, File testFile, LayoutResult result,
+ EventsChecker eventsChecker) throws TransformerException {
Element testRoot = testAssistant.getTestRoot(testFile);
NodeList nodes;
@@ -196,6 +262,13 @@ public class LayoutEngineTestCase {
Document ifDocument = createIF(fopFactory, testFile, result.getAreaTree());
ifTester.doIFChecks(testFile.getName(), ifChecks, ifDocument);
}
+
+ nodes = testRoot.getElementsByTagName("event-checks");
+ if (nodes.getLength() > 0) {
+ Element eventChecks = (Element) nodes.item(0);
+ doEventChecks(eventChecks, eventsChecker);
+ }
+ eventsChecker.emitUncheckedEvents();
}
private Document createIF(FopFactory fopFactory, File testFile, Document areaTreeXML)
@@ -254,4 +327,28 @@ public class LayoutEngineTestCase {
}
}
+ private void doEventChecks(Element eventChecks, EventsChecker eventsChecker) {
+ NodeList events = eventChecks.getElementsByTagName("event");
+ for (int i = 0; i < events.getLength(); i++) {
+ Element event = (Element) events.item(i);
+ NamedNodeMap attributes = event.getAttributes();
+ Map<String, String> params = new HashMap<String, String>();
+ String key = null;
+ for (int j = 0; j < attributes.getLength(); j++) {
+ Node attribute = attributes.item(j);
+ String name = attribute.getNodeName();
+ String value = attribute.getNodeValue();
+ if ("key".equals(name)) {
+ key = value;
+ } else {
+ params.put(name, value);
+ }
+ }
+ if (key == null) {
+ throw new RuntimeException("An event element must have a \"key\" attribute");
+ }
+ eventsChecker.checkEvent(key, params);
+ }
+ }
+
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
index 2a70f255d..89bf28a55 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* JUnit test suit for running layout engine test under JUnit control.
*/
@RunWith(Suite.class)
-@SuiteClasses({ LayoutEngineTestCase.class })
+@SuiteClasses(LayoutEngineTestCase.class)
public class LayoutEngineTestSuite {
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java
index fb7f07023..963b66dff 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutEngineTestUtils.java
@@ -162,7 +162,7 @@ public final class LayoutEngineTestUtils {
Collection<File[]> parametersForJUnit4 = new ArrayList<File[]>();
int index = 0;
for (File f : files) {
- parametersForJUnit4.add(new File[] { f });
+ parametersForJUnit4.add(new File[] {f});
if (DEBUG) {
System.out.println(String.format("%3d %s", index++, f));
}
diff --git a/test/java/org/apache/fop/layoutengine/LayoutResult.java b/test/java/org/apache/fop/layoutengine/LayoutResult.java
index 52c83daa8..92c459234 100644
--- a/test/java/org/apache/fop/layoutengine/LayoutResult.java
+++ b/test/java/org/apache/fop/layoutengine/LayoutResult.java
@@ -19,9 +19,10 @@
package org.apache.fop.layoutengine;
-import org.apache.fop.apps.FormattingResults;
import org.w3c.dom.Document;
+import org.apache.fop.apps.FormattingResults;
+
/**
* This class holds references to all the results from the FOP processing run.
*/
diff --git a/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java b/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java
index c2fc84551..629e5f1c6 100644
--- a/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java
+++ b/test/java/org/apache/fop/layoutmgr/table/TableCellLayoutManagerTestCase.java
@@ -23,6 +23,10 @@ import java.awt.Color;
import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import org.apache.fop.fo.flow.table.PrimaryGridUnit;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableCell;
@@ -37,10 +41,6 @@ import org.apache.fop.layoutmgr.PageSequenceLayoutManager;
import org.apache.fop.layoutmgr.PositionIterator;
import org.apache.fop.layoutmgr.RetrieveTableMarkerLayoutManager;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
public class TableCellLayoutManagerTestCase {
// this test aims to check that the first call to addAreas() calls
diff --git a/test/java/org/apache/fop/logging/LoggingElementListObserver.java b/test/java/org/apache/fop/logging/LoggingElementListObserver.java
index 26c4db00e..7824a6b8b 100644
--- a/test/java/org/apache/fop/logging/LoggingElementListObserver.java
+++ b/test/java/org/apache/fop/logging/LoggingElementListObserver.java
@@ -24,9 +24,10 @@ import java.util.ListIterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.layoutmgr.ElementListObserver.Observer;
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.ListElement;
-import org.apache.fop.layoutmgr.ElementListObserver.Observer;
/**
* <p>Logs all observed element lists.
diff --git a/test/java/org/apache/fop/memory/MemoryEater.java b/test/java/org/apache/fop/memory/MemoryEater.java
index 7afb80476..efe0cc489 100644
--- a/test/java/org/apache/fop/memory/MemoryEater.java
+++ b/test/java/org/apache/fop/memory/MemoryEater.java
@@ -45,7 +45,7 @@ import org.apache.fop.apps.MimeConstants;
/**
* Debug tool to create and process large FO files by replicating them a specified number of times.
*/
-public class MemoryEater {
+public final class MemoryEater {
private SAXTransformerFactory tFactory
= (SAXTransformerFactory)SAXTransformerFactory.newInstance();
@@ -53,7 +53,7 @@ public class MemoryEater {
private Stats stats;
- public MemoryEater() throws TransformerConfigurationException, MalformedURLException {
+ private MemoryEater() throws TransformerConfigurationException, MalformedURLException {
File xsltFile = new File("test/xsl/fo-replicator.xsl");
Source xslt = new StreamSource(xsltFile);
replicatorTemplates = tFactory.newTemplates(xslt);
diff --git a/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java
index 95d5c0a1d..dec62c0a4 100644
--- a/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java
+++ b/test/java/org/apache/fop/pdf/AbstractPDFStreamTestCase.java
@@ -23,10 +23,11 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Test case for {@link AbstractPDFStream}.
*/
diff --git a/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java
index a9d7bf4f6..3301fff9e 100644
--- a/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java
+++ b/test/java/org/apache/fop/pdf/FileIDGeneratorTestCase.java
@@ -19,10 +19,6 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -33,6 +29,10 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
/**
* Tests the {@link FileIDGenerator} class.
*/
@@ -96,7 +96,7 @@ public class FileIDGeneratorTestCase {
assertTrue(Arrays.equals(originalFileID, updatedFileID));
}
- private static interface TestGetter {
+ private interface TestGetter {
FileIDGenerator getSut() throws Exception;
}
diff --git a/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java
index 89d980029..21eb6088f 100644
--- a/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java
+++ b/test/java/org/apache/fop/pdf/ObjectStreamManagerTestCase.java
@@ -19,15 +19,15 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.pdf.xref.CompressedObjectReference;
public class ObjectStreamManagerTestCase {
diff --git a/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java
index 317828e4b..3512e1147 100644
--- a/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java
+++ b/test/java/org/apache/fop/pdf/ObjectStreamTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
@@ -29,6 +27,8 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
public class ObjectStreamTestCase {
private static final String OBJECT_CONTENT = "<<\n /Foo True\n /Bar False\n>>\n";
diff --git a/test/java/org/apache/fop/pdf/PDFAModeTestCase.java b/test/java/org/apache/fop/pdf/PDFAModeTestCase.java
index 352e0710e..68609575a 100644
--- a/test/java/org/apache/fop/pdf/PDFAModeTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFAModeTestCase.java
@@ -97,7 +97,7 @@ public class PDFAModeTestCase {
}
@Test
- public void checkPDFA_1a() {
+ public void checkPDFA1a() {
new PDFAModeChecker(PDFAMode.PDFA_1A)
.isEnabled()
.isPart1()
@@ -106,7 +106,7 @@ public class PDFAModeTestCase {
}
@Test
- public void checkPDFA_1b() {
+ public void checkPDFA1b() {
new PDFAModeChecker(PDFAMode.PDFA_1B)
.isEnabled()
.isPart1()
@@ -115,7 +115,7 @@ public class PDFAModeTestCase {
}
@Test
- public void checkPDFA_2a() {
+ public void checkPDFA2a() {
new PDFAModeChecker(PDFAMode.PDFA_2A)
.isEnabled()
.isNotPart1()
@@ -124,7 +124,7 @@ public class PDFAModeTestCase {
}
@Test
- public void checkPDFA_2b() {
+ public void checkPDFA2b() {
new PDFAModeChecker(PDFAMode.PDFA_2B)
.isEnabled()
.isNotPart1()
@@ -133,7 +133,7 @@ public class PDFAModeTestCase {
}
@Test
- public void checkPDFA_2u() {
+ public void checkPDFA2u() {
new PDFAModeChecker(PDFAMode.PDFA_2U)
.isEnabled()
.isNotPart1()
diff --git a/test/java/org/apache/fop/pdf/PDFArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java
index 418b2f1a9..53e9bdba0 100644
--- a/test/java/org/apache/fop/pdf/PDFArrayTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFArrayTestCase.java
@@ -19,17 +19,17 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import org.junit.Before;
import org.junit.Test;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
/**
* Test case for {@link PDFArray}.
diff --git a/test/java/org/apache/fop/pdf/PDFDestsTestCase.java b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java
index 49c1e6dab..4655b258d 100644
--- a/test/java/org/apache/fop/pdf/PDFDestsTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFDestsTestCase.java
@@ -19,13 +19,13 @@
package org.apache.fop.pdf;
-import org.junit.Before;
-import org.junit.Test;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+
/**
* Test case for {@link PDFDests}.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java
index 00224e93e..267e05c2c 100644
--- a/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFDictionaryTestCase.java
@@ -19,17 +19,18 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import org.apache.commons.io.output.CountingOutputStream;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import org.apache.commons.io.output.CountingOutputStream;
+
/**
* Test case for {@link PDFDictionary}.
diff --git a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java
index c7eff506e..880613a78 100644
--- a/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFDocumentGraphics2DTestCase.java
@@ -24,8 +24,6 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
-import junit.framework.Assert;
-
import org.junit.Test;
import org.apache.commons.io.output.ByteArrayOutputStream;
@@ -34,6 +32,8 @@ import org.apache.xmlgraphics.util.UnitConv;
import org.apache.fop.svg.PDFDocumentGraphics2D;
+import junit.framework.Assert;
+
/**
* Tests for {@link PDFDocumentGraphics2D}.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java
index 8965635b9..e58201f13 100644
--- a/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFDocumentTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import static org.junit.Assert.assertEquals;
/**
* Test case for {@link PDFDocument}
diff --git a/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java b/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java
index 34e48f1a6..2f80b077c 100644
--- a/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFEncodingTestCase.java
@@ -19,11 +19,11 @@ package org.apache.fop.pdf;
import org.junit.Test;
-import org.apache.fop.fonts.CodePointMapping;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import org.apache.fop.fonts.CodePointMapping;
+
public class PDFEncodingTestCase {
/**
diff --git a/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java
index ea3b011c7..e3f8344e0 100644
--- a/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFEncryptionJCETestCase.java
@@ -19,10 +19,6 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -43,6 +39,10 @@ import javax.crypto.spec.SecretKeySpec;
import org.junit.Test;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
/**
* Tests the {@link PDFEncryptionJCE} class.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java
index 5e4b9e2e4..edbc7e449 100644
--- a/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFFactoryTestCase.java
@@ -53,7 +53,7 @@ public class PDFFactoryTestCase {
@Override
public int[] getWidths() {
- return new int[] { 0 };
+ return new int[] {0};
}
@Override
diff --git a/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java
index 2504d871a..d1cc6273d 100644
--- a/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFFilterListTestCase.java
@@ -19,10 +19,10 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertFalse;
-
import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+
public class PDFFilterListTestCase {
@Test
diff --git a/test/java/org/apache/fop/pdf/PDFNameTestCase.java b/test/java/org/apache/fop/pdf/PDFNameTestCase.java
index 80917f416..8d7321496 100644
--- a/test/java/org/apache/fop/pdf/PDFNameTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFNameTestCase.java
@@ -22,11 +22,13 @@ package org.apache.fop.pdf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import org.apache.commons.io.output.CountingOutputStream;
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.fail;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.commons.io.output.CountingOutputStream;
/**
* Test class for {@link PDFName}.
diff --git a/test/java/org/apache/fop/pdf/PDFNullTestCase.java b/test/java/org/apache/fop/pdf/PDFNullTestCase.java
index 98427cd20..87dacc7f6 100644
--- a/test/java/org/apache/fop/pdf/PDFNullTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFNullTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import static org.junit.Assert.assertEquals;
/**
* Test case for {@link PDFNull}.
diff --git a/test/java/org/apache/fop/pdf/PDFNumberTestCase.java b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java
index ed660af8d..65f484dc7 100644
--- a/test/java/org/apache/fop/pdf/PDFNumberTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFNumberTestCase.java
@@ -19,13 +19,13 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
-import java.io.IOException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
/**
* This test tests PDFNumber's doubleOut() methods.
diff --git a/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java
index e0dca33bf..d36775cda 100644
--- a/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFNumsArrayTestCase.java
@@ -19,11 +19,11 @@
package org.apache.fop.pdf;
+import java.io.IOException;
+
import org.junit.Before;
import org.junit.Test;
-import java.io.IOException;
-
/**
* Test case for {@link PDFNumsArray}.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java
index 10ffa3b27..f35d2a15c 100644
--- a/test/java/org/apache/fop/pdf/PDFObjectTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFObjectTestCase.java
@@ -19,17 +19,17 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
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.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
/**
* Tests the PDFObject class.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java
index 24b6a1c71..ed87cd23e 100644
--- a/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFRectangleTestCase.java
@@ -19,14 +19,14 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
/**
* Test case for {@link PDFRectangle}.
*/
diff --git a/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java
index a2c6193cf..4e0e8814d 100644
--- a/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFReferenceTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertEquals;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import org.junit.Test;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
+import static org.junit.Assert.assertEquals;
/**
* Test case for {@link PDFReference}.
diff --git a/test/java/org/apache/fop/pdf/PDFStreamTestCase.java b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java
index 20e38a600..b5fb66e00 100644
--- a/test/java/org/apache/fop/pdf/PDFStreamTestCase.java
+++ b/test/java/org/apache/fop/pdf/PDFStreamTestCase.java
@@ -19,17 +19,17 @@
package org.apache.fop.pdf;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
public class PDFStreamTestCase {
private PDFStream stream;
diff --git a/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java b/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java
index a1d581402..2fa5008ed 100644
--- a/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java
+++ b/test/java/org/apache/fop/pdf/TableHeaderScopeTestCase.java
@@ -109,14 +109,14 @@ public class TableHeaderScopeTestCase {
}
private PDFDictionary scopeAttribute(Scope scope) {
- return argThat(new isScopeAttribute(scope));
+ return argThat(new IsScopeAttribute(scope));
}
- private static class isScopeAttribute extends ArgumentMatcher<PDFDictionary> {
+ private static class IsScopeAttribute extends ArgumentMatcher<PDFDictionary> {
private final Scope expectedScope;
- public isScopeAttribute(Scope expectedScope) {
+ public IsScopeAttribute(Scope expectedScope) {
this.expectedScope = expectedScope;
}
diff --git a/test/java/org/apache/fop/pdf/VersionControllerTestCase.java b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java
index 74637c91f..e14fc9502 100644
--- a/test/java/org/apache/fop/pdf/VersionControllerTestCase.java
+++ b/test/java/org/apache/fop/pdf/VersionControllerTestCase.java
@@ -19,13 +19,13 @@
package org.apache.fop.pdf;
+import org.junit.Before;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
-import org.junit.Before;
-import org.junit.Test;
-
/**
* A test class for {@link VersionController}.
diff --git a/test/java/org/apache/fop/pdf/VersionTestCase.java b/test/java/org/apache/fop/pdf/VersionTestCase.java
index 9c90f0966..dd2731d8b 100644
--- a/test/java/org/apache/fop/pdf/VersionTestCase.java
+++ b/test/java/org/apache/fop/pdf/VersionTestCase.java
@@ -19,11 +19,11 @@
package org.apache.fop.pdf;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import org.junit.Test;
-
/**
* This is a test case for ({@link Version}.
*/
diff --git a/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java
index 8b103d277..b7a326c64 100644
--- a/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java
+++ b/test/java/org/apache/fop/pdf/xref/CompressedObjectReferenceTestCase.java
@@ -19,14 +19,14 @@
package org.apache.fop.pdf.xref;
-import static org.junit.Assert.assertArrayEquals;
-
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertArrayEquals;
+
public class CompressedObjectReferenceTestCase extends ObjectReferenceTest {
@Test
diff --git a/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java
index df1b86e53..cd55577cd 100644
--- a/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java
+++ b/test/java/org/apache/fop/pdf/xref/CrossReferenceObjectTest.java
@@ -19,8 +19,6 @@
package org.apache.fop.pdf.xref;
-import static org.junit.Assert.assertArrayEquals;
-
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -32,6 +30,8 @@ import java.util.Map;
import org.junit.Before;
+import static org.junit.Assert.assertArrayEquals;
+
import org.apache.fop.pdf.PDFDocument;
import org.apache.fop.pdf.PDFInfo;
import org.apache.fop.pdf.PDFPages;
diff --git a/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java
index b147084e8..a9f506aaa 100644
--- a/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java
+++ b/test/java/org/apache/fop/pdf/xref/UncompressedObjectReferenceTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.pdf.xref;
-import static org.junit.Assert.assertArrayEquals;
-
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
@@ -28,6 +26,8 @@ import java.util.List;
import org.junit.Test;
+import static org.junit.Assert.assertArrayEquals;
+
public class UncompressedObjectReferenceTestCase extends ObjectReferenceTest {
@Test
diff --git a/test/java/org/apache/fop/render/AbstractRenderingTest.java b/test/java/org/apache/fop/render/AbstractRenderingTest.java
index 9d196e71d..297a9ba05 100644
--- a/test/java/org/apache/fop/render/AbstractRenderingTest.java
+++ b/test/java/org/apache/fop/render/AbstractRenderingTest.java
@@ -33,6 +33,7 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
+
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
diff --git a/test/java/org/apache/fop/render/RawPNGTestUtil.java b/test/java/org/apache/fop/render/RawPNGTestUtil.java
index e6660bb42..506556c66 100644
--- a/test/java/org/apache/fop/render/RawPNGTestUtil.java
+++ b/test/java/org/apache/fop/render/RawPNGTestUtil.java
@@ -28,9 +28,9 @@ 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 static final int NUM_ROWS = 32;
+ private static final int NUM_COLUMNS = 32;
+ private static final int DPI = 72;
private RawPNGTestUtil() {
@@ -83,7 +83,7 @@ public final class RawPNGTestUtil {
}
/**
- *
+ *
* @return a default ImageSize
*/
public static ImageSize getImageSize() {
diff --git a/test/java/org/apache/fop/render/RendererFactoryTestCase.java b/test/java/org/apache/fop/render/RendererFactoryTestCase.java
index 4bed835ec..1fa4ae0fa 100644
--- a/test/java/org/apache/fop/render/RendererFactoryTestCase.java
+++ b/test/java/org/apache/fop/render/RendererFactoryTestCase.java
@@ -19,13 +19,13 @@
package org.apache.fop.render;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import java.io.File;
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import org.apache.commons.io.output.NullOutputStream;
import org.apache.fop.apps.FOPException;
diff --git a/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java b/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java
index 691d75f3f..dfe956d90 100644
--- a/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java
+++ b/test/java/org/apache/fop/render/afp/AFPBorderPainterTestCase.java
@@ -19,12 +19,15 @@
package org.apache.fop.render.afp;
-import static org.junit.Assert.assertTrue;
-
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.afp.AFPBorderPainter;
import org.apache.fop.afp.AFPLineDataInfo;
import org.apache.fop.afp.AFPPaintingState;
@@ -32,8 +35,6 @@ import org.apache.fop.afp.BorderPaintingInfo;
import org.apache.fop.afp.DataStream;
import org.apache.fop.afp.Factory;
import org.apache.fop.fo.Constants;
-import org.junit.Before;
-import org.junit.Test;
public class AFPBorderPainterTestCase {
private ByteArrayOutputStream outStream;
@@ -63,12 +64,12 @@ public class AFPBorderPainterTestCase {
ds.endDocument();
assertTrue(line.getX1() == 4999 && line.getX2() == 8332);
}
-
+
class MyDataStream extends DataStream {
public MyDataStream(Factory factory, AFPPaintingState paintingState, OutputStream outputStream) {
super(factory, paintingState, outputStream);
}
-
+
public void createLine(AFPLineDataInfo lineDataInfo) {
line = lineDataInfo;
}
diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java
index 799045872..8ed54049f 100644
--- a/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/afp/AFPRendererConfigParserTestCase.java
@@ -25,6 +25,10 @@ import java.util.Map;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.apps.AFPRendererConfBuilder;
import org.apache.fop.apps.AbstractRendererConfigParserTester;
@@ -33,9 +37,6 @@ import org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions;
import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_COLOR;
import static org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions.MODE_GRAYSCALE;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
public class AFPRendererConfigParserTestCase
extends AbstractRendererConfigParserTester<AFPRendererConfBuilder, AFPRendererConfig> {
diff --git a/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java
index 115b3149a..48cf89240 100644
--- a/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java
+++ b/test/java/org/apache/fop/render/afp/AFPRendererConfiguratorTestCase.java
@@ -24,6 +24,9 @@ import java.util.Map;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+
import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceLevel.ResourceType;
import org.apache.fop.afp.AFPResourceLevelDefaults;
@@ -33,9 +36,6 @@ import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.afp.AFPRendererConfig.AFPRendererConfigParser;
import org.apache.fop.render.afp.AFPRendererConfig.ImagesModeOptions;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.verify;
-
public class AFPRendererConfiguratorTestCase extends
AbstractRendererConfiguratorTest<AFPRendererConfigurator, AFPRendererConfBuilder> {
diff --git a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java
index 78578a2b6..9e83829f8 100644
--- a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java
+++ b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java
@@ -19,20 +19,22 @@
package org.apache.fop.render.afp;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import org.apache.commons.io.IOUtils;
+
import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.parser.MODCAParser;
import org.apache.fop.afp.parser.UnparsedStructuredField;
import org.apache.fop.apps.FOUserAgent;
-import org.junit.Test;
/**
* Tests generation of afp:no-operation (NOPs).
diff --git a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java
index 04f872a84..cae184d51 100644
--- a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java
+++ b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfigParserTester.java
@@ -24,6 +24,11 @@ import java.awt.image.BufferedImage;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.apps.AbstractRendererConfigParserTester;
import org.apache.fop.apps.BitmapRendererConfBuilder;
import org.apache.fop.render.bitmap.BitmapRendererConfig.BitmapRendererConfigParser;
@@ -36,10 +41,6 @@ import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGBA;
import static org.apache.fop.render.bitmap.BitmapRendererOption.JAVA2D_TRANSPARENT_PAGE_BACKGROUND;
import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY;
import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_SPEED;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
public class AbstractBitmapRendererConfigParserTester
extends AbstractRendererConfigParserTester<BitmapRendererConfBuilder, BitmapRendererConfig> {
diff --git a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java
index 3e0c8c203..dcbb27754 100644
--- a/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java
+++ b/test/java/org/apache/fop/render/bitmap/AbstractBitmapRendererConfiguratorTest.java
@@ -23,6 +23,11 @@ import java.awt.image.BufferedImage;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
import org.apache.fop.apps.AbstractRendererConfiguratorTest;
import org.apache.fop.apps.BitmapRendererConfBuilder;
import org.apache.fop.render.intermediate.IFDocumentHandler;
@@ -35,10 +40,6 @@ import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGB;
import static org.apache.fop.render.bitmap.BitmapRendererOption.COLOR_MODE_RGBA;
import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_QUALITY;
import static org.apache.fop.render.bitmap.BitmapRendererOption.RENDERING_SPEED;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.when;
public abstract class AbstractBitmapRendererConfiguratorTest extends
AbstractRendererConfiguratorTest<BitmapRendererConfigurator, BitmapRendererConfBuilder> {
diff --git a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java
index d33076983..8a5c2a72d 100644
--- a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfigParserTestCase.java
@@ -21,16 +21,16 @@ package org.apache.fop.render.bitmap;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.xmlgraphics.image.writer.Endianness;
import org.apache.fop.apps.FopConfBuilder;
import org.apache.fop.apps.TIFFRendererConfBuilder;
import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class TIFFRendererConfigParserTestCase
extends AbstractBitmapRendererConfigParserTester {
diff --git a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java
index b5e6318ce..e340830f4 100644
--- a/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java
+++ b/test/java/org/apache/fop/render/bitmap/TIFFRendererConfiguratorTestCase.java
@@ -23,6 +23,10 @@ import java.awt.image.BufferedImage;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.xmlgraphics.image.writer.Endianness;
import org.apache.fop.apps.FopConfBuilder;
@@ -32,9 +36,6 @@ import org.apache.fop.render.bitmap.TIFFRendererConfig.TIFFRendererConfigParser;
import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T4;
import static org.apache.fop.render.bitmap.TIFFCompressionValue.CCITT_T6;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
public class TIFFRendererConfiguratorTestCase extends AbstractBitmapRendererConfiguratorTest {
diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java
index 6e48845c1..e3f892e7c 100644
--- a/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java
+++ b/test/java/org/apache/fop/render/extensions/prepress/PageBoundariesTestCase.java
@@ -19,15 +19,15 @@
package org.apache.fop.render.extensions.prepress;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
import java.awt.Dimension;
import java.awt.Rectangle;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
/**
* Tests for the fox:bleed, fox:crop-offset, fox:crop-box extension properties.
*/
diff --git a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java
index ff07e63ce..9de045cf7 100644
--- a/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java
+++ b/test/java/org/apache/fop/render/extensions/prepress/PageScaleTestCase.java
@@ -19,14 +19,14 @@
package org.apache.fop.render.extensions.prepress;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
import java.awt.geom.Point2D;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
/**
* Tests for the fox:scale extension property.
*/
diff --git a/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java b/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java
index be8b5d718..ec0f35737 100644
--- a/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java
+++ b/test/java/org/apache/fop/render/intermediate/AbstractIFPainterTestCase.java
@@ -26,15 +26,15 @@ import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.render.RenderingContext;
import org.apache.fop.traits.BorderProps;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
public class AbstractIFPainterTestCase {
private AbstractIFPainter<?> sut;
diff --git a/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java b/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java
index 61093c629..039ddcf90 100644
--- a/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java
+++ b/test/java/org/apache/fop/render/intermediate/ArcToBezierCurveTransformerTestCase.java
@@ -76,4 +76,4 @@ public class ArcToBezierCurveTransformerTestCase {
fail("Angle " + angle + " is in (0, " + Math.PI / 2 + ")");
}
}
-} \ No newline at end of file
+}
diff --git a/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java b/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java
index f0e9522d9..4a89b3ac6 100644
--- a/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java
+++ b/test/java/org/apache/fop/render/intermediate/BorderPainterTestCase.java
@@ -575,4 +575,4 @@ public class BorderPainterTestCase {
}
-} \ No newline at end of file
+}
diff --git a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java
index 4df3fe278..5546e5905 100644
--- a/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java
+++ b/test/java/org/apache/fop/render/intermediate/IFStructureTreeBuilderTestCase.java
@@ -19,14 +19,6 @@
package org.apache.fop.render.intermediate;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
@@ -36,6 +28,14 @@ import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
import org.apache.fop.fo.FOElementMapping;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.InternalElementMapping;
diff --git a/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java
index c5aad66d0..757d6620b 100644
--- a/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java
+++ b/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java
@@ -20,10 +20,6 @@
package org.apache.fop.render.intermediate;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
@@ -32,6 +28,10 @@ import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
import org.apache.fop.render.intermediate.IFStructureTreeBuilder.SAXEventRecorder;
import org.apache.fop.util.XMLUtil;
diff --git a/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java b/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java
index 00631af4b..e87c8713d 100644
--- a/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java
+++ b/test/java/org/apache/fop/render/java2d/Java2DRendererConfigParserTestcase.java
@@ -21,17 +21,14 @@ package org.apache.fop.render.java2d;
import org.junit.Test;
-import org.apache.avalon.framework.configuration.Configuration;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import org.apache.fop.apps.AbstractRendererConfigParserTester;
-import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Java2DRendererConfBuilder;
import org.apache.fop.render.java2d.Java2DRendererConfig.Java2DRendererConfigParser;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
public class Java2DRendererConfigParserTestcase
extends AbstractRendererConfigParserTester<Java2DRendererConfBuilder, Java2DRendererConfig> {
diff --git a/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java
index 113c3e2bd..caf534854 100644
--- a/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/pcl/PCLRendererConfigParserTestCase.java
@@ -21,13 +21,13 @@ package org.apache.fop.render.pcl;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.apps.AbstractRendererConfigParserTester;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser;
-import static org.junit.Assert.assertEquals;
-
public class PCLRendererConfigParserTestCase
extends AbstractRendererConfigParserTester<PCLRendererConfBuilder, PCLRendererConfig> {
diff --git a/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java
index 024104179..fc7175ad6 100644
--- a/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java
+++ b/test/java/org/apache/fop/render/pcl/PCLRendererConfiguratorTestCase.java
@@ -19,16 +19,16 @@ package org.apache.fop.render.pcl;
import org.junit.Test;
-import org.apache.fop.apps.AbstractRendererConfiguratorTest;
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
+import org.apache.fop.apps.AbstractRendererConfiguratorTest;
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.render.pcl.PCLRendererConfig.PCLRendererConfigParser;
+
public class PCLRendererConfiguratorTestCase extends
AbstractRendererConfiguratorTest<PCLRendererConfigurator, PCLRendererConfBuilder> {
diff --git a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java
index 94c842e68..b2b77e842 100644
--- a/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFAConformanceTestCase.java
@@ -21,14 +21,19 @@ package org.apache.fop.render.pdf;
import java.io.File;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
import org.junit.Test;
import org.xml.sax.SAXException;
+import static org.junit.Assert.fail;
+
import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.events.EventChecker;
+import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFConformanceException;
-
-import static org.junit.Assert.fail;
+import org.apache.fop.svg.SVGEventProducer;
/**
* Tests PDF/A-1 functionality.
@@ -108,4 +113,17 @@ public class PDFAConformanceTestCase extends BasePDFTest {
}
}
+ @Test
+ public void svgTransparency() throws Exception {
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put("pdfProfile", PDFAMode.PDFA_1B);
+ EventChecker eventChecker = new EventChecker(SVGEventProducer.class.getName()
+ + ".transparencyIgnored", params);
+ FOUserAgent ua = getUserAgent();
+ ua.getEventBroadcaster().addEventListener(eventChecker);
+ File foFile = new File(foBaseDir, "svg-transparency.fo");
+ convertFO(foFile, ua, dumpPDF);
+ eventChecker.end();
+ }
+
}
diff --git a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
index 1606bf073..6ff40b3c3 100644
--- a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
@@ -19,15 +19,14 @@
package org.apache.fop.render.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
import java.util.Calendar;
import java.util.TimeZone;
-import org.apache.fop.pdf.PDFDocument;
-import org.apache.fop.pdf.PDFInfo;
-import org.apache.fop.pdf.PDFMetadata;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
@@ -35,7 +34,10 @@ import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFAdapter;
import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
-import org.junit.Test;
+
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFInfo;
+import org.apache.fop.pdf.PDFMetadata;
/**
* Test case for PDF/A metadata handling.
diff --git a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java
index fee2c07aa..bb0f2f92e 100644
--- a/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFCMapTestCase.java
@@ -19,13 +19,14 @@
package org.apache.fop.render.pdf;
-import static org.junit.Assert.assertEquals;
-
import java.io.StringWriter;
-import org.apache.fop.pdf.CMapBuilder;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.fop.pdf.CMapBuilder;
+
/** Simple sanity test of the PDFCmap class */
public class PDFCMapTestCase {
private static final String EOL = "\n";
@@ -60,8 +61,7 @@ public class PDFCMapTestCase {
+ "end" + EOL
+ "end" + EOL
+ "%%EndResource" + EOL
- + "%%EOF" + EOL
- ;
+ + "%%EOF" + EOL;
final StringWriter w = new StringWriter();
final CMapBuilder builder = new CMapBuilder(w, "test");
diff --git a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java
index 34647818a..fc6212dcd 100644
--- a/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFEncodingTestCase.java
@@ -19,9 +19,6 @@
package org.apache.fop.render.pdf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
@@ -30,6 +27,9 @@ import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.SAXException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.apps.FOUserAgent;
/** Test that characters are correctly encoded in a generated PDF file */
diff --git a/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java
index 4f3a5e628..3130a73e7 100644
--- a/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFGraphicsPainterTestCase.java
@@ -24,12 +24,12 @@ import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
-import org.apache.fop.pdf.PDFNumber;
-
import static org.mockito.Matchers.endsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import org.apache.fop.pdf.PDFNumber;
+
public class PDFGraphicsPainterTestCase {
private PDFGraphicsPainter sut;
diff --git a/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java b/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
index f431b3ee9..db1757847 100644
--- a/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
@@ -24,17 +24,17 @@ import java.awt.Rectangle;
import org.junit.Test;
-import org.apache.fop.apps.FOUserAgent;
-import org.apache.fop.fo.Constants;
-import org.apache.fop.render.intermediate.IFContext;
-import org.apache.fop.traits.BorderProps;
-
import static org.mockito.Matchers.endsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.render.intermediate.IFContext;
+import org.apache.fop.traits.BorderProps;
+
public class PDFPainterTestCase {
@Test
diff --git a/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java
index 2d3dfb760..4dd3a6610 100644
--- a/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFRendererConfigParserTestCase.java
@@ -21,6 +21,10 @@ package org.apache.fop.render.pdf;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import org.apache.fop.apps.AbstractRendererConfigParserTester;
import org.apache.fop.apps.PDFRendererConfBuilder;
import org.apache.fop.pdf.PDFAMode;
@@ -28,10 +32,6 @@ import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.Version;
import org.apache.fop.render.pdf.PDFRendererConfig.PDFRendererConfigParser;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
public class PDFRendererConfigParserTestCase
extends AbstractRendererConfigParserTester<PDFRendererConfBuilder, PDFRendererConfig> {
diff --git a/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java b/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java
index 489d4dc96..699a8a186 100644
--- a/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFRendererOptionsConfigTestCase.java
@@ -29,6 +29,8 @@ import java.util.Map;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.pdf.PDFAMode;
import org.apache.fop.pdf.PDFEncryptionParams;
import org.apache.fop.pdf.PDFXMode;
@@ -40,7 +42,6 @@ import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
-import static org.junit.Assert.assertEquals;
public class PDFRendererOptionsConfigTestCase {
@@ -51,7 +52,7 @@ public class PDFRendererOptionsConfigTestCase {
static {
final EnumMap<PDFRendererOption, Object> props
= new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
- for(PDFRendererOption option : PDFRendererOption.values()) {
+ for (PDFRendererOption option : PDFRendererOption.values()) {
props.put(option, option.getDefaultValue());
}
DEFAULT_OPTIONS = Collections.unmodifiableMap(props);
@@ -102,7 +103,7 @@ public class PDFRendererOptionsConfigTestCase {
assertEncryptionParamsEquals(expectedEncryptionParams, actual.getEncryptionParameters());
}
- private static void assertEncryptionParamsEquals(PDFEncryptionParams expected,
+ private static void assertEncryptionParamsEquals(PDFEncryptionParams expected,
PDFEncryptionParams actual) {
assertEquals(expected == null, actual == null);
if (actual != null) {
diff --git a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java
index d084aa618..965a8e30e 100644
--- a/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFsRGBSettingsTestCase.java
@@ -19,14 +19,14 @@
package org.apache.fop.render.pdf;
-import static org.junit.Assert.fail;
-
import java.io.File;
import java.io.IOException;
import org.junit.Test;
import org.xml.sax.SAXException;
+import static org.junit.Assert.fail;
+
import org.apache.fop.apps.FOUserAgent;
/**
diff --git a/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java
index f41520bf3..e74251be1 100644
--- a/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java
+++ b/test/java/org/apache/fop/render/pdf/RenderPDFTestSuite.java
@@ -28,8 +28,6 @@ import org.junit.runners.Suite.SuiteClasses;
* A test suite for org.apache.fop.render.pdf.*
*/
@RunWith(Suite.class)
-@SuiteClasses({
- PDFRendererConfigParserTestCase.class
-})
+@SuiteClasses(PDFRendererConfigParserTestCase.class)
public final class RenderPDFTestSuite {
}
diff --git a/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java
index dcbc2d757..eb25c3f94 100644
--- a/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java
+++ b/test/java/org/apache/fop/render/ps/AbstractPostScriptTest.java
@@ -19,11 +19,11 @@
package org.apache.fop.render.ps;
-import static org.junit.Assert.assertEquals;
-
import java.io.File;
import java.io.IOException;
+import static org.junit.Assert.assertEquals;
+
import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.DSCException;
import org.apache.xmlgraphics.ps.dsc.DSCParser;
diff --git a/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java
index 458033dad..53654d76a 100644
--- a/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java
+++ b/test/java/org/apache/fop/render/ps/ImageEncoderPNGTestCase.java
@@ -27,17 +27,16 @@ 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;
+import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawPNG;
+
+import org.apache.fop.render.RawPNGTestUtil;
+
public class ImageEncoderPNGTestCase {
@Test
diff --git a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java
index ba0598b52..02e96806f 100644
--- a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java
+++ b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java
@@ -18,15 +18,15 @@
/* $Id$ */
package org.apache.fop.render.ps;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.IOUtils;
import org.apache.xmlgraphics.ps.DSCConstants;
diff --git a/test/java/org/apache/fop/render/ps/PSPainterTestCase.java b/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
index 79e5bd9b6..b678fdb4b 100644
--- a/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
+++ b/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
@@ -146,11 +146,11 @@ public class PSPainterTestCase {
int y = 100000;
int letterSpacing = 0;
int wordSpacing = 0;
- int dp[][] = {{100, 100, 0, 0}, null, null, {200, 200, -100, -100}};
- double X = (x + dp[0][0]) / 1000.0;
- double Y = (y - dp[0][1]) / 1000.0;
- when(psGenerator.formatDouble(X)).thenReturn("100.100");
- when(psGenerator.formatDouble(Y)).thenReturn("99.900");
+ int[][] dp = {{100, 100, 0, 0}, null, null, {200, 200, -100, -100}};
+ double xAsDouble = (x + dp[0][0]) / 1000.0;
+ double yAsDouble = (y - dp[0][1]) / 1000.0;
+ when(psGenerator.formatDouble(xAsDouble)).thenReturn("100.100");
+ when(psGenerator.formatDouble(yAsDouble)).thenReturn("99.900");
String text = "Hello Mock!";
try {
psPainter.drawText(x, y, letterSpacing, wordSpacing, dp, text);
diff --git a/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java
index fe59143b4..45642764c 100644
--- a/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/ps/PSRendererConfigParserTestCase.java
@@ -21,14 +21,14 @@ package org.apache.fop.render.ps;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.fop.apps.AbstractRendererConfigParserTester;
import org.apache.fop.apps.PSRendererConfBuilder;
import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser;
-import static org.junit.Assert.assertEquals;
-
public class PSRendererConfigParserTestCase
extends AbstractRendererConfigParserTester<PSRendererConfBuilder, PSRendererConfig> {
diff --git a/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java b/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java
index 4d42a0aab..67ba24763 100644
--- a/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java
+++ b/test/java/org/apache/fop/render/ps/PSRendererConfiguratorTestCase.java
@@ -19,16 +19,16 @@ package org.apache.fop.render.ps;
import org.junit.Test;
-import org.apache.fop.apps.AbstractRendererConfiguratorTest;
-import org.apache.fop.apps.MimeConstants;
-import org.apache.fop.apps.PSRendererConfBuilder;
-import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
+import org.apache.fop.apps.AbstractRendererConfiguratorTest;
+import org.apache.fop.apps.MimeConstants;
+import org.apache.fop.apps.PSRendererConfBuilder;
+import org.apache.fop.render.ps.PSRendererConfig.PSRendererConfigParser;
+
public class PSRendererConfiguratorTestCase extends
AbstractRendererConfiguratorTest<PSRendererConfigurator, PSRendererConfBuilder> {
private PSRenderingUtil psUtil;
diff --git a/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java b/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java
index 3f1088fe1..0a2c895be 100644
--- a/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java
+++ b/test/java/org/apache/fop/render/ps/PSRenderingUtilTestCase.java
@@ -23,13 +23,13 @@ import java.io.IOException;
import org.junit.Test;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
import org.apache.xmlgraphics.ps.PSGenerator;
import org.apache.fop.render.ps.extensions.PSPageTrailerCodeBefore;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
public class PSRenderingUtilTestCase {
private final String content = "<< /MyEntry 0 >> command";
diff --git a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java
index bfdb5f968..4f06938d2 100644
--- a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java
+++ b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java
@@ -19,11 +19,6 @@
package org.apache.fop.render.ps;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -33,6 +28,11 @@ import java.util.Set;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import org.apache.commons.io.IOUtils;
import org.apache.xmlgraphics.ps.DSCConstants;
diff --git a/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java b/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java
index b48da4186..29a3a7bd3 100644
--- a/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java
+++ b/test/java/org/apache/fop/render/ps/svg/PSSVGGraphics2DTestCase.java
@@ -29,6 +29,8 @@ import java.io.IOException;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.commons.io.FileUtils;
import org.apache.batik.ext.awt.RadialGradientPaint;
@@ -36,8 +38,6 @@ import org.apache.batik.ext.awt.RadialGradientPaint;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.ps.PSGenerator;
-import static org.junit.Assert.assertEquals;
-
public class PSSVGGraphics2DTestCase {
float cx = 841.891f;
diff --git a/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java b/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java
index 283d3f4ad..3a6db4396 100644
--- a/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java
+++ b/test/java/org/apache/fop/render/ps/svg/PSSVGLinearGraphics2DTestCase.java
@@ -29,6 +29,8 @@ import java.io.IOException;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.commons.io.FileUtils;
import org.apache.batik.ext.awt.LinearGradientPaint;
@@ -36,13 +38,11 @@ import org.apache.batik.ext.awt.LinearGradientPaint;
import org.apache.xmlgraphics.java2d.GraphicContext;
import org.apache.xmlgraphics.ps.PSGenerator;
-import static org.junit.Assert.assertEquals;
-
public class PSSVGLinearGraphics2DTestCase {
float startX = 115f;
float endX = 15f;
float startY = 285f;
- float endY=15f;
+ float endY = 15f;
float[] fractions = {0.0f, 1.0f};
/**
diff --git a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java
index c5821fff1..4c3c8446e 100644
--- a/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java
+++ b/test/java/org/apache/fop/render/rtf/Bug39607TestCase.java
@@ -21,13 +21,14 @@ package org.apache.fop.render.rtf;
import java.io.StringWriter;
+import org.junit.Test;
+
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
-import org.junit.Test;
/**
* Test for http://issues.apache.org/bugzilla/show_bug.cgi?id=39607
diff --git a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java
index d8296fc33..5b294bd9b 100644
--- a/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java
+++ b/test/java/org/apache/fop/render/rtf/RichTextFormatTestSuite.java
@@ -27,6 +27,6 @@ import org.junit.runners.Suite.SuiteClasses;
* Test suite for FOP's RTF library.
*/
@RunWith(Suite.class)
-@SuiteClasses({ Bug39607TestCase.class })
+@SuiteClasses(Bug39607TestCase.class)
public class RichTextFormatTestSuite {
}
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java
index 07085059d..9df1c26ef 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/BasicLink.java
@@ -27,17 +27,15 @@
package org.apache.fop.render.rtf.rtflib.testdocs;
+import java.io.IOException;
+
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink;
-
-import java.io.IOException;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/**
* Class <code>BasicLink</code> here.
- *
- * @author <a href="mailto:mks@ANDREAS">Andreas Putz</a>
*/
public class BasicLink extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java
index 16460cd1c..7f17514ef 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/CreateTestDocuments.java
@@ -29,11 +29,8 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.File;
import java.io.IOException;
-//import org.apache.fop.render.rtf.rtflib.jfor.main.JForVersionInfo;
/** Create test RTF documents from classes found in this package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
- * @author Andreas Putz a.putz@skynamics.com
*/
public class CreateTestDocuments {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java
index 3329b26b9..1af4c7bed 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/DummyTableColumnsInfo.java
@@ -33,8 +33,6 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableColumnsInfo;
* to create documents without worrying about nested tables handling.
* Might need to be replaced by more complete version in some sample
* documents created by this package.
- *
- * @author bdelacretaz@codeconsult.ch
*/
class DummyTableColumnsInfo implements ITableColumnsInfo {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java
index b957bc1fa..1127f3e72 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ExternalGraphic.java
@@ -27,16 +27,14 @@
package org.apache.fop.render.rtf.rtflib.testdocs;
+import java.io.IOException;
+
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
-
-import java.io.IOException;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/**
* Generate a test document containing external graphics.
- *
- * @author <a href="mailto:a.putz@skynamics.com">Andreas Putz</a>
*/
class ExternalGraphic extends TestDocument {
private String file = "file:///tmp/jfor-images/logo.";
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java
index 3ce05c606..6f4e27a59 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ListInTable.java
@@ -30,13 +30,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
/** Generates a simple RTF test document for the jfor rtflib package.
*/
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java
index f1817bf03..9be5e899a 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/MergedTableCells.java
@@ -32,11 +32,10 @@ import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
/** Generates an RTF test document containing merged table cells
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class MergedTableCells extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java
index 72dad7e98..c11fbc334 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/NestedTable.java
@@ -30,14 +30,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
/** Generates an RTF document to test nested tables with the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class NestedTable extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java
index 2b38aa789..edce3264a 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/ParagraphAlignment.java
@@ -27,14 +27,13 @@
package org.apache.fop.render.rtf.rtflib.testdocs;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
/** Generates a simple RTF test document for the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
public class ParagraphAlignment extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java
index 2ca16c0e5..ca6ce79bc 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleDocument.java
@@ -30,11 +30,10 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/** Generates a simple RTF test document for the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class SimpleDocument
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java
index eff3aa7ff..e817f6a13 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleLists.java
@@ -30,15 +30,14 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListStyle;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListStyleNumber;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/** Generates a simple RTF test document for the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class SimpleLists extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java
index cf84b3ec4..10ddc11e7 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/SimpleTable.java
@@ -32,11 +32,10 @@ import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableRow;
/** Generates a simple RTF test document for the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class SimpleTable extends TestDocument {
/** generate the body of the test document */
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java
index 5274dc32e..266903766 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TestDocument.java
@@ -27,19 +27,17 @@
package org.apache.fop.render.rtf.rtflib.testdocs;
-import java.util.Date;
import java.io.File;
-import java.io.IOException;
import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Date;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfFile;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
-//import org.apache.fop.render.rtf.rtflib.jfor.main.JForVersionInfo;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/** Base class for generating RTF documents used to test the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
abstract class TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java
index 4ab48acb0..bb0614cee 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/TextAttributes.java
@@ -29,14 +29,13 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfText;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
/** Generates a simple RTF test document for the jfor rtflib package.
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class TextAttributes extends TestDocument {
diff --git a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java
index 4359822f6..a206e014f 100644
--- a/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java
+++ b/test/java/org/apache/fop/render/rtf/rtflib/testdocs/Whitespace.java
@@ -30,11 +30,10 @@ package org.apache.fop.render.rtf.rtflib.testdocs;
import java.io.IOException;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfDocumentArea;
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfParagraph;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
/** Generates an RTF document to test the WhitespaceCollapser
- * @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
*/
class Whitespace extends TestDocument {
diff --git a/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java b/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java
index a7ae52c65..30fed05ea 100644
--- a/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java
+++ b/test/java/org/apache/fop/render/txt/TxtRendererConfigParserTestCase.java
@@ -21,13 +21,12 @@ package org.apache.fop.render.txt;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.fop.apps.AbstractRendererConfigParserTester;
import org.apache.fop.apps.TxtRendererConfBuilder;
-import org.apache.fop.render.RendererConfig.RendererConfigParser;
-import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererOption;
import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererConfigParser;
-
-import static org.junit.Assert.assertEquals;
+import org.apache.fop.render.txt.TxtRendererConfig.TxtRendererOption;
public class TxtRendererConfigParserTestCase
extends AbstractRendererConfigParserTester<TxtRendererConfBuilder, TxtRendererConfig> {
diff --git a/test/java/org/apache/fop/svg/NativeTextPainterTest.java b/test/java/org/apache/fop/svg/NativeTextPainterTest.java
new file mode 100644
index 000000000..1c2c3b582
--- /dev/null
+++ b/test/java/org/apache/fop/svg/NativeTextPainterTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.io.File;
+import java.io.IOException;
+
+import org.w3c.dom.Document;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.TextPainter;
+
+import org.apache.fop.apps.FOUserAgent;
+import org.apache.fop.apps.FopFactory;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.base14.Base14FontCollection;
+import org.apache.fop.svg.font.FOPFontFamilyResolverImpl;
+
+abstract class NativeTextPainterTest {
+
+ protected final void runTest(String testcase, OperatorValidator validator) throws Exception {
+ FontInfo fontInfo = createFontInfo();
+ BridgeContext bridgeContext = createBridgeContext(fontInfo);
+ GraphicsNode svg = loadSVG(bridgeContext, testcase);
+ Graphics2D g2d = createGraphics2D(fontInfo, validator);
+ svg.paint(g2d);
+ validator.end();
+ }
+
+ private FontInfo createFontInfo() {
+ FontInfo fontInfo = new FontInfo();
+ new Base14FontCollection(true).setup(0, fontInfo);
+ return fontInfo;
+ }
+
+ private BridgeContext createBridgeContext(FontInfo fontInfo) {
+ FOUserAgent userAgent = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+ SVGUserAgent svgUserAgent = new SVGUserAgent(userAgent, new FOPFontFamilyResolverImpl(fontInfo),
+ new AffineTransform());
+ BridgeContext bridgeContext = new BridgeContext(svgUserAgent);
+ bridgeContext.setTextPainter(createTextPainter(fontInfo));
+ return bridgeContext;
+ }
+
+ protected abstract TextPainter createTextPainter(FontInfo fontInfo);
+
+ private GraphicsNode loadSVG(BridgeContext bridgeContext, String resourceName) throws IOException {
+ SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(null);
+ Document svg = factory.createDocument(null, getClass().getResourceAsStream(resourceName));
+ GVTBuilder builder = new GVTBuilder();
+ return builder.build(bridgeContext, svg);
+ }
+
+ protected abstract Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator);
+
+}
diff --git a/test/java/org/apache/fop/svg/OperatorValidator.java b/test/java/org/apache/fop/svg/OperatorValidator.java
new file mode 100644
index 000000000..e94c8e404
--- /dev/null
+++ b/test/java/org/apache/fop/svg/OperatorValidator.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+class OperatorValidator {
+
+ private interface Match {
+
+ boolean match(String line);
+ }
+
+ private static class MatchSequence implements OperatorValidator.Match {
+
+ private final Queue<OperatorValidator.Match> expectedMatches = new LinkedList<OperatorValidator.Match>();
+
+ private OperatorValidator.Match currentMatch;
+
+ private static final OperatorValidator.Match FINAL_MATCH = new Match() {
+
+ public boolean match(String line) {
+ return false;
+ }
+ };
+
+ public boolean isExhausted() {
+ return currentMatch == FINAL_MATCH;
+ }
+
+ public void addMatch(OperatorValidator.Match match) {
+ if (currentMatch == null) {
+ currentMatch = match;
+ } else {
+ expectedMatches.add(match);
+ }
+ }
+
+ public boolean match(String line) {
+ boolean match = currentMatch.match(line);
+ if (match) {
+ if (expectedMatches.isEmpty()) {
+ currentMatch = FINAL_MATCH;
+ } else {
+ currentMatch = expectedMatches.remove();
+ }
+ }
+ return match;
+ }
+ }
+
+ private static class OperatorMatch implements OperatorValidator.Match {
+
+ final String operator;
+
+ final String line;
+
+ OperatorMatch(String operator, String line) {
+ this.operator = operator;
+ this.line = line;
+ }
+
+ public boolean match(String line) {
+ if (line.contains(operator)) {
+ assertEquals(this.line, line);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private final OperatorValidator.MatchSequence matchSequence = new MatchSequence();
+
+ public OperatorValidator addOperatorMatch(String operator, String expectedLine) {
+ matchSequence.addMatch(new OperatorMatch(operator, expectedLine));
+ return this;
+ }
+
+ public void check(String line) {
+ matchSequence.match(line);
+ }
+
+ public void end() {
+ assertTrue("Expected operators remain", matchSequence.isExhausted());
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java b/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java
new file mode 100644
index 000000000..e7e47e7ba
--- /dev/null
+++ b/test/java/org/apache/fop/svg/PDFTextPainterTestCase.java
@@ -0,0 +1,148 @@
+/*
+ * 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.Graphics2D;
+import java.io.StringWriter;
+
+import org.junit.Test;
+
+import org.apache.batik.gvt.TextPainter;
+
+import org.apache.xmlgraphics.java2d.GraphicContext;
+
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.pdf.PDFDocument;
+
+public class PDFTextPainterTestCase extends NativeTextPainterTest {
+
+ private static class OperatorCheckingPDFGraphics2D extends PDFGraphics2D {
+
+ OperatorCheckingPDFGraphics2D(FontInfo fontInfo, final OperatorValidator validator) {
+ super(false, fontInfo, new PDFDocument("test"), null, null, null, 0, null);
+ this.currentStream = new StringWriter() {
+
+ @Override
+ public void write(String str) {
+ validator.check(str);
+ }
+
+ };
+ }
+ }
+
+ @Override
+ protected TextPainter createTextPainter(FontInfo fontInfo) {
+ return new PDFTextPainter(fontInfo);
+ }
+
+ @Override
+ protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) {
+ PDFGraphics2D g2d = new OperatorCheckingPDFGraphics2D(fontInfo, validator);
+ g2d.setGraphicContext(new GraphicContext());
+ return g2d;
+ }
+
+ @Test
+ public void testRotatedGlyph() throws Exception {
+ runTest("rotated-glyph.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm ")
+ .addOperatorMatch("TJ", "[(A)] TJ\n")
+ .addOperatorMatch("Tm", "0.70710677 0.7071068 0.7071068 -0.70710677 106.69999695 110 Tm ")
+ .addOperatorMatch("TJ", "[(B)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 173.3999939 110 Tm ")
+ .addOperatorMatch("TJ", "[(C)] TJ\n"));
+ }
+
+ @Test
+ public void testDxDy() throws Exception {
+ runTest("dx-dy.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "1 0 0 -1 55 35 Tm ")
+ .addOperatorMatch("TJ", "[(ABCDE)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 55 75 Tm ")
+ .addOperatorMatch("TJ", "[(A)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 69 85 Tm ")
+ .addOperatorMatch("TJ", "[(B)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 109 80 Tm ")
+ .addOperatorMatch("TJ", "[(C)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 91 65 Tm ")
+ .addOperatorMatch("TJ", "[(D)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 127 75 Tm ")
+ .addOperatorMatch("TJ", "[(E)] TJ\n"));
+ }
+
+ @Test
+ public void testSpacing() throws Exception {
+ runTest("spacing.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
+ .addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
+ .addOperatorMatch("TJ", "[(V) 80 (A) 70 (V)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
+ .addOperatorMatch("TJ", "[(V) -20 (A) -30 (V)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
+ .addOperatorMatch("TJ", "[(ab) -111 ( ) -389 (cd)] TJ\n"));
+ }
+
+ @Test
+ public void testGlyphOrientation() throws Exception {
+ runTest("glyph-orientation.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "0 1 1 0 738.5 0 Tm ")
+ .addOperatorMatch("TJ", "[(A)] TJ\n")
+ .addOperatorMatch("Tm", "0 1 1 0 738.5 667 Tm ")
+ .addOperatorMatch("TJ", "[(B)] TJ\n")
+ .addOperatorMatch("Tm", "0 1 1 0 738.5 1334 Tm ")
+ .addOperatorMatch("TJ", "[(C)] TJ\n")
+ .addOperatorMatch("Tm", "0 1 1 0 738.5 2056 Tm ")
+ .addOperatorMatch("TJ", "[(D)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 2149 718 Tm ")
+ .addOperatorMatch("TJ", "[(E)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 2165.5 1643 Tm ")
+ .addOperatorMatch("TJ", "[(F)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 2124 2568 Tm ")
+ .addOperatorMatch("TJ", "[(G)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 2138.5 3493 Tm ")
+ .addOperatorMatch("TJ", "[(H)] TJ\n")
+ .addOperatorMatch("Tm", "0 -1 -1 0 718 5000 Tm ")
+ .addOperatorMatch("TJ", "[(I)] TJ\n")
+ .addOperatorMatch("Tm", "0 -1 -1 0 1643 5000 Tm ")
+ .addOperatorMatch("TJ", "[(J)] TJ\n")
+ .addOperatorMatch("Tm", "0 -1 -1 0 2568 5000 Tm ")
+ .addOperatorMatch("TJ", "[(K)] TJ\n")
+ .addOperatorMatch("Tm", "0 -1 -1 0 3493 5000 Tm ")
+ .addOperatorMatch("TJ", "[(L)] TJ\n"));
+ }
+
+ @Test
+ public void testBaselineShift() throws Exception {
+ runTest("baseline-shift.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "1 0 0 -1 0 0 Tm ")
+ .addOperatorMatch("TJ", "[(AB)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 1334 -462.5 Tm ")
+ .addOperatorMatch("TJ", "[(CD)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 2778 0 Tm ")
+ .addOperatorMatch("TJ", "[(EF)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 4056 462.5 Tm ")
+ .addOperatorMatch("TJ", "[(GH)] TJ\n")
+ .addOperatorMatch("Tm", "1 0 0 -1 5556 0 Tm ")
+ .addOperatorMatch("TJ", "[(IJ)] TJ\n"));
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/PSTextPainterTestCase.java b/test/java/org/apache/fop/svg/PSTextPainterTestCase.java
new file mode 100644
index 000000000..2d5de7455
--- /dev/null
+++ b/test/java/org/apache/fop/svg/PSTextPainterTestCase.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.svg;
+
+import java.awt.Graphics2D;
+import java.io.IOException;
+
+import org.junit.Test;
+
+import org.apache.commons.io.output.NullOutputStream;
+
+import org.apache.batik.gvt.TextPainter;
+
+import org.apache.xmlgraphics.java2d.GraphicContext;
+import org.apache.xmlgraphics.java2d.ps.PSGraphics2D;
+import org.apache.xmlgraphics.ps.PSGenerator;
+
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.render.ps.PSTextPainter;
+
+public class PSTextPainterTestCase extends NativeTextPainterTest {
+
+ private static class OperatorCheckingPSGraphics2D extends PSGraphics2D {
+
+ OperatorCheckingPSGraphics2D(FontInfo fontInfo, final OperatorValidator validator) {
+ super(false, new PSGenerator(new NullOutputStream()) {
+
+ @Override
+ public void writeln(String cmd) throws IOException {
+ validator.check(cmd);
+ }
+
+ });
+ }
+ }
+
+ @Override
+ protected TextPainter createTextPainter(FontInfo fontInfo) {
+ return new PSTextPainter(fontInfo);
+ }
+
+ @Override
+ protected Graphics2D createGraphics2D(FontInfo fontInfo, OperatorValidator validator) {
+ PSGraphics2D g2d = new OperatorCheckingPSGraphics2D(fontInfo, validator);
+ g2d.setGraphicContext(new GraphicContext());
+ return g2d;
+ }
+
+ @Test
+ public void testRotatedGlyph() throws Exception {
+ runTest("rotated-glyph.svg", new OperatorValidator()
+ .addOperatorMatch("Tm", "1 0 0 -1 40 110 Tm")
+ .addOperatorMatch("xshow", "(A)\n[0] xshow")
+ .addOperatorMatch("Tm", "0.70711 0.70711 0.70711 -0.70711 106.7 110 Tm")
+ .addOperatorMatch("xshow", "(B)\n[0] xshow")
+ .addOperatorMatch("Tm", "1 0 0 -1 173.39999 110 Tm")
+ .addOperatorMatch("xshow", "(C)\n[0] xshow"));
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/baseline-shift.svg b/test/java/org/apache/fop/svg/baseline-shift.svg
new file mode 100644
index 000000000..0f375b9af
--- /dev/null
+++ b/test/java/org/apache/fop/svg/baseline-shift.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<svg width="150" height="60" xmlns="http://www.w3.org/2000/svg">
+<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/>
+<g transform="translate(10, 40) scale(20) scale(0.001)">
+<text font-family="sans-serif" font-size="1000">
+AB<tspan baseline-shift="super">CD</tspan>EF<tspan baseline-shift="sub">GH</tspan>IJ
+</text>
+</g>
+</svg>
diff --git a/test/java/org/apache/fop/svg/dx-dy.svg b/test/java/org/apache/fop/svg/dx-dy.svg
new file mode 100644
index 000000000..cfdc2de01
--- /dev/null
+++ b/test/java/org/apache/fop/svg/dx-dy.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
+<rect x="0" y="0" width="100%" height="100%" stroke="black" stroke-width="2" fill="none"/>
+<g font-family="monospace" font-size="30">
+ <text x="55" y="35">ABCDE</text>
+ <text x="55" y="75" dx="0 -4 22 -36 18" dy="0 10 -5 -15 10">ABCDE</text>
+</g>
+</svg>
diff --git a/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java b/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java
new file mode 100644
index 000000000..c6f062a84
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/BasicGlyphVectorTestCase.java
@@ -0,0 +1,193 @@
+/*
+ * 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.font;
+
+import java.awt.Rectangle;
+import java.awt.font.GlyphMetrics;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.batik.gvt.font.GVTGlyphMetrics;
+import org.apache.batik.gvt.font.GVTLineMetrics;
+
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontMetrics;
+
+/**
+ * Tests all the methods of {@link FOPGVTGlyphVector} with a mocked font.
+ */
+public class BasicGlyphVectorTestCase extends FOPGVTGlyphVectorTest {
+
+ private final int fontSize = 10000;
+
+ @Before
+ public void createGlyphVector() {
+ FontMetrics metrics = mockFontMetrics();
+ Font font = mockFont(metrics);
+ FOPGVTFont gvtFont = mockGVTFont(font);
+ CharacterIterator it = new StringCharacterIterator("ABC");
+ glyphVector = new FOPGVTGlyphVector(gvtFont, it, null);
+ glyphVector.performDefaultLayout();
+ }
+
+ private FontMetrics mockFontMetrics() {
+ FontMetrics metrics = mock(FontMetrics.class);
+ when(metrics.getAscender(eq(fontSize))).thenReturn(8000000);
+ when(metrics.getDescender(eq(fontSize))).thenReturn(-4000000);
+ when(metrics.getWidth(eq(1), eq(fontSize))).thenReturn(10000000);
+ when(metrics.getBoundingBox(eq(1), eq(fontSize))).thenReturn(
+ new Rectangle(-1000000, -2000000, 3000000, 4000000));
+ when(metrics.getWidth(eq(2), eq(fontSize))).thenReturn(11000000);
+ when(metrics.getBoundingBox(eq(2), eq(fontSize))).thenReturn(
+ new Rectangle(-5000000, -6000000, 7000000, 9000000));
+ when(metrics.getWidth(eq(3), eq(fontSize))).thenReturn(12000000);
+ when(metrics.getBoundingBox(eq(3), eq(fontSize))).thenReturn(
+ new Rectangle(-9000000, -10000000, 11000000, 14000000));
+ return metrics;
+ }
+
+ private Font mockFont(FontMetrics metrics) {
+ Font font = mock(Font.class);
+ when(font.getFontMetrics()).thenReturn(metrics);
+ when(font.getFontSize()).thenReturn(fontSize);
+ when(font.mapChar(eq('A'))).thenReturn((char) 1);
+ when(font.mapChar(eq('B'))).thenReturn((char) 2);
+ when(font.mapChar(eq('C'))).thenReturn((char) 3);
+ return font;
+ }
+
+ private FOPGVTFont mockGVTFont(Font font) {
+ FOPGVTFont gvtFont = mock(FOPGVTFont.class);
+ when(gvtFont.getFont()).thenReturn(font);
+ when(gvtFont.getLineMetrics(anyInt())).thenReturn(
+ new GVTLineMetrics(8, 0, null, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0));
+ return gvtFont;
+ }
+
+ @Test
+ public void getGlyphCodeReturnsGlyphIndex() {
+ assertEquals(1, glyphVector.getGlyphCode(0));
+ assertEquals(2, glyphVector.getGlyphCode(1));
+ assertEquals(3, glyphVector.getGlyphCode(2));
+ }
+
+ @Test
+ public void testGetGlyphCodes() {
+ assertArrayEquals(new int[] {1, 2, 3}, glyphVector.getGlyphCodes(0, 3, null));
+ assertArrayEquals(new int[] {2, 3}, glyphVector.getGlyphCodes(1, 2, null));
+ }
+
+ @Test
+ public void testGetGlyphMetrics() {
+ assertGlyphMetricsEqual(new GVTGlyphMetrics(10, 12, new Rectangle(-1, -2, 3, 4), GlyphMetrics.STANDARD),
+ glyphVector.getGlyphMetrics(0));
+ assertGlyphMetricsEqual(new GVTGlyphMetrics(11, 12, new Rectangle(-5, -3, 7, 9), GlyphMetrics.STANDARD),
+ glyphVector.getGlyphMetrics(1));
+ assertGlyphMetricsEqual(new GVTGlyphMetrics(12, 12, new Rectangle(-9, -4, 11, 14), GlyphMetrics.STANDARD),
+ glyphVector.getGlyphMetrics(2));
+ }
+
+ private void assertGlyphMetricsEqual(GVTGlyphMetrics expected, GVTGlyphMetrics actual) {
+ assertEquals(expected.getHorizontalAdvance(), actual.getHorizontalAdvance(), 0);
+ assertEquals(expected.getVerticalAdvance(), actual.getVerticalAdvance(), 0);
+ assertEquals(expected.getBounds2D(), actual.getBounds2D());
+ assertEquals(expected.getLSB(), actual.getLSB(), 0);
+ assertEquals(expected.getRSB(), actual.getRSB(), 0);
+ assertEquals(expected.getType(), actual.getType());
+ assertEquals(expected.isCombining(), actual.isCombining());
+ assertEquals(expected.isComponent(), actual.isComponent());
+ assertEquals(expected.isLigature(), actual.isLigature());
+ assertEquals(expected.isStandard(), actual.isStandard());
+ assertEquals(expected.isWhitespace(), actual.isWhitespace());
+ }
+
+ @Test
+ public void testGetGlyphPosition() {
+ assertEquals(new Point2D.Float(0, 0), glyphVector.getGlyphPosition(0));
+ assertEquals(new Point2D.Float(10, 0), glyphVector.getGlyphPosition(1));
+ assertEquals(new Point2D.Float(21, 0), glyphVector.getGlyphPosition(2));
+ assertEquals(new Point2D.Float(33, 0), glyphVector.getGlyphPosition(3));
+ }
+
+ @Test
+ public void testGetGlyphPositions() {
+ float[] expectedPositions = new float[] {0, 0, 10, 0, 21, 0, 33, 0};
+ assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, null), 0);
+ assertArrayEquals(expectedPositions, glyphVector.getGlyphPositions(0, 4, new float[8]), 0);
+ }
+
+ @Test
+ public void testGetGlyphOutline() {
+ assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphOutline(0).getBounds());
+ assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphOutline(1).getBounds());
+ assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphOutline(2).getBounds());
+ }
+
+ @Test
+ public void testGetOutline() {
+ assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getOutline().getBounds());
+ }
+
+ @Test
+ public void testGetLogicalBounds() {
+ assertEquals(new Rectangle(0, -8, 33, 12), glyphVector.getLogicalBounds());
+ }
+
+ @Test
+ public void testGetLogicalBoundsRotated() {
+ for (int i = 0; i < 3; i++) {
+ glyphVector.setGlyphTransform(i, new AffineTransform(0.7, 0.7, -0.7, 0.7, 0, 0));
+ }
+ assertEquals(new Rectangle2D.Float(-2.8f, -5.6f, 37.8f, 16.8f), glyphVector.getLogicalBounds());
+ }
+
+ @Test
+ public void testGetBounds() {
+ assertEquals(new Rectangle(-1, -4, 24, 14), glyphVector.getBounds2D(null));
+ }
+
+ @Test
+ public void testGetGlyphVisualBounds() {
+ assertEquals(new Rectangle(-1, -2, 3, 4), glyphVector.getGlyphVisualBounds(0).getBounds());
+ assertEquals(new Rectangle(5, -3, 7, 9), glyphVector.getGlyphVisualBounds(1).getBounds());
+ assertEquals(new Rectangle(12, -4, 11, 14), glyphVector.getGlyphVisualBounds(2).getBounds());
+ }
+
+ @Test
+ public void testGetGlyphLogicalBounds() {
+ assertEquals(new Rectangle(0, -8, 10, 12), glyphVector.getGlyphLogicalBounds(0).getBounds());
+ assertEquals(new Rectangle(10, -8, 11, 12), glyphVector.getGlyphLogicalBounds(1).getBounds());
+ assertEquals(new Rectangle(21, -8, 12, 12), glyphVector.getGlyphLogicalBounds(2).getBounds());
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java b/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java
new file mode 100644
index 000000000..d14752b90
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/FOPFontFamilyResolverTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * 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.font;
+
+import java.awt.FontFormatException;
+import java.awt.GraphicsEnvironment;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.batik.gvt.font.GVTFontFamily;
+import org.apache.batik.gvt.font.GVTLineMetrics;
+
+import org.apache.fop.fonts.FontInfo;
+
+public class FOPFontFamilyResolverTestCase {
+
+ private static FontInfo fontInfo;
+
+ private FOPFontFamilyResolver resolver;
+
+ @BeforeClass
+ public static void setUpFontInfo() {
+ fontInfo = new FontInfoBuilder()
+ .useDejaVuLGCSerif()
+ .useDroidSansMono()
+ .build();
+ }
+
+ @Before
+ public void createFontFamilyResolver() {
+ resolver = new FOPFontFamilyResolverImpl(fontInfo);
+ }
+
+ @Test
+ public void testResolve() {
+ assertNull(resolver.resolve("Unavailable"));
+ assertNotNull(resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF));
+ }
+
+ @Test
+ public void testGetFamilyThatCanDisplay() {
+ GVTFontFamily family = resolver.getFamilyThatCanDisplay('\u0180');
+ assertEquals(FontInfoBuilder.DEJAVU_LGC_SERIF, family.getFamilyName());
+ family = resolver.getFamilyThatCanDisplay('\u02F3');
+ assertEquals(FontInfoBuilder.DROID_SANS_MONO, family.getFamilyName());
+ family = resolver.getFamilyThatCanDisplay('\u02DF');
+ assertNull(family);
+ }
+
+ @Test
+ public void testDeriveFont() {
+ FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
+ FOPGVTFont font = family.deriveFont(10, Collections.emptyMap());
+ assertEquals(10, font.getSize(), 0);
+ assertTrue(font.canDisplay('\u01F6'));
+ assertFalse(font.canDisplay('\u01F7'));
+ }
+
+ @Test
+ @Ignore("FOP metrics don't match AWT, but not sure who is right and who is wrong")
+ public void testLineMetrics() throws FontFormatException, IOException {
+ FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
+ FOPGVTFont font = family.deriveFont(10, Collections.emptyMap());
+ GVTLineMetrics fopMetrics = font.getLineMetrics("", null);
+ LineMetrics awtMetrics = getAWTLineMetrics();
+ printDifference("Ascent", awtMetrics.getAscent(), fopMetrics.getAscent());
+ printDifference("Descent", awtMetrics.getDescent(), fopMetrics.getDescent());
+ printDifference("Height", awtMetrics.getHeight(), fopMetrics.getHeight());
+ printDifference("Leading", awtMetrics.getLeading(), fopMetrics.getLeading());
+ printDifference("StrikethroughOffset", awtMetrics.getStrikethroughOffset(),
+ fopMetrics.getStrikethroughOffset());
+ printDifference("StrikethroughThickness", awtMetrics.getStrikethroughThickness(),
+ fopMetrics.getStrikethroughThickness());
+ printDifference("UnderlineOffset", awtMetrics.getUnderlineOffset(),
+ fopMetrics.getUnderlineOffset());
+ printDifference("UnderlineThickness", awtMetrics.getUnderlineThickness(),
+ fopMetrics.getUnderlineThickness());
+ }
+
+ private LineMetrics getAWTLineMetrics() throws FontFormatException, IOException {
+ File fontFile = new File("test/resources/fonts/ttf/DejaVuLGCSerif.ttf");
+ java.awt.Font awtFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile).deriveFont(10f);
+ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ BufferedImage dummyImage = new BufferedImage(1000, 1000, BufferedImage.TYPE_INT_RGB);
+ FontRenderContext frc = ge.createGraphics(dummyImage).getFontRenderContext();
+ LineMetrics awtMetrics = awtFont.getLineMetrics("ABC", frc);
+ return awtMetrics;
+ }
+
+ private void printDifference(String value, float awt, float fop) {
+ System.out.println(String.format("%22s AWT: %10f FOP: %10f Difference: %.2f%%", value, awt, fop,
+ (fop - awt) / awt * 100));
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java b/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java
new file mode 100644
index 000000000..b27dac5b2
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/FOPGVTFontTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * 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.font;
+
+import java.text.StringCharacterIterator;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.fop.fonts.Font;
+
+public class FOPGVTFontTestCase {
+
+ private FOPGVTFont font;
+
+ @Before
+ public void createFont() {
+ Font f = mock(Font.class);
+ when(f.hasChar(eq((char) 0))).thenReturn(false);
+ when(f.hasChar(eq((char) 1))).thenReturn(true);
+ font = new FOPGVTFont(f, null);
+ }
+
+ @Test
+ public void testCanDisplayUpTo() {
+ char[] text = new char[] {1, 1, 1};
+ testCanDisplayUpToVariants(text, -1, 0, 3);
+ testCanDisplayUpToVariants(text, -1, 1, 3);
+ text = new char[] {1, 1, 0, 1};
+ testCanDisplayUpToVariants(text, 2, 0, 4);
+ testCanDisplayUpToVariants(text, 2, 1, 4);
+ testCanDisplayUpToVariants(text, 2, 2, 4);
+ testCanDisplayUpToVariants(text, -1, 3, 4);
+ testCanDisplayUpToVariants(text, -1, 1, 2);
+ }
+
+ @Test
+ public void testCanDisplayUpToString() {
+ assertEquals(-1, font.canDisplayUpTo(new String(new char[] {1, 1, 1})));
+ assertEquals(0, font.canDisplayUpTo(new String(new char[] {0, 1, 1})));
+ assertEquals(1, font.canDisplayUpTo(new String(new char[] {1, 0, 1})));
+ assertEquals(2, font.canDisplayUpTo(new String(new char[] {1, 1, 0})));
+ }
+
+ private void testCanDisplayUpToVariants(char[] text, int expected, int start, int limit) {
+ assertEquals(expected, font.canDisplayUpTo(text, start, limit));
+ assertEquals(expected, font.canDisplayUpTo(new StringCharacterIterator(new String(text)), start, limit));
+ }
+}
diff --git a/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java b/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java
new file mode 100644
index 000000000..0995ab4df
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/FOPGVTGlyphVectorTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.font;
+
+
+public abstract class FOPGVTGlyphVectorTest {
+
+ protected FOPGVTGlyphVector glyphVector;
+
+}
diff --git a/test/java/org/apache/fop/svg/font/FontInfoBuilder.java b/test/java/org/apache/fop/svg/font/FontInfoBuilder.java
new file mode 100644
index 000000000..c9346588c
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/FontInfoBuilder.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.font;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.fop.apps.io.InternalResourceResolver;
+import org.apache.fop.apps.io.ResourceResolverFactory;
+import org.apache.fop.fonts.EmbeddingMode;
+import org.apache.fop.fonts.EncodingMode;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontMetrics;
+import org.apache.fop.fonts.truetype.OFFontLoader;
+
+class FontInfoBuilder {
+
+ public static final String DEJAVU_LGC_SERIF = "DejaVu LGC Serif";
+
+ public static final String DROID_SANS_MONO = "Droid Sans Mono";
+
+ private static final boolean USE_ADVANCED_BY_DEFAULT = true;
+
+ private FontInfo fontInfo;
+
+ private int fontKey;
+
+ public FontInfoBuilder() {
+ reset();
+ }
+
+ private void reset() {
+ fontInfo = new FontInfo();
+ fontKey = 1;
+ }
+
+ public FontInfoBuilder useDejaVuLGCSerif() {
+ return useDejaVuLGCSerif(USE_ADVANCED_BY_DEFAULT);
+ }
+
+ public FontInfoBuilder useDejaVuLGCSerif(boolean useAdvanced) {
+ try {
+ return useFont(DEJAVU_LGC_SERIF, "DejaVuLGCSerif.ttf", useAdvanced);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public FontInfoBuilder useDroidSansMono() {
+ return useDroidSansMono(USE_ADVANCED_BY_DEFAULT);
+ }
+
+ public FontInfoBuilder useDroidSansMono(boolean useAdvanced) {
+ try {
+ return useFont(DROID_SANS_MONO, "DroidSansMono.ttf", useAdvanced);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private FontInfoBuilder useFont(String fontName, String filename, boolean useAdvanced)
+ throws IOException, URISyntaxException {
+ URI baseURI = new File("test/resources/fonts/ttf").toURI();
+ InternalResourceResolver resolver = ResourceResolverFactory.createDefaultInternalResourceResolver(baseURI);
+ OFFontLoader fontLoader = new OFFontLoader(new URI(filename), null, true,
+ EmbeddingMode.AUTO, EncodingMode.AUTO, true, useAdvanced, resolver);
+ FontMetrics font = fontLoader.getFont();
+ registerFont(font, "F" + fontKey++, fontName);
+ return this;
+ }
+
+ private void registerFont(FontMetrics font, String key, String familyName) {
+ fontInfo.addMetrics(key, font);
+ fontInfo.addFontProperties(key, familyName, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL);
+ }
+
+ public FontInfo build() {
+ FontInfo fontInfo = this.fontInfo;
+ reset();
+ return fontInfo;
+ }
+}
diff --git a/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java b/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
new file mode 100644
index 000000000..5c1fb2c86
--- /dev/null
+++ b/test/java/org/apache/fop/svg/font/GlyphLayoutTestCase.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.svg.font;
+
+import java.util.Collections;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.fop.fonts.FontInfo;
+
+/**
+ * Specifically tests glyph positioning from a real font.
+ */
+public class GlyphLayoutTestCase extends FOPGVTGlyphVectorTest {
+
+ /**
+ * Glyph positioning using the legacy kern table.
+ */
+ @Test
+ public void testBasicGlyphPositioning() throws Exception {
+ testGlyphLayout(false);
+ }
+
+ /**
+ * Glyph positioning using GPOS sub-tables.
+ */
+ @Test
+ public void testAdvancedGlyphPositioning() throws Exception {
+ testGlyphLayout(true);
+ }
+
+ private void testGlyphLayout(boolean useAdvanced) {
+ FOPGVTFont font = loadFont(useAdvanced);
+ glyphVector = (FOPGVTGlyphVector) font.createGlyphVector(null, "L\u201DP,V.F,A\u2019LT.");
+ glyphVector.performDefaultLayout();
+ // Values in font units (unitsPerEm = 2048), glyph width - kern
+ int[] widths = {
+ /* L */ 1360 - 491,
+ /* " */ 1047,
+ /* P */ 1378 - 415,
+ /* , */ 651,
+ /* V */ 1479 - 358,
+ /* . */ 651,
+ /* F */ 1421 - 319,
+ /* , */ 651,
+ /* A */ 1479 - 301,
+ /* ' */ 651,
+ /* L */ 1360 - 167,
+ /* T */ 1366 - 301,
+ /* . */ 651};
+ checkGlyphPositions(13, widths);
+ }
+
+ private FOPGVTFont loadFont(boolean useAdvanced) {
+ FontInfo fontInfo = new FontInfoBuilder().useDejaVuLGCSerif(useAdvanced).build();
+ FOPFontFamilyResolver resolver = new FOPFontFamilyResolverImpl(fontInfo);
+ FOPGVTFontFamily family = resolver.resolve(FontInfoBuilder.DEJAVU_LGC_SERIF);
+ return family.deriveFont(1000, Collections.emptyMap());
+ }
+
+ private void checkGlyphPositions(int expectedGlyphCount, int[] widths) {
+ assertEquals(expectedGlyphCount, glyphVector.getNumGlyphs());
+ float[] positions = new float[2 * (widths.length + 1)];
+ for (int i = 0, n = 2; i < widths.length; i++, n += 2) {
+ positions[n] = positions[n - 2] + widths[i] / 2.048f;
+ }
+ for (int i = 0; i <= widths.length; i++) {
+ assertEquals(positions[2 * i], glyphVector.getGlyphPosition(i).getX(), 3);
+ }
+ }
+
+}
diff --git a/test/java/org/apache/fop/svg/glyph-orientation.svg b/test/java/org/apache/fop/svg/glyph-orientation.svg
new file mode 100644
index 000000000..4900a3b02
--- /dev/null
+++ b/test/java/org/apache/fop/svg/glyph-orientation.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<svg width="100" height="140" xmlns="http://www.w3.org/2000/svg">
+<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/>
+<g transform="translate(10) scale(20) scale(0.001) translate(0, 1000)"
+ font-family="sans-serif" font-size="1000">
+ <text x="1000" writing-mode="tb">ABCD</text>
+ <text x="2500" writing-mode="tb" glyph-orientation-vertical="0">EFGH</text>
+ <text x="0" y="5000" glyph-orientation-horizontal="270">IJKL</text>
+</g>
+</svg>
diff --git a/test/java/org/apache/fop/svg/rotated-glyph.svg b/test/java/org/apache/fop/svg/rotated-glyph.svg
new file mode 100644
index 000000000..8b942905e
--- /dev/null
+++ b/test/java/org/apache/fop/svg/rotated-glyph.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
+<rect x="0" y="0" width="100%" height="100%" fill="none" stroke="black" stroke-width="2"/>
+<text font-family="Helvetica" font-size="100" x="40" y="110" rotate="0 45 0">ABC</text>
+</svg>
diff --git a/test/java/org/apache/fop/svg/spacing.svg b/test/java/org/apache/fop/svg/spacing.svg
new file mode 100644
index 000000000..943ab1d04
--- /dev/null
+++ b/test/java/org/apache/fop/svg/spacing.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<svg width="150" height="200" xmlns="http://www.w3.org/2000/svg">
+<rect x="0" y="0" width="100%" height="100%" stroke="black" stroke-width="2" fill="none"/>
+<g transform="translate(10) scale(40) scale(0.001) translate(0, 1000)"
+ font-family="sans-serif" font-size="1000">
+ <g transform="">
+ <text>VAV</text>
+ <line x1="667" y1="-818" x2="667" y2="100" stroke-width="10" stroke="blue"/>
+ </g>
+ <g transform="translate(0, 1000)">
+ <text kerning="0">VAV</text>
+ <line x1="667" y1="-818" x2="667" y2="100" stroke-width="10" stroke="blue"/>
+ </g>
+ <g transform="translate(0, 2000)">
+ <text letter-spacing="100">VAV</text>
+ </g>
+ <g transform="translate(0, 3000)">
+ <text word-spacing="500">ab cd</text>
+ </g>
+</g>
+</svg>
diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java
index 42ca8dee6..d8813c3bc 100644
--- a/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java
+++ b/test/java/org/apache/fop/text/linebreak/LineBreakStatusTestCase.java
@@ -19,10 +19,10 @@
package org.apache.fop.text.linebreak;
-import static org.junit.Assert.assertTrue;
-
import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
/**
* JUnit test case for the LineBreakStatus class
diff --git a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java
index 015c1846f..5fc5c7d50 100644
--- a/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java
+++ b/test/java/org/apache/fop/text/linebreak/LineBreakUtilsTestCase.java
@@ -19,10 +19,10 @@
package org.apache.fop.text.linebreak;
-import static org.junit.Assert.assertEquals;
-
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* TODO add javadoc
*
diff --git a/test/java/org/apache/fop/threading/FOProcessorImpl.java b/test/java/org/apache/fop/threading/FOProcessorImpl.java
index 04fed19ba..721830aee 100644
--- a/test/java/org/apache/fop/threading/FOProcessorImpl.java
+++ b/test/java/org/apache/fop/threading/FOProcessorImpl.java
@@ -81,8 +81,8 @@ public class FOProcessorImpl extends AbstractLogEnabled
}
}
- /** {@inheritDoc}
- * @throws URISyntaxException
+ /** {@inheritDoc}
+ * @throws URISyntaxException
* @throws SAXException */
public void process(Source src, Templates templates, OutputStream out)
throws java.io.IOException, URISyntaxException, SAXException {
diff --git a/test/java/org/apache/fop/threading/Main.java b/test/java/org/apache/fop/threading/Main.java
index 7ff0cec4f..d18ae405a 100644
--- a/test/java/org/apache/fop/threading/Main.java
+++ b/test/java/org/apache/fop/threading/Main.java
@@ -32,7 +32,10 @@ import org.apache.avalon.framework.logger.ConsoleLogger;
/**
* Starter class for the multi-threading testbed.
*/
-public class Main {
+public final class Main {
+
+ private Main() {
+ }
private static void prompt() throws IOException {
BufferedReader in = new BufferedReader(new java.io.InputStreamReader(System.in));
diff --git a/test/java/org/apache/fop/traits/BorderPropsTestCase.java b/test/java/org/apache/fop/traits/BorderPropsTestCase.java
index ec93d708e..692e3059f 100644
--- a/test/java/org/apache/fop/traits/BorderPropsTestCase.java
+++ b/test/java/org/apache/fop/traits/BorderPropsTestCase.java
@@ -23,14 +23,14 @@ import java.awt.Color;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
import org.apache.fop.fo.Constants;
import org.apache.fop.util.ColorUtil;
-import static org.junit.Assert.assertEquals;
-
/**
* Tests the BorderProps class.
*/
@@ -67,7 +67,7 @@ public class BorderPropsTestCase {
Color col = new Color(1.0f, 1.0f, 0.5f, 1.0f);
//Normalize: Avoid false alarms due to color conversion (rounding)
col = ColorUtil.parseColorString(null, ColorUtil.colorToString(col));
- for(BorderProps.Mode mode : BorderProps.Mode.values()) {
+ for (BorderProps.Mode mode : BorderProps.Mode.values()) {
BorderProps sut = BorderProps.makeRectangular(Constants.EN_SOLID, 10, col, mode);
testSerialization(sut);
sut = new BorderProps(Constants.EN_SOLID, 10, 4, 3, col, mode);
diff --git a/test/java/org/apache/fop/traits/MinOptMaxTestCase.java b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java
index 73465fdcc..ba6862785 100644
--- a/test/java/org/apache/fop/traits/MinOptMaxTestCase.java
+++ b/test/java/org/apache/fop/traits/MinOptMaxTestCase.java
@@ -19,13 +19,13 @@
package org.apache.fop.traits;
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import org.junit.Test;
-
/**
* Tests the {@link MinOptMax} class.
*/
diff --git a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
index c4b9446ac..5e75f2563 100644
--- a/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
+++ b/test/java/org/apache/fop/util/AdvancedMessageFormatTestCase.java
@@ -19,15 +19,16 @@
package org.apache.fop.util;
-import static org.junit.Assert.assertEquals;
-
import java.util.Map;
-import org.apache.fop.events.model.EventSeverity;
-import org.apache.fop.util.text.AdvancedMessageFormat;
import org.junit.Test;
import org.xml.sax.helpers.LocatorImpl;
+import static org.junit.Assert.assertEquals;
+
+import org.apache.fop.events.model.EventSeverity;
+import org.apache.fop.util.text.AdvancedMessageFormat;
+
/**
* Tests for EventFormatter.
*/
diff --git a/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java
index 3afcc3a2e..8bda99785 100644
--- a/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java
+++ b/test/java/org/apache/fop/util/BitmapImageUtilTestCase.java
@@ -19,8 +19,6 @@
package org.apache.fop.util;
-import static org.junit.Assert.assertEquals;
-
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
@@ -31,13 +29,18 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
import org.apache.commons.io.IOUtils;
-import org.apache.fop.util.bitmap.BitmapImageUtil;
-import org.apache.fop.util.bitmap.MonochromeBitmapConverter;
+
import org.apache.xmlgraphics.image.writer.ImageWriterUtil;
import org.apache.xmlgraphics.util.WriterOutputStream;
import org.apache.xmlgraphics.util.io.ASCIIHexOutputStream;
-import org.junit.Test;
+
+import org.apache.fop.util.bitmap.BitmapImageUtil;
+import org.apache.fop.util.bitmap.MonochromeBitmapConverter;
/**
* Tests {@link BitmapImageUtil}.
diff --git a/test/java/org/apache/fop/util/ColorUtilTestCase.java b/test/java/org/apache/fop/util/ColorUtilTestCase.java
index 6e65004a3..c86ebbeac 100644
--- a/test/java/org/apache/fop/util/ColorUtilTestCase.java
+++ b/test/java/org/apache/fop/util/ColorUtilTestCase.java
@@ -26,6 +26,11 @@ import java.net.URI;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import org.apache.xmlgraphics.java2d.color.ColorSpaces;
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
@@ -34,11 +39,6 @@ import org.apache.xmlgraphics.java2d.color.RenderingIntent;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.FopFactory;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
/**
* Tests the ColorUtil class.
*/
diff --git a/test/java/org/apache/fop/util/DigestFilter.java b/test/java/org/apache/fop/util/DigestFilter.java
index 94e8d67d2..9e62fdc1c 100644
--- a/test/java/org/apache/fop/util/DigestFilter.java
+++ b/test/java/org/apache/fop/util/DigestFilter.java
@@ -95,9 +95,6 @@ public class DigestFilter extends XMLFilterImpl {
super.endDocument();
}
- /* (non-Javadoc)
- * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
- */
public void startElement(
String url,
String localName,
diff --git a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
index 342488a93..5e4f38b0b 100644
--- a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
+++ b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
@@ -19,17 +19,18 @@
package org.apache.fop.util;
+import java.util.LinkedList;
+
+import org.junit.Test;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import java.util.LinkedList;
-
import org.apache.fop.layoutmgr.ElementListUtils;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
-import org.junit.Test;
/**
* Test class for ElementListUtils.
diff --git a/test/java/org/apache/fop/util/LanguageTagsTestCase.java b/test/java/org/apache/fop/util/LanguageTagsTestCase.java
index f7383c720..91861dcc6 100644
--- a/test/java/org/apache/fop/util/LanguageTagsTestCase.java
+++ b/test/java/org/apache/fop/util/LanguageTagsTestCase.java
@@ -19,12 +19,12 @@
package org.apache.fop.util;
-import static org.junit.Assert.assertEquals;
-
import java.util.Locale;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
/**
* Tests {@link LanguageTags}.
*/
diff --git a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java
index 26cfa4406..60aa16d83 100644
--- a/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java
+++ b/test/java/org/apache/fop/util/XMLResourceBundleTestCase.java
@@ -19,15 +19,15 @@
package org.apache.fop.util;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
/**
* Tests for XMLResourceBundle.
*/
diff --git a/test/java/org/apache/fop/visual/BitmapComparator.java b/test/java/org/apache/fop/visual/BitmapComparator.java
index e0c1d5bd4..f2157176b 100644
--- a/test/java/org/apache/fop/visual/BitmapComparator.java
+++ b/test/java/org/apache/fop/visual/BitmapComparator.java
@@ -30,11 +30,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import org.apache.commons.io.IOUtils;
+
import org.apache.batik.ext.awt.image.GraphicsUtil;
import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
import org.apache.batik.util.ParsedURL;
-import org.apache.commons.io.IOUtils;
/**
* Helper class to visually compare two bitmap images.
@@ -45,7 +46,11 @@ import org.apache.commons.io.IOUtils;
* <p>
* TODO Move as utility class to XML Graphics Commons when possible
*/
-public class BitmapComparator {
+public final class BitmapComparator {
+
+
+ private BitmapComparator() {
+ }
/**
* Builds a new BufferedImage that is the difference between the two input images
@@ -79,15 +84,14 @@ public class BitmapComparator {
int w = ref.getWidth();
int h = ref.getHeight();
- int y, i, val;
int [] refPix = null;
int [] genPix = null;
- for (y = 0; y < h; y++) {
- refPix = refWR.getPixels (0, y, w, 1, refPix);
- genPix = genWR.getPixels (0, y, w, 1, genPix);
- for (i = 0; i < refPix.length; i++) {
+ for (int y = 0; y < h; y++) {
+ refPix = refWR.getPixels(0, y, w, 1, refPix);
+ genPix = genWR.getPixels(0, y, w, 1, genPix);
+ for (int i = 0; i < refPix.length; i++) {
// val = ((genPix[i] - refPix[i]) * 5) + 128;
- val = ((refPix[i] - genPix[i]) * 10) + 128;
+ int val = ((refPix[i] - genPix[i]) * 10) + 128;
if ((val & 0xFFFFFF00) != 0) {
if ((val & 0x80000000) != 0) {
val = 0;
diff --git a/test/java/org/apache/fop/visual/ConvertUtils.java b/test/java/org/apache/fop/visual/ConvertUtils.java
index e83322f90..aa4dadf47 100644
--- a/test/java/org/apache/fop/visual/ConvertUtils.java
+++ b/test/java/org/apache/fop/visual/ConvertUtils.java
@@ -27,7 +27,10 @@ import org.apache.commons.logging.Log;
/**
* Utilities for converting files with external converters.
*/
-public class ConvertUtils {
+public final class ConvertUtils {
+
+ private ConvertUtils() {
+ }
/**
* Calls an external converter application (GhostScript, for example).
diff --git a/test/layoutengine/disabled-testcases.xml b/test/layoutengine/disabled-testcases.xml
index 5208fa91d..b96ee1b77 100644
--- a/test/layoutengine/disabled-testcases.xml
+++ b/test/layoutengine/disabled-testcases.xml
@@ -91,16 +91,15 @@
NullPointerException.</description>
</testcase>
<testcase>
- <name>inline-container is not implemented, yet.</name>
- <file>inline-container_block_nested.xml</file>
- <description>inline-container is not implemented, yet. Content of an
- inline-container will get swallowed. The test case contains no checks.</description>
+ <name>Keeps on inline-container are not implemented, yet.</name>
+ <file>inline-container_keeps.xml</file>
+ <description>The keep-with-previous and keep-with-next properties have not been implemented on
+ inline-container yet. They will be treated as if they had the value "auto".</description>
</testcase>
<testcase>
- <name>inline-container is not implemented, yet.</name>
+ <name>Borders and padding inline-container are not implemented, yet.</name>
<file>inline-container_border_padding.xml</file>
- <description>inline-container is not implemented, yet. Content of an
- inline-container will get swallowed.</description>
+ <description>Borders and paddings on an inline-container will be ignored.</description>
</testcase>
<testcase>
<name>inline letter-spacing</name>
diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml
new file mode 100644
index 000000000..3e696a696
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_alignment-adjust.xml
@@ -0,0 +1,244 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that the alignment-adjust property on inline-container behaves properly.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="170pt" page-width="220pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="before-edge":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="before-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="text-before-edge":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="text-before-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="after-edge":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="after-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="text-after-edge":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="text-after-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="middle":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="middle">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="central":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="central">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="ideographic":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="ideographic">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="alphabetic":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="alphabetic">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="hanging":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="hanging">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="mathematical":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="mathematical">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="30pt":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="30pt">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-adjust="10%":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="-10%" dominant-baseline="text-before-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+
+ <checks>
+
+ <!-- before-edge -->
+ <eval expected="37416" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- text-before-edge -->
+ <eval expected="37416" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- after-edge -->
+ <eval expected="31284" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="20184" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- text-after-edge -->
+ <eval expected="31284" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="20184" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- middle -->
+ <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="5784" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- central -->
+ <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="5784" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[6]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- ideographic -->
+ <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="11544" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[7]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- alphabetic -->
+ <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="8664" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[8]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- hanging -->
+ <eval expected="31656" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="2856" xpath="//pageSequence[9]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- mathematical -->
+ <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="5784" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[10]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- 30pt -->
+ <eval expected="49764" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="38664" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[11]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- 10% -->
+ <eval expected="38856" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="10056" xpath="//pageSequence[12]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml
new file mode 100644
index 000000000..53b9be0a9
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_alignment-baseline.xml
@@ -0,0 +1,74 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that the alignment-baseline property on inline-container behaves properly.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="170pt" page-width="220pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-baseline="before-edge":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-baseline="before-edge">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">alignment-baseline="central":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-baseline="central">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+
+ <checks>
+
+ <!-- before-edge -->
+ <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- central -->
+ <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="8850" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_alignment.xml b/test/layoutengine/standard-testcases/inline-container_alignment.xml
new file mode 100644
index 000000000..153d9a9c4
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_alignment.xml
@@ -0,0 +1,154 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that the inline-container is properly aligned with the parent area.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="320pt" page-width="220pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>By default the alignment is with the baseline of the first descendant
+ line-area.</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt">
+ <fo:block font-size="20pt">Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt">
+ <fo:block space-before="20pt" space-before.conditionality="retain">
+ <fo:block-container space-before="10pt" space-before.conditionality="retain"
+ border="4pt solid" padding="2pt" start-indent="6pt" end-indent="6pt">
+ <fo:block font-size="20pt" start-indent="0" end-indent="0">Inside the
+ inline-container.</fo:block>
+ </fo:block-container>
+ </fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>This inline-container has no line-area descendant. The after edge of its
+ allocation rectangle should be aligned with the baseline.</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt">
+ <fo:block border="6pt solid" padding="2pt" start-indent="8pt" end-indent="8pt"/>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>The first line-area descendant is in fo:list-item-body.</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt">
+ <fo:list-block provisional-distance-between-starts="10pt"
+ provisional-label-separation="5pt">
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block/>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>
+ <fo:block font-size="8pt">List item</fo:block>
+ </fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>This inline-container contains a block that contains an inline that contains a
+ block.</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt">
+ <fo:block><fo:inline><fo:block>inline</fo:block></fo:inline></fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <!-- Page sequence 1 -->
+ <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/>
+ <!--
+ The font used is Helvetica, ascender 718, descender −207.
+ Default font size is 12pt => baseline offset = 718 * 12 = 8616mpt
+ Default line height is 1.2 * font-size
+ => space-before = (line-height − (ascender − descender) * font-size) / 2
+ = (1.2 * 12000 − (718 + 207) * 12) / 2
+ = 1650
+ At font size 20, the distance between the before-edge of the inline-container’s child block
+ area and the first line area’s baseline is space-before + baseline-offset = 2750 + 14360 = 17110
+ So the word "Before:" must be offset by 17110 − 8616 = 8494
+ -->
+ <eval expected="Before: " xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]"/>
+ <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+
+ <eval expected="72000" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <eval expected=" After the" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]"/>
+ <eval expected="8494" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[2]/@baseline"/>
+
+ <!-- Page sequence 2 -->
+ <eval expected="34494" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[2]//flow/block/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="104000" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[2]//flow/block/lineArea[2]/viewport/@offset"/>
+
+ <!-- Page sequence 3 -->
+ <!-- bpd = max(text ascent, ascent of inline-container) + text descent
+ = 16000 + 207 * 12 -->
+ <eval expected="18484" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="7384" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="16000" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[3]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- Page sequence 4 -->
+ <eval expected="11372" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="9600" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="1772" xpath="//pageSequence[4]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- Page sequence 5 -->
+ <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="1650" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="14400" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[5]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_basic.xml b/test/layoutengine/standard-testcases/inline-container_basic.xml
new file mode 100644
index 000000000..b2dfcc6e5
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_basic.xml
@@ -0,0 +1,56 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Test for a basic implementation of fo:inline-container.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="320pt" page-width="420pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="80pt" height="50pt">
+ <fo:block>Text inside inline-container.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <!-- The inline-container’s area is there, at the right place -->
+ <eval expected="viewport" xpath="local-name(//flow/block/lineArea/*[position()=2])"/>
+ <!-- It has the right properties -->
+ <eval expected="true" xpath="//viewport/@is-viewport-area"/>
+ <eval expected="80000" xpath="//viewport/@ipd"/>
+ <eval expected="50000" xpath="//viewport/@bpd"/>
+ <eval expected="1" xpath="count(//viewport/*)"/>
+ <eval expected="container" xpath="local-name(//viewport/*)"/>
+ <!-- Its content is there too -->
+ <eval expected="1" xpath="count(//container/block)"/>
+ <eval expected="80000" xpath="//container/block/@ipd"/>
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_block_nested.xml b/test/layoutengine/standard-testcases/inline-container_block_nested.xml
deleted file mode 100644
index cf4ebf486..000000000
--- a/test/layoutengine/standard-testcases/inline-container_block_nested.xml
+++ /dev/null
@@ -1,65 +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$ -->
-<testcase>
- <info>
- <p>
- This test checks nested blocks with inline-containers and indents.
- </p>
- </info>
- <fo>
- <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
- <fo:layout-master-set>
- <fo:simple-page-master master-name="normal" page-width="5in" page-height="5in">
- <fo:region-body/>
- </fo:simple-page-master>
- </fo:layout-master-set>
- <fo:page-sequence master-reference="normal" white-space-collapse="true">
- <fo:flow flow-name="xsl-region-body">
- <fo:block margin-left="12pt">outer block
- <fo:inline-container start-indent="18pt">
- <fo:block margin-left="13pt">inner block</fo:block>
- </fo:inline-container>
- </fo:block>
- </fo:flow>
- </fo:page-sequence>
- </fo:root>
- </fo>
- <checks>
- <!-- First block, no gap -->
- <!--eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-start"/>
- <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-end"/>
- <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-before"/>
- <eval expected="(133,#0000ff,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@border-after"/>
- <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bap"/>
- <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipd"/>
- <eval expected="360000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@ipda"/>
- <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpd"/>
- <eval expected="34400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/@bpda"/-->
- <!-- Nested block of first block -->
- <!--eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-start"/>
- <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-end"/>
- <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-before"/>
- <eval expected="(133,#ff0000,5000)" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@border-after"/>
- <eval expected="5000 5000 5000 5000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bap"/>
- <eval expected="340000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipd"/>
- <eval expected="350000" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@ipda"/>
- <eval expected="14400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpd"/>
- <eval expected="24400" xpath="/areaTree/pageSequence/pageViewport/page[1]/regionViewport/regionBody/mainReference/span/flow/block[1]/block[1]/@bpda"/-->
- </checks>
-</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_bpd.xml b/test/layoutengine/standard-testcases/inline-container_bpd.xml
new file mode 100644
index 000000000..8f808c030
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_bpd.xml
@@ -0,0 +1,72 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that block-progression-dimension on fo:inline-container is properly handled.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="220pt" page-width="320pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="60pt">
+ <fo:block>This text inside inline-container should fit on four lines.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="70pt" height="35pt" overflow="hidden">
+ <fo:block>This text overflows the inline-container in the
+ block-progression-direction.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="80pt">
+ <fo:block space-after="10pt">Block 1</fo:block>
+ <fo:block space-before="20pt" space-after="10pt"
+ space-after.conditionality="retain">Block 2</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <eval expected="40000" xpath="//pageSequence[1]//viewport/@bpd"/>
+
+ <eval expected="35000" xpath="//pageSequence[2]//viewport/@bpd"/>
+ <true xpath="//pageSequence[2]//viewport/@clip"/>
+
+ <eval expected="50000" xpath="//pageSequence[3]//viewport/@bpd"/>
+ </checks>
+
+ <event-checks>
+ <event key="viewportBPDOverflow" elementName="fo:inline-container" amount="15000" clip="true"/>
+ </event-checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml
new file mode 100644
index 000000000..402eb806d
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_dominant-baseline.xml
@@ -0,0 +1,74 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that the dominant-baseline property on inline-container behaves properly.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="170pt" page-width="220pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">dominant-baseline="alphabetic":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="baseline">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="10pt">dominant-baseline="central":</fo:block>
+ <fo:block>The line before. The line before. Before: <fo:inline-container width="100pt"
+ alignment-adjust="baseline" dominant-baseline="central">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After the inline-container.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+
+ </fo:root>
+ </fo>
+
+ <checks>
+
+ <!-- alphabetic -->
+ <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="8664" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[1]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ <!-- central -->
+ <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/@bpd"/>
+ <eval expected="5784" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@offset"/>
+ <eval expected="8616" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/text[1]/@baseline"/>
+ <eval expected="28800" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@bpd"/>
+ <eval expected="0" xpath="//pageSequence[2]//flow/block[2]/lineArea[2]/viewport/@offset"/>
+
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml
new file mode 100644
index 000000000..c19544809
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_ipd-auto.xml
@@ -0,0 +1,66 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ When inline-progression-dimension has been left to auto on fo:inline-container, fall back to
+ the IPD of the nearest ancestor reference-area.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="220pt" page-width="320pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container height="20pt">
+ <fo:block>Text inside inline-container.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block-container space-before="10pt" start-indent="100pt" width="100pt">
+ <fo:block start-indent="0">
+ Before: <fo:inline-container>
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After.
+ </fo:block>
+ </fo:block-container>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <eval expected="3" xpath="count(//pageSequence[1]//flow/block/lineArea)"/>
+ <eval expected="300000" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@ipd"/>
+ <eval expected="3" xpath="count(//pageSequence[2]//flow/block/block/block/lineArea)"/>
+ <eval expected="100000" xpath="//pageSequence[2]//flow/block/block/block/lineArea[2]/viewport/@ipd"/>
+ </checks>
+
+ <event-checks>
+ <event key="inlineContainerAutoIPDNotSupported" fallback="300.0"/>
+ <event key="inlineContainerAutoIPDNotSupported" fallback="100.0"/>
+ </event-checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml
new file mode 100644
index 000000000..aa681d134
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_ipd-percent.xml
@@ -0,0 +1,61 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Checks that percentage values for the dimensions of an fo:inline-container are resolved
+ properly.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="220pt" page-width="320pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>Before: <fo:inline-container width="50%" height="50%">
+ <fo:block>Text inside inline-container.</fo:block>
+ </fo:inline-container> After.</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block-container space-before="10pt" start-indent="50pt" width="200pt">
+ <fo:block start-indent="0">
+ Before: <fo:inline-container width="30%" height="30%">
+ <fo:block>Inside the inline-container.</fo:block>
+ </fo:inline-container> After.
+ </fo:block>
+ </fo:block-container>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <eval expected="150000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@ipd"/>
+ <eval expected="10000" xpath="//pageSequence[1]//flow/block/lineArea/viewport/@bpd"/>
+ <eval expected="60000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@ipd"/>
+ <eval expected="20000" xpath="//pageSequence[2]//flow/block/block/block/lineArea/viewport/@bpd"/>
+ </checks>
+</testcase>
diff --git a/test/layoutengine/standard-testcases/inline-container_keeps.xml b/test/layoutengine/standard-testcases/inline-container_keeps.xml
new file mode 100644
index 000000000..e946f13f3
--- /dev/null
+++ b/test/layoutengine/standard-testcases/inline-container_keeps.xml
@@ -0,0 +1,49 @@
+<?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$ -->
+<testcase>
+ <info>
+ <p>
+ Test for keeps on fo:inline-container.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="220pt" page-width="320pt" margin="10pt">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>This inline-container must be kept with the word before: <fo:inline-container
+ id="inline-container" width="100pt" keep-with-previous.within-line="always"
+ background-color="#F0F0F0">
+ <fo:block>Inline-container</fo:block>
+ </fo:inline-container></fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+
+ <checks>
+ <eval expected="before: " xpath="//pageSequence[1]//flow/block/lineArea[2]/text[1]"/>
+ <eval expected="inline-container" xpath="//pageSequence[1]//flow/block/lineArea[2]/viewport/@prod-id"/>
+ </checks>
+</testcase>
diff --git a/test/layoutengine/testcase2checks.xsl b/test/layoutengine/testcase2checks.xsl
index ae3a8fe72..25dfcc810 100644
--- a/test/layoutengine/testcase2checks.xsl
+++ b/test/layoutengine/testcase2checks.xsl
@@ -25,6 +25,7 @@
<checks>
<xsl:apply-templates select="checks"/>
<xsl:apply-templates select="if-checks"/>
+ <xsl:apply-templates select="event-checks"/>
</checks>
</xsl:template>
@@ -40,7 +41,13 @@
<xsl:copy-of select="*"/>
</if-checks>
</xsl:template>
-
+
+<xsl:template match="event-checks">
+ <event-checks>
+ <xsl:copy-of select="*"/>
+ </event-checks>
+</xsl:template>
+
<xsl:template match="text()" />
</xsl:stylesheet>
diff --git a/test/xml/pdf-a/svg-transparency.fo b/test/xml/pdf-a/svg-transparency.fo
new file mode 100644
index 000000000..922416fbc
--- /dev/null
+++ b/test/xml/pdf-a/svg-transparency.fo
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Gladiator">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="page"
+ page-height="420pt" page-width="620pt" margin="10pt">
+ <fo:region-body display-align="center"/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="page">
+ <fo:flow flow-name="xsl-region-body" text-align="center">
+ <fo:block font-size="20pt">RGB Circles</fo:block>
+ <fo:block><fo:instream-foreign-object>
+ <svg xmlns="http://www.w3.org/2000/svg" width="300" height="286.6">
+ <g style="fill-opacity:0.7; stroke:black; stroke-width:3"
+ transform="translate(0, 286.6) scale(1, -1) translate(100, 100)">
+ <circle cx="50" cy="86.6" r="80" style="fill:red;"/>
+ <circle cx="0" cy="0" r="80" style="fill:green;"/>
+ <circle cx="100" cy="0" r="80" style="fill:blue;"/>
+ </g>
+ </svg>
+ </fo:instream-foreign-object></fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>